1 /** Trait for getting maximum size of types `T`. 2 * 3 * Implementation in `std.variant` uses recursion. 4 * 5 * See_Also: https://forum.dlang.org/post/hzpuiyxrrfasfuktpgqn@forum.dlang.org 6 */ 7 module nxt.maxsize_trait; 8 9 /** Get maximum size of types `Ts`. 10 * 11 * Limitation compared to `std.variant.maxSize`: `Ts` cannot contain `void`. 12 */ 13 static template maxSizeOf(Ts...) 14 { 15 align(1) union Impl { Ts t; } 16 enum maxSizeOf = Impl.sizeof; 17 } 18 19 /// 20 @safe pure unittest 21 { 22 static assert(maxSizeOf!(char) == 1); 23 static assert(maxSizeOf!(byte) == 1); 24 static assert(maxSizeOf!(byte, short) == 2); 25 static assert(maxSizeOf!(short, byte) == 2); 26 static assert(maxSizeOf!(byte, short, int) == 4); 27 static assert(maxSizeOf!(byte, short, int, long) == 8); 28 static assert(maxSizeOf!(byte, short, int, string) == 16); 29 static assert(!__traits(compiles, { enum _ = maxSizeOf!(byte, void); })); 30 } 31 32 // alternative implementation that supports `void` 33 static template maxSizeOf_1(Ts...) 34 { 35 align(1) union Impl { 36 static foreach (i, T; Ts) { 37 static if (!is(T == void)) 38 mixin("T _field_" ~ i.stringof ~ ";"); 39 } 40 } 41 enum maxSizeOf_1 = Impl.sizeof; 42 } 43 44 /// 45 @safe pure unittest 46 { 47 static assert(maxSizeOf_1!(char) == 1); 48 static assert(maxSizeOf_1!(byte) == 1); 49 static assert(maxSizeOf_1!(byte, short) == 2); 50 static assert(maxSizeOf_1!(short, byte) == 2); 51 static assert(maxSizeOf_1!(byte, short, int) == 4); 52 static assert(maxSizeOf_1!(byte, short, int, long) == 8); 53 static assert(maxSizeOf_1!(byte, short, int, string) == 16); 54 static assert(maxSizeOf_1!(byte, void) == 1); 55 static assert(maxSizeOf_1!(byte, short, void) == 2); 56 }