1 /* 2 * bitleveld - reinterpret.d 3 * by Laszlo Szeremi 4 * 5 * Copyright under Boost Software License. 6 * 7 * Contains functions that can be used to reinterpret data types and arrays between each other. 8 */ 9 10 module bitleveld.reinterpret; 11 /* 12 * Note on reinterpretation of pointers: 13 * 14 * The functions allow to cast pointers, but accessing those pointers might lead to memory leakage issues when accessing 15 * them. The same is true for other types. 16 */ 17 /** 18 * Thrown on a reinterpretation error. 19 */ 20 public class ReinterpretException : Exception { 21 @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null) 22 { 23 super(msg, file, line, nextInChain); 24 } 25 26 @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__) 27 { 28 super(msg, file, line, nextInChain); 29 } 30 } 31 /** 32 * Safely casts one type of an array to another. 33 */ 34 T[] reinterpretCast (T, U)(U[] input) @trusted pure { 35 T[] _reinterpretCast() @system pure { 36 return cast(T[])(cast(void[])input); 37 } 38 if ((U.sizeof * input.length) % T.sizeof == 0) return _reinterpretCast(); 39 else throw new ReinterpretException("Cannot cast safely!"); 40 } 41 /** 42 * Safely casts one type of an array to a single instance of a type. 43 */ 44 T reinterpretGet (T, U)(U[] input) @trusted pure { 45 T _reinterpretGet() @system pure { 46 return (cast(T[])(cast(void[])input))[0]; 47 } 48 if (U.sizeof * input.length == T.sizeof) return _reinterpretGet; 49 else throw new ReinterpretException("Cannot cast safely!"); 50 51 } 52 /** 53 * Safely cast a type into an array type. 54 */ 55 T[] reinterpretAsArray (T, U)(U input) @trusted pure { 56 T[] _reinterpretAsArray() @system pure { 57 return (cast(T[])(cast(void[])[input])); 58 } 59 if (U.sizeof % T.sizeof == 0) return _reinterpretAsArray; 60 else throw new ReinterpretException("Cannot cast safely!"); 61 } 62 unittest { 63 64 align(1) struct TestStruct { 65 ubyte val0; 66 ubyte val1; 67 ubyte val2; 68 } 69 TestStruct x = TestStruct(1,2,3); 70 byte[] testArray = reinterpretAsArray!(byte)(x); 71 reinterpretGet!TestStruct(testArray); 72 reinterpretCast!ubyte(testArray); 73 }