1 /** 2 Helpers for creating special types. 3 4 Copyright: 5 Copyright © 2023-2025, Kitsunebi Games 6 Copyright © 2023-2025, Inochi2D Project 7 8 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 9 Authors: Luna Nielsen 10 */ 11 module numem.core.types; 12 13 /** 14 Creates a new unique handle type. 15 16 Handle types are pointers to opaque structs. 17 18 Params: 19 name = Unique name of the handle. 20 21 Examples: 22 --- 23 alias VkInstance = OpaqueHandle!("VkInstance"); 24 --- 25 */ 26 template OpaqueHandle(string name) { 27 struct OpaqueHandleT(string name); 28 alias OpaqueHandle = OpaqueHandleT!(name)*; 29 } 30 31 @("OpaqueHandle") 32 unittest { 33 alias HandleT1 = OpaqueHandle!("HandleT1"); 34 alias HandleT2 = OpaqueHandle!("HandleT2"); 35 36 assert(!is(HandleT1 == HandleT2)); 37 assert(!is(HandleT1 : HandleT2)); 38 } 39 40 /** 41 Creates a new type based on an existing type. 42 43 Params: 44 T = Base type of the typedef. 45 name = An extra identifier for the type. 46 init = Initializer value for this type. 47 48 Examples: 49 --- 50 alias MyInt = TypeDef!(int, "MyInt"); 51 assert(!is(MyInt == int)); 52 --- 53 */ 54 template TypeDef(T, string name, T init = T.init) { 55 import std.format : format; 56 57 mixin(q{ 58 struct %s { 59 @nogc nothrow: 60 private: 61 T value = init; 62 63 public: 64 alias BaseType = T; 65 alias value this; 66 67 static if ((is(T == struct) || is(T == union)) && !is(typeof({T t;}))) { 68 @disable this(); 69 } 70 this(T init) { this.value = init; } 71 this(typeof(this) init) { this.value = init.value; } 72 } 73 }.format(name)); 74 75 alias TypeDef = mixin(name); 76 } 77 78 /** 79 Gets the base type of a typedef. 80 */ 81 template TypeDefBase(T) { 82 static if (is(typeof({ T.BaseType t; }))) { 83 alias TypeDefBase = T.BaseType; 84 } else { 85 static assert(0, "Not a TypeDef!"); 86 } 87 } 88 89 @("TypeDef") 90 unittest { 91 alias MyInt = TypeDef!(int, "MyInt"); 92 93 // They're not the same type, but they *are* implicitly convertible. 94 assert(!is(MyInt == int)); 95 assert(is(MyInt : int)); 96 97 int i = 42; 98 MyInt va = 42; 99 100 assert(i == va); 101 assert(TypeDefBase!MyInt.stringof == int.stringof); 102 }