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