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 }