1 module reversineer.structure; 2 3 import std.traits; 4 5 enum isPODStruct(T) = !isIntegral!T && !isSomeChar!T && !isBoolean!T && !isFloatingPoint!T && isMutable!T && isSimpleStruct!T; 6 7 template isSimpleStruct(T) { 8 static if (!is(T == struct)) { 9 enum isSimpleStruct = false; 10 } 11 else static if (!__traits(compiles, { T val; })) { 12 enum isSimpleStruct = false; 13 } else { 14 enum isSimpleStruct = true; 15 } 16 } 17 @safe pure nothrow @nogc unittest { 18 struct SimpleStruct { int v; } 19 struct NonSimpleStruct { int v; @disable this(); } 20 static assert(!isSimpleStruct!int); 21 static assert(isSimpleStruct!SimpleStruct); 22 static assert(!isSimpleStruct!NonSimpleStruct); 23 } 24 25 pure @safe nothrow unittest { 26 import reversineer.io : read; 27 struct Basic { 28 int x; 29 } 30 assert((cast(ubyte[])[4, 0, 0, 0]).read!Basic == Basic(4)); 31 32 struct InputRangeReduce { 33 ubyte[] bytes; 34 size_t index = 0; 35 ubyte front() @safe pure nothrow @nogc { 36 return bytes[index]; 37 } 38 bool empty() @safe pure nothrow @nogc { 39 return index >= bytes.length; 40 } 41 void popFront() @safe pure nothrow @nogc { 42 index++; 43 } 44 } 45 assert(InputRangeReduce([4, 0, 0, 0]).read!Basic == Basic(4)); 46 } 47 48 struct Offset { 49 ulong offset; 50 } 51 52 struct Palette { 53 bool shareSeed = false; 54 bool dontSkipFirst = false; 55 } 56 struct Name { 57 } 58 59 struct Label { 60 string name; 61 string description; 62 } 63 64 struct Randomize {} 65 66 struct Width { 67 ulong width; 68 } 69 70 struct Height { 71 ulong height; 72 } 73 74 enum RowByRow; 75 76 align(1) struct UnknownData(size_t Size) { 77 align(1): 78 ubyte[Size] raw; 79 string toBase64() const @safe { 80 import std.base64 : Base64; 81 return Base64.encode(raw[]); 82 } 83 } 84 85 @safe pure unittest { 86 UnknownData!4 data; 87 data.raw = [1, 2, 3, 4]; 88 assert(data.toBase64 == "AQIDBA=="); 89 }