1 /** 2 Optional compile time traits 3 */ 4 module optional.traits; 5 6 /// Checks if T is an optional type 7 template isOptional(T) { 8 import optional: Optional; 9 import std.traits: isInstanceOf; 10 enum isOptional = isInstanceOf!(Optional, T); 11 } 12 13 /// 14 @("Example of isOptional") 15 unittest { 16 import optional: Optional; 17 18 assert(isOptional!(Optional!int) == true); 19 assert(isOptional!int == false); 20 assert(isOptional!(int[]) == false); 21 } 22 23 /// Returns the target type of a optional. 24 template OptionalTarget(T) if (isOptional!T) { 25 import std.traits: TemplateArgsOf; 26 alias OptionalTarget = TemplateArgsOf!T[0]; 27 } 28 29 /// 30 @("Example of OptionalTarget") 31 unittest { 32 import optional: Optional; 33 34 class C {} 35 struct S {} 36 37 import std.meta: AliasSeq; 38 foreach (T; AliasSeq!(int, int*, S, C, int[], S[], C[])) { 39 alias CT = const T; 40 alias IT = immutable T; 41 alias ST = shared T; 42 43 static assert(is(OptionalTarget!(Optional!T) == T)); 44 static assert(is(OptionalTarget!(Optional!CT) == CT)); 45 static assert(is(OptionalTarget!(Optional!IT) == IT)); 46 static assert(is(OptionalTarget!(Optional!ST) == ST)); 47 } 48 } 49 50 /// Checks if T is an optional chain 51 template isOptionalChain(T) { 52 import optional: OptionalChain; 53 import std.traits: isInstanceOf; 54 enum isOptionalChain = isInstanceOf!(OptionalChain, T); 55 } 56 57 /// 58 @("Example of isOptionalChain") 59 @safe @nogc unittest { 60 import optional: oc, some; 61 static assert(isOptionalChain!(typeof(oc(some(3))))); 62 }