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)(ref 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)(ref 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 }