1 /** 2 Iz is is - reason for choosing iz is because is is a keyword. Answers the qustions "is this 'thing' ____ ?" 3 */ 4 module bolts.iz; 5 6 import bolts.internal; 7 8 /** 9 `Iz` is a helper template that allows you to inspect a type or an alias. 10 11 It takes a single element as an argument. The reason the template parameters is 12 types as a variable arg sequence is becure if D does not allow (pre version 2.087) 13 to say "I want either a type or alias over here, I don't care, I'll figure it out". 14 But it does allow it when you use a $(I template sequence parameter) 15 16 $(TABLE 17 $(TR $(TH method) $(TH Description)) 18 $(TR 19 $(TD $(DDOX_NAMED_REF bolts.iz.iz.of, `of`)) 20 $(TD True if the resolved type is the same as another resolved type) 21 ) 22 $(TR 23 $(TD $(DDOX_NAMED_REF bolts.iz.iz.sameAs, `sameAs`)) 24 $(TD True if T and U are the same "thing" (type, alias, literal value)) 25 ) 26 $(TR 27 $(TD $(DDOX_NAMED_REF bolts.iz.iz.nullType, `nullType`)) 28 $(TD True if the resolved type is typeof(null)) 29 ) 30 $(TR 31 $(TD $(DDOX_NAMED_REF bolts.iz.iz.unaryOver, `unaryOver`)) 32 $(TD True if the resolved type a unary funtion over some other types) 33 ) 34 $(TR 35 $(TD $(DDOX_NAMED_REF bolts.iz.iz.binaryOver, `binaryOver`)) 36 $(TD True if the resolved type a binary funtion over some other types) 37 ) 38 $(TR 39 $(TD $(DDOX_NAMED_REF bolts.iz.iz.functionOver, `functionOver`)) 40 $(TD True if the resolved type an n-ary funtion over n types) 41 ) 42 $(TR 43 $(TD $(DDOX_NAMED_REF bolts.iz.iz.refType, `refType`)) 44 $(TD True if the resolved type a reference type) 45 ) 46 $(TR 47 $(TD $(DDOX_NAMED_REF bolts.iz.iz.valueType, `valueType`)) 48 $(TD True if the resolved type a value type) 49 ) 50 $(TR 51 $(TD $(DDOX_NAMED_REF bolts.iz.iz.literalOf, `literalOf`)) 52 $(TD True if the resolved type is a literal of a type of T) 53 ) 54 $(TR 55 $(TD $(DDOX_NAMED_REF bolts.iz.iz.literal, `literal`)) 56 $(TD True if the resolved type is a literal) 57 ) 58 $(TR 59 $(TD $(DDOX_NAMED_REF bolts.iz.iz.copyConstructable, `copyConstructable`)) 60 $(TD True if resolved type is copy constructable) 61 ) 62 $(TR 63 $(TD $(DDOX_NAMED_REF bolts.iz.iz.nonTriviallyCopyConstructable, `nonTriviallyCopyConstructable`)) 64 $(TD True if resolved type is non-trivially copy constructable) 65 ) 66 $(TR 67 $(TD $(DDOX_NAMED_REF bolts.iz.iz.triviallyCopyConstructable, `triviallyCopyConstructable`)) 68 $(TD True if resolved is trivially copy constructable) 69 ) 70 $(TR 71 $(TD $(DDOX_NAMED_REF bolts.iz.iz.equatableTo, `equatableTo`)) 72 $(TD True if resolved type is equatabel to other) 73 ) 74 $(TR 75 $(TD $(DDOX_NAMED_REF bolts.iz.iz.nullTestable, `nullTestable`)) 76 $(TD True if resolved type can be checked against null) 77 ) 78 $(TR 79 $(TD $(DDOX_NAMED_REF bolts.iz.iz.nullSettable, `nullSettable`)) 80 $(TD True if resolved type can be set to null) 81 ) 82 $(TR 83 $(TD $(DDOX_NAMED_REF bolts.iz.iz.refDecl, `refDecl`)) 84 $(TD True if resolved type is declred with ref or is a function that returns ref) 85 ) 86 ) 87 88 See_also: 89 - https://dlang.org/spec/template.html#variadic-templates 90 */ 91 template iz(Aliases...) if (Aliases.length == 1) { 92 import bolts.traits.symbols: TypesOf; 93 94 alias ResolvedType = TypesOf!Aliases[0]; 95 96 /// See: `bolts.traits.symbols.isOf` 97 static template of(Other...) if (Other.length == 1) { 98 enum of = from.bolts.traits.isOf!(Aliases[0], Other[0]); 99 } 100 101 // TODO: Remove on major bump 102 deprecated("use nullTestable") 103 enum nullable = from.bolts.traits.isNullable!ResolvedType; 104 105 /// See: `bolts.traits.types.isNullType` 106 enum nullType = from.bolts.traits.isNullType!ResolvedType; 107 108 /// See: `bolts.traits.symbols.isSame` 109 static template sameAs(Other...) if (Other.length == 1) { 110 enum sameAs = from.bolts.traits.isSame!(Aliases[0], Other[0]); 111 } 112 113 /// See: `bolts.traits.functions.isFunctionOver` 114 enum functionOver(U...) = from.bolts.traits.isFunctionOver!(Aliases[0], U); 115 116 /// See: `bolts.traits.functions.isUnaryOver` 117 enum unaryOver(U...) = from.bolts.traits.isUnaryOver!(Aliases[0], U); 118 119 /// See: `bolts.traits.functions.isBinaryOver` 120 enum binaryOver(U...) = from.bolts.traits.isBinaryOver!(Aliases[0], U); 121 122 /// See: `bolts.traits.types.isRefType` 123 enum refType = from.bolts.traits.isRefType!ResolvedType; 124 125 /// See: `bolts.traits.types.isValueType` 126 enum valueType = from.bolts.traits.isValueType!ResolvedType; 127 128 /// See: `bolts.traits.symbols.isLiteralOf` 129 enum literalOf(T) = from.bolts.traits.isLiteralOf!(Aliases[0], T); 130 131 /// See: `bolts.traits.symbols.isLiteral` 132 enum literal = from.bolts.traits.isLiteral!(Aliases[0]); 133 134 /// See: `bolts.traits.types.isCopyConstructable` 135 enum copyConstructable = from.bolts.traits.isCopyConstructable!ResolvedType; 136 137 /// See: `bolts.traits.types.isNonTriviallyCopyConstructable` 138 enum nonTriviallyCopyConstructable = from.bolts.traits.isNonTriviallyCopyConstructable!ResolvedType; 139 140 /// See: `bolts.traits.types.isTriviallyCopyConstructable` 141 enum triviallyCopyConstructable = from.bolts.traits.isTriviallyCopyConstructable!ResolvedType; 142 143 /// See: `bolts.traits.types.areEquatable` 144 static template equatableTo(Other...) if (Other.length == 1) { 145 enum equatableTo = from.bolts.traits.areEquatable!(Aliases[0], Other[0]); 146 } 147 148 /// See: `bolts.traits.types.isNullTestable` 149 enum nullTestable = from.bolts.traits.isNullTestable!Aliases; 150 151 /// See: `bolts.traits.types.isNullSettable` 152 enum nullSettable = from.bolts.traits.isNullSettable!Aliases; 153 154 /// See: `bolts.traits.symbols.isRefDecl` 155 enum refDecl = from.bolts.traits.isRefDecl!Aliases; 156 } 157 158 /// 159 unittest { 160 int i = 3; 161 int j = 4; 162 int *pi = null; 163 164 // Is it resolved to the same type as another? 165 static assert( iz!i.of!int); 166 static assert(!iz!i.of!(int*)); 167 static assert( iz!3.of!i); 168 static assert(!iz!int.of!pi); 169 170 // Is it the same as another? 171 static assert( iz!i.sameAs!i); 172 static assert(!iz!i.sameAs!j); 173 static assert( iz!1.sameAs!1); 174 static assert(!iz!1.sameAs!2); 175 176 // Using std.meta algorithm with iz 177 import std.meta: allSatisfy, AliasSeq; 178 static assert(allSatisfy!(iz!int.of, 3, 4, int, i)); 179 180 /// Is it a function over 181 static assert( iz!(a => a).unaryOver!int); 182 static assert( iz!((a, b) => a).binaryOver!(int, int)); 183 static assert( iz!((a, b, c, d) => a).functionOver!(int, int, int, int)); 184 185 // Is this thing a value or reference type? 186 struct SValueType {} 187 class CRefType {} 188 static assert( iz!SValueType.valueType); 189 static assert(!iz!CRefType.valueType); 190 static assert(!iz!SValueType.refType); 191 static assert( iz!CRefType.refType); 192 193 static assert( iz!"hello".literalOf!string); 194 static assert(!iz!3.literalOf!string); 195 196 // Is this thing copy constructable? 197 static struct SDisabledCopyConstructor { @disable this(ref typeof(this)); } 198 static assert(!iz!SDisabledCopyConstructor.copyConstructable); 199 static assert( iz!int.copyConstructable); 200 201 // Does this thing define a custom copy constructor (i.e. non-trivial copy constructor) 202 static struct SCopyConstructor { this(ref typeof(this)) {} } 203 static assert( iz!SCopyConstructor.nonTriviallyCopyConstructable); 204 static assert(!iz!SCopyConstructor.triviallyCopyConstructable); 205 static assert(!iz!int.nonTriviallyCopyConstructable); 206 static assert( iz!int.triviallyCopyConstructable); 207 208 // Can we equate these things? 209 static assert( iz!int.equatableTo!3); 210 static assert(!iz!3.equatableTo!string); 211 212 // What null-semantics does the type have 213 214 // Is it settable to null? 215 static struct SNullSettable { void opAssign(int*) {} } 216 static assert( iz!pi.nullSettable); 217 static assert( iz!SNullSettable.nullSettable); 218 static assert(!iz!i.nullSettable); 219 220 // Is it checable with null? (i.e. if (this is null) ) 221 static assert( iz!pi.nullTestable); 222 static assert(!iz!SNullSettable.nullTestable); 223 static assert(!iz!i.nullTestable); 224 225 // Is it typeof(null)? 226 static assert(!iz!int.nullType); 227 static assert( iz!null.nullType); 228 static assert( iz!(typeof(null)).nullType); 229 }