1 module ut.traits; 2 3 4 import ut; 5 import mirror.meta; 6 import mirror.traits; 7 import std.meta: AliasSeq; 8 9 10 @("isEnum") 11 @safe pure unittest { 12 static import modules.types; 13 import std.meta: Filter, AliasSeq; 14 15 alias mod = Module!"modules.types"; 16 alias aggregates = mod.Aggregates; 17 alias enums = Filter!(isEnum, aggregates); 18 static assert(is(enums == AliasSeq!(modules.types.Enum)), enums.stringof); 19 } 20 21 22 @("isStruct") 23 @safe pure unittest { 24 static import modules.types; 25 import std.meta: Filter, AliasSeq; 26 27 alias mod = Module!"modules.types"; 28 alias aggregates = mod.Aggregates; 29 alias structs = Filter!(isStruct, aggregates); 30 static assert(is(structs == AliasSeq!(modules.types.String)), structs.stringof); 31 } 32 33 34 @("isInterface") 35 @safe pure unittest { 36 static import modules.types; 37 import std.meta: Filter, AliasSeq; 38 39 alias mod = Module!"modules.types"; 40 alias aggregates = mod.Aggregates; 41 alias interfaces = Filter!(isInterface, aggregates); 42 static assert(is(interfaces == AliasSeq!(modules.types.Interface)), interfaces.stringof); 43 } 44 45 46 @("isClass") 47 @safe pure unittest { 48 static import modules.types; 49 import std.meta: Filter, AliasSeq; 50 51 alias mod = Module!"modules.types"; 52 alias aggregates = mod.Aggregates; 53 alias classes = Filter!(isClass, aggregates); 54 alias expected = AliasSeq!( 55 modules.types.Class, 56 modules.types.AbstractClass, 57 modules.types.MiddleClass, 58 modules.types.LeafClass, 59 ); 60 static assert(is(classes == expected), classes.stringof); 61 } 62 63 64 @("isOOP") 65 @safe pure unittest { 66 static import modules.types; 67 import std.meta: Filter, AliasSeq; 68 69 alias mod = Module!"modules.types"; 70 alias aggregates = mod.Aggregates; 71 alias classes = Filter!(isOOP, aggregates); 72 alias expected = AliasSeq!( 73 modules.types.Class, 74 modules.types.Interface, 75 modules.types.AbstractClass, 76 modules.types.MiddleClass, 77 modules.types.LeafClass, 78 ); 79 static assert(is(classes == expected), classes.stringof); 80 } 81 82 83 @("FundamentalType.scalar") 84 @safe pure unittest { 85 static assert(is(FundamentalType!int == int)); 86 static assert(is(FundamentalType!double == double)); 87 static struct Foo { } 88 static assert(is(FundamentalType!Foo == Foo)); 89 } 90 91 92 @("FundamentalType.array") 93 @safe pure unittest { 94 static assert(is(FundamentalType!(int[]) == int)); 95 static assert(is(FundamentalType!(int[][]) == int)); 96 static assert(is(FundamentalType!(int[][][]) == int)); 97 98 static assert(is(FundamentalType!(double[]) == double)); 99 static assert(is(FundamentalType!(double[][]) == double)); 100 101 static assert(is(FundamentalType!string == immutable char)); 102 static assert(is(FundamentalType!(string[]) == immutable char)); 103 104 static struct Foo { } 105 static assert(is(FundamentalType!(Foo[]) == Foo)); 106 static assert(is(FundamentalType!(Foo[][]) == Foo)); 107 } 108 109 110 @("FundamentalType.pointer") 111 @safe pure unittest { 112 static assert(is(FundamentalType!(int*) == int)); 113 static assert(is(FundamentalType!(int**) == int)); 114 static assert(is(FundamentalType!(int***) == int)); 115 116 static assert(is(FundamentalType!(double*) == double)); 117 static assert(is(FundamentalType!(double**) == double)); 118 119 static assert(is(FundamentalType!(string*) == immutable char)); 120 static assert(is(FundamentalType!(string**) == immutable char)); 121 122 static struct Foo { } 123 static assert(is(FundamentalType!(Foo*) == Foo)); 124 static assert(is(FundamentalType!(Foo**) == Foo)); 125 } 126 127 128 @("RecursiveFieldTypes.scalar") 129 @safe pure unittest { 130 static assert(is(RecursiveFieldTypes!int == int)); 131 static assert(is(RecursiveFieldTypes!double == double)); 132 } 133 134 135 @("RecursiveFieldTypes.udt.flat") 136 @safe pure unittest { 137 138 static struct Foo { 139 int i; 140 double d; 141 } 142 143 shouldEqual!(RecursiveFieldTypes!Foo, AliasSeq!(int, double)); 144 } 145 146 147 @("RecursiveFieldTypes.udt.nested") 148 @safe pure unittest { 149 150 static struct Inner0 { 151 int i; 152 double d; 153 } 154 155 static struct Inner1 { 156 double d; 157 string s; 158 } 159 160 static struct Mid { 161 Inner0 inner0; 162 Inner1 inner1; 163 } 164 165 static struct Outer { 166 Mid mid; 167 byte b; 168 float func(float, float); 169 170 @property static Outer max() @safe pure nothrow @nogc { 171 return Outer(); 172 } 173 } 174 175 shouldEqual!(RecursiveFieldTypes!Outer, 176 AliasSeq!(Mid, Inner0, int, double, Inner1, string, byte)); 177 } 178 179 180 @("RecursiveFieldTypes.udt.Date") 181 @safe pure unittest { 182 183 import std.datetime: Date, Month; 184 185 static struct Struct { 186 int i; 187 Date date; 188 } 189 190 shouldEqual!(RecursiveFieldTypes!Struct, 191 AliasSeq!(int, Date, short, Month, ubyte)); 192 } 193 194 195 @("RecursiveFieldTypes.udt.DateTime") 196 @safe pure unittest { 197 198 import std.datetime: Date, DateTime, Month, TimeOfDay; 199 200 static struct Struct { 201 int i; 202 DateTime date; 203 } 204 205 shouldEqual!(RecursiveFieldTypes!Struct, 206 AliasSeq!(int, DateTime, Date, short, Month, ubyte, TimeOfDay)); 207 } 208 209 210 @("RecursiveFieldTypes.udt.composite.struct") 211 @safe pure unittest { 212 213 static struct Struct { 214 Struct* child; 215 } 216 217 shouldEqual!(RecursiveFieldTypes!Struct, Struct*); 218 } 219 220 221 @("RecursiveFieldTypes.udt.composite.class.simple") 222 @safe pure unittest { 223 224 static class Class { 225 Class child; 226 } 227 228 shouldEqual!(RecursiveFieldTypes!Class, Class); 229 } 230 231 232 @("RecursiveFieldTypes.udt.composite.class.multiple") 233 @safe pure unittest { 234 235 shouldEqual!(RecursiveFieldTypes!RecursiveClass0, 236 AliasSeq!(RecursiveClass1, RecursiveClass2)); 237 } 238 239 240 private class RecursiveClass0 { 241 RecursiveClass1 child; 242 } 243 244 private class RecursiveClass1 { 245 RecursiveClass2 child; 246 } 247 248 private class RecursiveClass2 { 249 RecursiveClass0 child; 250 } 251 252 253 @("RecursiveFieldTypes.udt.composite.array") 254 @safe pure unittest { 255 256 static struct Point(T) { 257 T x, y; 258 } 259 260 struct Inner1(T) { 261 Point!T point; 262 T value; 263 } 264 265 struct EvenInner(T) { 266 T value; 267 } 268 269 struct Inner2(T) { 270 EvenInner!T evenInner; 271 } 272 273 static struct Outer(T) { 274 Inner1!T[] inner1s; 275 Inner2!T inner2; 276 } 277 278 // pragma(msg, RecursiveFieldTypes!(Outer!double)); 279 shouldEqual!(RecursiveFieldTypes!(Outer!double), 280 AliasSeq!(Inner1!double[], Point!double, double, Inner2!double, EvenInner!double)); 281 } 282 283 284 @("RecursiveFieldTypes.SocketOSException") 285 @safe @nogc pure unittest { 286 import std.socket: SocketOSException; 287 alias types = RecursiveFieldTypes!SocketOSException; 288 //pragma(msg, types); 289 shouldEqual!(types, AliasSeq!int); 290 } 291 292 293 @("isProperty.struct") 294 @safe @nogc pure unittest { 295 296 static struct Struct { 297 int _i; 298 @property int i(); 299 @property void i(int i); 300 int foo(double d); 301 } 302 303 static assert(isProperty!(__traits(getOverloads, Struct, "i")[1])); 304 static assert(isProperty!(__traits(getOverloads, Struct, "i")[1])); 305 static assert(!isProperty!(Struct.foo)); 306 } 307 308 309 @("isProperty.class") 310 @safe @nogc pure unittest { 311 312 static class Class { 313 int _i; 314 @property int i() { return _i; } 315 @property void i(int i) { _i = i; } 316 int foo(double d) { return i * 2; } 317 } 318 319 static assert(isProperty!(__traits(getOverloads, Class, "i")[1])); 320 static assert(isProperty!(__traits(getOverloads, Class, "i")[1])); 321 static assert(!isProperty!(Class.foo)); 322 } 323 324 325 @("MemberFunctions.struct") 326 @safe @nogc pure unittest { 327 328 static struct Struct { 329 private int _i; 330 @property int i(); 331 @property void i(int i); 332 int foo(double d); 333 string bar(int i); 334 } 335 336 //pragma(msg, "MemberFunctions.struct: ", MemberFunctions!Struct.stringof); 337 338 shouldEqual!( 339 MemberFunctions!Struct, 340 AliasSeq!( 341 __traits(getOverloads, Struct, "i")[0], 342 __traits(getOverloads, Struct, "i")[1], 343 Struct.foo, 344 Struct.bar, 345 ) 346 ); 347 } 348 349 350 @("MemberFunctions.class") 351 @safe @nogc pure unittest { 352 353 static class Class { 354 private int _i; 355 @property int i() { return _i; } 356 @property void i(int i) { _i = i; } 357 int foo(double d) { return cast(int) (d * 2); } 358 string bar(int i) { return "foobar"; } 359 } 360 361 //pragma(msg, "MemberFunctions.class: ", MemberFunctions!Class.stringof); 362 363 shouldEqual!( 364 MemberFunctions!Class, 365 AliasSeq!( 366 __traits(getOverloads, Class, "i")[0], 367 __traits(getOverloads, Class, "i")[1], 368 Class.foo, 369 Class.bar, 370 ) 371 ); 372 } 373 374 375 @("PublicMembers.std.socket") 376 @safe @nogc pure unittest { 377 import std.socket; 378 alias members = PublicMembers!(std.socket); 379 }