1 // Written in the D programming language
2 /++
3     Templates which extract information about types and symbols at compile time.
4 
5     In the context of phobos.sys.traits, a "trait" is a template which provides
6     information about a type or symbol. Most traits evaluate to
7     $(D true) or $(D false), telling the code using it whether the given
8     arguments match / have that specific trait (e.g. whether the given type is
9     a dynamic array or whether the given function is $(D @safe)). However, some
10     traits may provide other kinds of information about a type (e.g. the trait
11     could evaluate to the base type for an enum type, or it could strip
12     $(D const) from the type to provide the mutable version of that type).
13 
14     These traits are then used primarily in template constraints so that they
15     can test that the template arguments meet the criteria required by those
16     templates, though they can be useful in a variety of compile-time contexts
17     (e.g. the condition of a $(D static if)).
18 
19     Note that unless otherwise specified, the isXXXX and hasXXX traits in this
20     module are checking for exact matches, so base types (e.g. with enums) and
21     other implicit conversions do not factor into whether such traits are true
22     or false. The type itself is being checked, not what it can be converted
23     to.
24 
25     This is because these traits are often used in templated constraints, and
26     having a type pass a template constraint based on an implicit conversion
27     but then not have the implicit conversion actually take place (which it
28     won't unless the template does something to force it internally) can lead
29     to either compilation errors or subtle behavioral differences - and even
30     when the conversion is done explicitly within a templated function, since
31     it's not done at the call site, it can still lead to subtle bugs in some
32     cases (e.g. if slicing a static array is involved).
33 
34     So, it's typically best to be explicit and clear about a template constraint
35     accepting any kind of implicit conversion rather than having it buried in a
36     trait where programmers stand a good chance of using the trait without
37     realizing that enums might pass based on their base type - or that a type
38     might pass based on some other implicit conversion.
39 
40     Regardless of what a trait is testing for, the documentation strives to be
41     $(I very) clear about what the trait does, and of course, the names do try
42     to make it clear as well - though obviously, only so much information can
43     be put into a name, and some folks will misintrepret some symbols no matter
44     how well they're named. So, please be sure that you clearly understand what
45     these traits do when using them, since messing up template constraints can
46     unfortunately be a great way to introduce subtle bugs into your program.
47     Either way, of course, unit tests are your friends.
48 
49     $(SCRIPT inhibitQuickIndex = 1;)
50 
51     $(BOOKTABLE ,
52     $(TR $(TH Category) $(TH Templates))
53     $(TR $(TD Categories of types) $(TD
54               $(LREF isAggregateType)
55               $(LREF isDynamicArray)
56               $(LREF isFloatingPoint)
57               $(LREF isInstantiationOf)
58               $(LREF isInteger)
59               $(LREF isNumeric)
60               $(LREF isPointer)
61               $(LREF isSignedInteger)
62               $(LREF isStaticArray)
63               $(LREF isUnsignedInteger)
64     ))
65     $(TR $(TD Aggregate Type traits) $(TD
66               $(LREF EnumMembers)
67     ))
68     $(TR $(TD Traits testing for type conversions) $(TD
69               $(LREF isImplicitlyConvertible)
70               $(LREF isQualifierConvertible)
71     ))
72     $(TR $(TD Traits for comparisons) $(TD
73               $(LREF isEqual)
74               $(LREF isSameSymbol)
75               $(LREF isSameType)
76     ))
77     $(TR $(TD Aggregate Type Traits) $(TD
78               $(LREF FieldNames)
79               $(LREF FieldSymbols)
80               $(LREF FieldTypes)
81     ))
82     $(TR $(TD General Types) $(TD
83               $(LREF KeyType)
84               $(LREF OriginalType)
85               $(LREF ValueType)
86     ))
87     $(TR $(TD Traits for removing type qualfiers) $(TD
88               $(LREF Unconst)
89               $(LREF Unshared)
90               $(LREF Unqualified)
91     ))
92     $(TR $(TD Type Constructors) $(TD
93               $(LREF ConstOf)
94               $(LREF ImmutableOf)
95               $(LREF InoutOf)
96               $(LREF SharedOf)
97     ))
98     $(TR $(TD Misc) $(TD
99               $(LREF lvalueOf)
100               $(LREF rvalueOf)
101     ))
102     )
103 
104     Copyright: Copyright The D Language Foundation 2005 - 2024.
105     License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
106     Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)
107                $(HTTP digitalmars.com, Walter Bright),
108                Tomasz Stachowiak (`isExpressions`),
109                $(HTTP erdani.org, Andrei Alexandrescu),
110                Shin Fujishiro,
111                $(HTTP octarineparrot.com, Robert Clipsham),
112                $(HTTP klickverbot.at, David Nadlinger),
113                Kenji Hara,
114                Shoichi Kato
115     Source:    $(PHOBOSSRC phobos/sys/traits)
116 +/
117 module phobos.sys.traits;
118 
119 /++
120     Whether the given type is an "aggregate type" - i.e. a struct, class,
121     interface, or union.
122   +/
123 enum isAggregateType(T) = is(T == struct) || is(T == class) || is(T == interface) || is(T == union);
124 
125 @safe unittest
126 {
127     struct S {}
128     class C {}
129     interface I {}
130     union U {}
131 
132     static assert( isAggregateType!S);
133     static assert( isAggregateType!C);
134     static assert( isAggregateType!I);
135     static assert( isAggregateType!U);
136     static assert( isAggregateType!(const S));
137     static assert( isAggregateType!(shared C));
138 
139     static assert(!isAggregateType!int);
140     static assert(!isAggregateType!string);
141     static assert(!isAggregateType!(S*));
142     static assert(!isAggregateType!(C[]));
143     static assert(!isAggregateType!(I[string]));
144 }
145 
146 /++
147     Whether the given type is a dynamic array (or what is sometimes referred to
148     as a slice, since a dynamic array in D is a slice of memory).
149 
150     Note that this does not include implicit conversions or enum types. The
151     type itself must be a dynamic array.
152 
153     Remember that D's dynamic arrays are essentially:
154     ---
155     struct DynamicArray(T)
156     {
157         size_t length;
158         T* ptr;
159     }
160     ---
161     where $(D ptr) points to the first element in the array, and $(D length) is
162     the number of elements in the array.
163 
164     A dynamic array is not a pointer (unlike arrays in C/C++), and its elements
165     do not live inside the dynamic array itself. The dynamic array is simply a
166     slice of memory and does not own or manage its own memory. It can be a
167     slice of any piece of memory, including GC-allocated memory, the stack,
168     malloc-ed memory, etc. (with what kind of memory it is of course being
169     determined by how the dynamic array was created in the first place)
170     - though if you do any operations on it which end up requiring allocation
171     (e.g. appending to it if it doesn't have the capacity to expand in-place,
172     which it won't if it isn't a slice of GC-allocated memory), then that
173     reallocation will result in the dynamic array being a slice of newly
174     allocated, GC-backed memory (regardless of what it was a slice of before),
175     since it's the GC that deals with those allocations.
176 
177     As long as code just accesses the elements or members of the dynamic array
178     - or reduces its length so that it's a smaller slice - it will continue to
179     point to whatever block of memory it pointed to originally. And because the
180     GC makes sure that appending to a dynamic array does not stomp on the
181     memory of any other dynamic arrays, appending to a dynamic array will not
182     affect any other dynamic array which is a slice of that same block of
183     memory whether a reallocation occurs or not.
184 
185     Regardless, since what allocated the memory that the dynamic array is a
186     slice of is irrevelant to the type of the dynamic array, whether a given
187     type is a dynamic array has nothing to do with the kind of memory that's
188     backing it. A dynamic array which is a slice of a static array of $(D int)
189     is the the same type as a dynamic array of $(D int) allocated with $(D new)
190     - i.e. both are $(D int[]). So, this trait will not tell you anything about
191     what kind of memory a dynamic array is a slice of. It just tells you
192     whether the type is a dynamic array or not.
193 
194     If for some reason, it matters for a function what kind of memory backs one
195     of its parameters which is a dynamic array, or it needs to be made clear
196     whether the function will possibly cause that dynamic array to be
197     reallocated, then that needs to be indicated by the documentation and
198     cannot be enforced with a template constraint. A template constraint can
199     enforce that a type used with a template meets certain criteria (e.g. that
200     it's a dynamic array), but it cannot enforce anything about how the
201     template actually uses the type.
202 
203     However, it $(D is) possible to enforce that a function doesn't use any
204     operations on a dynamic array which might cause it to be reallocated by
205     marking that function as $(D @nogc).
206 
207     In most cases though, code can be written to not care what kind of memory
208     backs a dynamic array, because none of the operations on a dynamic array
209     actually care what kind of memory it's a slice of. It mostly just matters
210     when you need to track the lifetime of the memory, because it wasn't
211     allocated by the GC, or when it matters whether a dynamic array could be
212     reallocated or not (e.g. because the code needs to have that dynamic array
213     continue to point to the same block of memory).
214 
215     See_Also:
216         $(LREF isPointer)
217         $(LREF isStaticArray)
218         $(DDSUBLINK spec/arrays, , The language spec for arrays)
219   +/
220 enum isDynamicArray(T) = is(T == U[], U);
221 
222 ///
223 @safe unittest
224 {
225     // Some types which are dynamic arrays.
226     static assert( isDynamicArray!(int[]));
227     static assert( isDynamicArray!(const int[]));
228     static assert( isDynamicArray!(inout int[]));
229     static assert( isDynamicArray!(shared(int)[]));
230     static assert( isDynamicArray!string);
231 
232     static assert( isDynamicArray!(typeof([1, 2, 3])));
233     static assert( isDynamicArray!(typeof("dlang")));
234 
235     int[] arr;
236     static assert( isDynamicArray!(typeof(arr)));
237 
238     // Some types which aren't dynamic arrays.
239     static assert(!isDynamicArray!int);
240     static assert(!isDynamicArray!(int*));
241     static assert(!isDynamicArray!real);
242 
243     static struct S
244     {
245         int[] arr;
246     }
247     static assert(!isDynamicArray!S);
248 
249     // The struct itself isn't considered a dynamic array,
250     // but its member variable is when checked directly.
251     static assert( isDynamicArray!(typeof(S.arr)));
252 
253     // Static arrays.
254     static assert(!isDynamicArray!(int[5]));
255     static assert(!isDynamicArray!(const(int)[5]));
256 
257     int[2] sArr = [42, 97];
258     static assert(!isDynamicArray!(typeof(sArr)));
259 
260     // While a static array is not a dynamic array,
261     // a slice of a static array is a dynamic array.
262     static assert( isDynamicArray!(typeof(sArr[])));
263 
264     // Dynamic array of static arrays.
265     static assert( isDynamicArray!(long[3][]));
266 
267     // Static array of dynamic arrays.
268     static assert(!isDynamicArray!(long[][3]));
269 
270     // Associative array.
271     static assert(!isDynamicArray!(int[string]));
272 
273     // While typeof(null) gets treated as void[] in some contexts, it is
274     // distinct from void[] and is not considered to be a dynamic array.
275     static assert(!isDynamicArray!(typeof(null)));
276 
277     // However, naturally, if null is cast to a dynamic array, it's a
278     // dynamic array, since the cast forces the type.
279     static assert( isDynamicArray!(typeof(cast(int[]) null)));
280 
281     enum E : int[]
282     {
283         a = [1, 2, 3],
284     }
285 
286     // Enums do not count.
287     static assert(!isDynamicArray!E);
288 
289     static struct AliasThis
290     {
291         int[] arr;
292         alias this = arr;
293     }
294 
295     // Other implicit conversions do not count.
296     static assert(!isDynamicArray!AliasThis);
297 }
298 
299 @safe unittest
300 {
301     import phobos.sys.meta : Alias, AliasSeq;
302 
303     static struct AliasThis(T)
304     {
305         T member;
306         alias this = member;
307     }
308 
309     foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, SharedOf))
310     {
311         foreach (T; AliasSeq!(int[], char[], string, long[3][], double[string][]))
312         {
313             enum E : Q!T { a = Q!T.init }
314 
315             static assert( isDynamicArray!(Q!T));
316             static assert(!isDynamicArray!E);
317             static assert(!isDynamicArray!(AliasThis!(Q!T)));
318         }
319 
320         foreach (T; AliasSeq!(int, int[51], int[][2],
321                               char[][int][11], immutable char[13u],
322                               const(real)[1], const(real)[1][1], void[0]))
323         {
324             enum E : Q!T { a = Q!T.init }
325 
326             static assert(!isDynamicArray!(Q!T));
327             static assert(!isDynamicArray!E);
328             static assert(!isDynamicArray!(AliasThis!(Q!T)));
329         }
330     }
331 }
332 
333 /++
334     Whether type $(D T) is a static array.
335 
336     Note that this does not include implicit conversions or enum types. The
337     type itself must be a static array. This is in contrast to
338     $(D __traits(isStaticArray, T)) which is true for enums (but not for other
339     implict conversions to static arrays).
340 
341     As explained in the module documentation, traits like this one are not true
342     for enums (unlike most of the $(D __traits) traits) in order to avoid
343     testing for implicit conversions by default with template constraints,
344     since that tends to lead to subtle bugs when the code isn't carefully
345     written to take implicit conversions into account.
346 
347     See also:
348         $(DDSUBLINK spec/traits, isStaticArray, $(D __traits(isStaticArray, T)))
349         $(DDSUBLINK spec/arrays, , The language spec for arrays)
350   +/
351 enum isStaticArray(T) = is(T == U[n], U, size_t n);
352 
353 ///
354 @safe unittest
355 {
356     // Some types which are static arrays.
357     static assert( isStaticArray!(int[12]));
358     static assert( isStaticArray!(const int[42]));
359     static assert( isStaticArray!(inout int[0]));
360     static assert( isStaticArray!(shared(int)[907]));
361     static assert( isStaticArray!(immutable(char)[5]));
362 
363     // D doesn't have static array literals, but you get the same effect
364     // by casting a dynamic array literal to a static array, and of course,
365     // the result is typed as a static array.
366     static assert( isStaticArray!(typeof(cast(int[3]) [1, 2, 3])));
367 
368     int[2] sArr = [1, 2];
369     static assert( isStaticArray!(typeof(sArr)));
370 
371     // Some types which are not static arrays.
372     static assert(!isStaticArray!int);
373     static assert(!isStaticArray!(int*));
374     static assert(!isStaticArray!real);
375 
376     static struct S
377     {
378         int[4] arr;
379     }
380     static assert(!isStaticArray!S);
381 
382     // The struct itself isn't considered a static array,
383     // but its member variable is when checked directly.
384     static assert( isStaticArray!(typeof(S.arr)));
385 
386     // Dynamic arrays.
387     static assert(!isStaticArray!(int[]));
388     static assert(!isStaticArray!(const(int)[]));
389     static assert(!isStaticArray!string);
390 
391     int[] arr;
392     static assert(!isStaticArray!(typeof(arr)));
393 
394     // A slice of a static array is of course not a static array,
395     // because it's a dynamic array.
396     static assert(!isStaticArray!(typeof(sArr[])));
397 
398     // Static array of dynamic arrays.
399     static assert( isStaticArray!(long[][3]));
400 
401     // Dynamic array of static arrays.
402     static assert(!isStaticArray!(long[3][]));
403 
404     // Associative array.
405     static assert(!isStaticArray!(int[string]));
406 
407     // Of course, null is not considered to be a static array.
408     static assert(!isStaticArray!(typeof(null)));
409 
410     enum E : int[3]
411     {
412         a = [1, 2, 3],
413     }
414 
415     // Enums do not count.
416     static assert(!isStaticArray!E);
417 
418     // This is where isStaticArray differs from __traits(isStaticArray, ...)
419     static assert( __traits(isStaticArray, E));
420 
421     static struct AliasThis
422     {
423         int[] arr;
424         alias this = arr;
425     }
426 
427     // Other implicit conversions do not count.
428     static assert(!isStaticArray!AliasThis);
429 
430     static assert(!__traits(isStaticArray, AliasThis));
431 }
432 
433 @safe unittest
434 {
435     import phobos.sys.meta : Alias, AliasSeq;
436 
437     static struct AliasThis(T)
438     {
439         T member;
440         alias this = member;
441     }
442 
443     foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, SharedOf))
444     {
445         foreach (T; AliasSeq!(int[51], int[][2],
446                               char[][int][11], immutable char[13u],
447                               const(real)[1], const(real)[1][1], void[0]))
448         {
449             enum E : Q!T { a = Q!T.init, }
450 
451             static assert( isStaticArray!(Q!T));
452             static assert(!isStaticArray!E);
453             static assert(!isStaticArray!(AliasThis!(Q!T)));
454         }
455 
456         foreach (T; AliasSeq!(int, int[], char[], string, long[3][], double[string][]))
457         {
458             enum E : Q!T { a = Q!T.init, }
459 
460             static assert(!isStaticArray!(Q!T));
461             static assert(!isStaticArray!E);
462             static assert(!isStaticArray!(AliasThis!(Q!T)));
463         }
464     }
465 }
466 
467 /++
468     Whether the given type is one of the built-in integer types, ignoring all
469     qualifiers.
470 
471     $(TABLE
472         $(TR $(TH Integer Types))
473         $(TR $(TD byte))
474         $(TR $(TD ubyte))
475         $(TR $(TD short))
476         $(TR $(TD ushort))
477         $(TR $(TD int))
478         $(TR $(TD uint))
479         $(TR $(TD long))
480         $(TR $(TD ulong))
481     )
482 
483     Note that this does not include implicit conversions or enum types. The
484     type itself must be one of the built-in integer types.
485 
486     This trait does have some similarities with $(D __traits(isIntegral, T)),
487     but $(D isIntegral) accepts a $(I lot) more types than isInteger does.
488     isInteger is specifically for testing for the built-in integer types,
489     whereas $(D isIntegral) tests for a whole set of types that are vaguely
490     integer-like (including $(D bool), the three built-in character types, and
491     some of the vector types from core.simd). So, for most code, isInteger is
492     going to be more appropriate, but obviously, it depends on what the code is
493     trying to do.
494 
495     See also:
496         $(DDSUBLINK spec/traits, isIntegral, $(D __traits(isIntegral, T)))
497         $(LREF isFloatingPoint)
498         $(LREF isSignedInteger)
499         $(LREF isNumeric)
500         $(LREF isUnsignedInteger)
501   +/
502 enum isInteger(T) = is(immutable T == immutable byte) ||
503                     is(immutable T == immutable ubyte) ||
504                     is(immutable T == immutable short) ||
505                     is(immutable T == immutable ushort) ||
506                     is(immutable T == immutable int) ||
507                     is(immutable T == immutable uint) ||
508                     is(immutable T == immutable long) ||
509                     is(immutable T == immutable ulong);
510 
511 ///
512 @safe unittest
513 {
514     // Some types which are integer types.
515     static assert( isInteger!byte);
516     static assert( isInteger!ubyte);
517     static assert( isInteger!short);
518     static assert( isInteger!ushort);
519     static assert( isInteger!int);
520     static assert( isInteger!uint);
521     static assert( isInteger!long);
522     static assert( isInteger!ulong);
523 
524     static assert( isInteger!(const ubyte));
525     static assert( isInteger!(immutable short));
526     static assert( isInteger!(inout int));
527     static assert( isInteger!(shared uint));
528     static assert( isInteger!(const shared ulong));
529 
530     static assert( isInteger!(typeof(42)));
531     static assert( isInteger!(typeof(1234567890L)));
532 
533     int i;
534     static assert( isInteger!(typeof(i)));
535 
536     // Some types which aren't integer types.
537     static assert(!isInteger!bool);
538     static assert(!isInteger!char);
539     static assert(!isInteger!wchar);
540     static assert(!isInteger!dchar);
541     static assert(!isInteger!(int[]));
542     static assert(!isInteger!(ubyte[4]));
543     static assert(!isInteger!(int*));
544     static assert(!isInteger!double);
545     static assert(!isInteger!string);
546 
547     static struct S
548     {
549         int i;
550     }
551     static assert(!isInteger!S);
552 
553     // The struct itself isn't considered an integer,
554     // but its member variable is when checked directly.
555     static assert( isInteger!(typeof(S.i)));
556 
557     enum E : int
558     {
559         a = 42
560     }
561 
562     // Enums do not count.
563     static assert(!isInteger!E);
564 
565     static struct AliasThis
566     {
567         int i;
568         alias this = i;
569     }
570 
571     // Other implicit conversions do not count.
572     static assert(!isInteger!AliasThis);
573 }
574 
575 @safe unittest
576 {
577     import phobos.sys.meta : Alias, AliasSeq;
578 
579     static struct AliasThis(T)
580     {
581         T member;
582         alias this = member;
583     }
584 
585     // The actual core.simd types available vary from system to system, so we
586     // have to be a bit creative here. The reason that we're testing these types
587     // is because __traits(isIntegral, T) accepts them, but isInteger is not
588     // supposed to.
589     template SIMDTypes()
590     {
591         import core.simd;
592 
593         alias SIMDTypes = AliasSeq!();
594         static if (is(ubyte16))
595             SIMDTypes = AliasSeq!(SIMDTypes, ubyte16);
596         static if (is(int4))
597             SIMDTypes = AliasSeq!(SIMDTypes, int4);
598         static if (is(double2))
599             SIMDTypes = AliasSeq!(SIMDTypes, double2);
600         static if (is(void16))
601             SIMDTypes = AliasSeq!(SIMDTypes, void16);
602     }
603 
604     foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, SharedOf))
605     {
606         foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
607         {
608             enum E : Q!T { a = Q!T.init }
609 
610             static assert( isInteger!(Q!T));
611             static assert(!isInteger!E);
612             static assert(!isInteger!(AliasThis!(Q!T)));
613         }
614 
615         foreach (T; AliasSeq!(bool, char, wchar, dchar, float, double, real, SIMDTypes!(),
616                               int[], ubyte[8], dchar[], void[], long*))
617         {
618             enum E : Q!T { a = Q!T.init }
619 
620             static assert(!isInteger!(Q!T));
621             static assert(!isInteger!E);
622             static assert(!isInteger!(AliasThis!(Q!T)));
623         }
624     }
625 }
626 
627 /++
628     Whether the given type is one of the built-in signed integer types, ignoring
629     all qualifiers.
630 
631     $(TABLE
632         $(TR $(TH Signed Integer Types))
633         $(TR $(TD byte))
634         $(TR $(TD short))
635         $(TR $(TD int))
636         $(TR $(TD long))
637     )
638 
639     Note that this does not include implicit conversions or enum types. The
640     type itself must be one of the built-in signed integer types.
641 
642     See also:
643         $(LREF isFloatingPoint)
644         $(LREF isInteger)
645         $(LREF isNumeric)
646         $(LREF isUnsignedInteger)
647   +/
648 enum isSignedInteger(T) = is(immutable T == immutable byte) ||
649                           is(immutable T == immutable short) ||
650                           is(immutable T == immutable int) ||
651                           is(immutable T == immutable long);
652 
653 ///
654 @safe unittest
655 {
656     // Some types which are signed integer types.
657     static assert( isSignedInteger!byte);
658     static assert( isSignedInteger!short);
659     static assert( isSignedInteger!int);
660     static assert( isSignedInteger!long);
661 
662     static assert( isSignedInteger!(const byte));
663     static assert( isSignedInteger!(immutable short));
664     static assert( isSignedInteger!(inout int));
665     static assert( isSignedInteger!(shared int));
666     static assert( isSignedInteger!(const shared long));
667 
668     static assert( isSignedInteger!(typeof(42)));
669     static assert( isSignedInteger!(typeof(1234567890L)));
670 
671     int i;
672     static assert( isSignedInteger!(typeof(i)));
673 
674     // Some types which aren't signed integer types.
675     static assert(!isSignedInteger!ubyte);
676     static assert(!isSignedInteger!ushort);
677     static assert(!isSignedInteger!uint);
678     static assert(!isSignedInteger!ulong);
679 
680     static assert(!isSignedInteger!bool);
681     static assert(!isSignedInteger!char);
682     static assert(!isSignedInteger!wchar);
683     static assert(!isSignedInteger!dchar);
684     static assert(!isSignedInteger!(int[]));
685     static assert(!isSignedInteger!(ubyte[4]));
686     static assert(!isSignedInteger!(int*));
687     static assert(!isSignedInteger!double);
688     static assert(!isSignedInteger!string);
689 
690     static struct S
691     {
692         int i;
693     }
694     static assert(!isSignedInteger!S);
695 
696     // The struct itself isn't considered a signed integer,
697     // but its member variable is when checked directly.
698     static assert( isSignedInteger!(typeof(S.i)));
699 
700     enum E : int
701     {
702         a = 42
703     }
704 
705     // Enums do not count.
706     static assert(!isSignedInteger!E);
707 
708     static struct AliasThis
709     {
710         int i;
711         alias this = i;
712     }
713 
714     // Other implicit conversions do not count.
715     static assert(!isSignedInteger!AliasThis);
716 }
717 
718 @safe unittest
719 {
720     import phobos.sys.meta : Alias, AliasSeq;
721 
722     static struct AliasThis(T)
723     {
724         T member;
725         alias this = member;
726     }
727 
728     // The actual core.simd types available vary from system to system, so we
729     // have to be a bit creative here. The reason that we're testing these types
730     // is because __traits(isIntegral, T) accepts them, but isSignedInteger is
731     // not supposed to.
732     template SIMDTypes()
733     {
734         import core.simd;
735 
736         alias SIMDTypes = AliasSeq!();
737         static if (is(ubyte16))
738             SIMDTypes = AliasSeq!(SIMDTypes, ubyte16);
739         static if (is(int4))
740             SIMDTypes = AliasSeq!(SIMDTypes, int4);
741         static if (is(double2))
742             SIMDTypes = AliasSeq!(SIMDTypes, double2);
743         static if (is(void16))
744             SIMDTypes = AliasSeq!(SIMDTypes, void16);
745     }
746 
747     foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, SharedOf))
748     {
749         foreach (T; AliasSeq!(byte, short, int, long))
750         {
751             enum E : Q!T { a = Q!T.init }
752 
753             static assert( isSignedInteger!(Q!T));
754             static assert(!isSignedInteger!E);
755             static assert(!isSignedInteger!(AliasThis!(Q!T)));
756         }
757 
758         foreach (T; AliasSeq!(ubyte, ushort, uint, ulong,
759                               bool, char, wchar, dchar, float, double, real, SIMDTypes!(),
760                               int[], ubyte[8], dchar[], void[], long*))
761         {
762             enum E : Q!T { a = Q!T.init }
763 
764             static assert(!isSignedInteger!(Q!T));
765             static assert(!isSignedInteger!E);
766             static assert(!isSignedInteger!(AliasThis!(Q!T)));
767         }
768     }
769 }
770 
771 /++
772     Whether the given type is one of the built-in unsigned integer types,
773     ignoring all qualifiers.
774 
775     $(TABLE
776         $(TR $(TH Integer Types))
777         $(TR $(TD ubyte))
778         $(TR $(TD ushort))
779         $(TR $(TD uint))
780         $(TR $(TD ulong))
781     )
782 
783     Note that this does not include implicit conversions or enum types. The
784     type itself must be one of the built-in unsigned integer types.
785 
786     This trait does have some similarities with $(D __traits(isUnsigned, T)),
787     but $(D isUnsigned) accepts a $(I lot) more types than isUnsignedInteger
788     does. isUnsignedInteger is specifically for testing for the built-in
789     unsigned integer types, whereas $(D isUnsigned) tests for a whole set of
790     types that are unsigned and vaguely integer-like (including $(D bool), the
791     three built-in character types, and some of the vector types from
792     core.simd). So, for most code, isUnsignedInteger is going to be more
793     appropriate, but obviously, it depends on what the code is trying to do.
794 
795     See also:
796         $(DDSUBLINK spec/traits, isUnsigned, $(D __traits(isUnsigned, T)))
797         $(LREF isFloatingPoint)
798         $(LREF isInteger)
799         $(LREF isSignedInteger)
800         $(LREF isNumeric)
801   +/
802 enum isUnsignedInteger(T) = is(immutable T == immutable ubyte) ||
803                             is(immutable T == immutable ushort) ||
804                             is(immutable T == immutable uint) ||
805                             is(immutable T == immutable ulong);
806 
807 ///
808 @safe unittest
809 {
810     // Some types which are unsigned integer types.
811     static assert( isUnsignedInteger!ubyte);
812     static assert( isUnsignedInteger!ushort);
813     static assert( isUnsignedInteger!uint);
814     static assert( isUnsignedInteger!ulong);
815 
816     static assert( isUnsignedInteger!(const ubyte));
817     static assert( isUnsignedInteger!(immutable ushort));
818     static assert( isUnsignedInteger!(inout uint));
819     static assert( isUnsignedInteger!(shared uint));
820     static assert( isUnsignedInteger!(const shared ulong));
821 
822     static assert( isUnsignedInteger!(typeof(42u)));
823     static assert( isUnsignedInteger!(typeof(1234567890UL)));
824 
825     uint u;
826     static assert( isUnsignedInteger!(typeof(u)));
827 
828     // Some types which aren't unsigned integer types.
829     static assert(!isUnsignedInteger!byte);
830     static assert(!isUnsignedInteger!short);
831     static assert(!isUnsignedInteger!int);
832     static assert(!isUnsignedInteger!long);
833 
834     static assert(!isUnsignedInteger!bool);
835     static assert(!isUnsignedInteger!char);
836     static assert(!isUnsignedInteger!wchar);
837     static assert(!isUnsignedInteger!dchar);
838     static assert(!isUnsignedInteger!(int[]));
839     static assert(!isUnsignedInteger!(ubyte[4]));
840     static assert(!isUnsignedInteger!(int*));
841     static assert(!isUnsignedInteger!double);
842     static assert(!isUnsignedInteger!string);
843 
844     static struct S
845     {
846         uint u;
847     }
848     static assert(!isUnsignedInteger!S);
849 
850     // The struct itself isn't considered an unsigned integer,
851     // but its member variable is when checked directly.
852     static assert( isUnsignedInteger!(typeof(S.u)));
853 
854     enum E : uint
855     {
856         a = 42
857     }
858 
859     // Enums do not count.
860     static assert(!isUnsignedInteger!E);
861 
862     static struct AliasThis
863     {
864         uint u;
865         alias this = u;
866     }
867 
868     // Other implicit conversions do not count.
869     static assert(!isUnsignedInteger!AliasThis);
870 }
871 
872 @safe unittest
873 {
874     import phobos.sys.meta : Alias, AliasSeq;
875 
876     static struct AliasThis(T)
877     {
878         T member;
879         alias this = member;
880     }
881 
882     // The actual core.simd types available vary from system to system, so we
883     // have to be a bit creative here. The reason that we're testing these types
884     // is because __traits(isIntegral, T) and __traits(isUnsigned, T) accept
885     // them, but isUnsignedInteger is not supposed to.
886     template SIMDTypes()
887     {
888         import core.simd;
889 
890         alias SIMDTypes = AliasSeq!();
891         static if (is(ubyte16))
892             SIMDTypes = AliasSeq!(SIMDTypes, ubyte16);
893         static if (is(int4))
894             SIMDTypes = AliasSeq!(SIMDTypes, int4);
895         static if (is(double2))
896             SIMDTypes = AliasSeq!(SIMDTypes, double2);
897         static if (is(void16))
898             SIMDTypes = AliasSeq!(SIMDTypes, void16);
899     }
900 
901     foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, SharedOf))
902     {
903         foreach (T; AliasSeq!(ubyte, ushort, uint, ulong))
904         {
905             enum E : Q!T { a = Q!T.init }
906 
907             static assert( isUnsignedInteger!(Q!T));
908             static assert(!isUnsignedInteger!E);
909             static assert(!isUnsignedInteger!(AliasThis!(Q!T)));
910         }
911 
912         foreach (T; AliasSeq!(byte, short, int, long,
913                               bool, char, wchar, dchar, float, double, real, SIMDTypes!(),
914                               int[], ubyte[8], dchar[], void[], long*))
915         {
916             enum E : Q!T { a = Q!T.init }
917 
918             static assert(!isUnsignedInteger!(Q!T));
919             static assert(!isUnsignedInteger!E);
920             static assert(!isUnsignedInteger!(AliasThis!(Q!T)));
921         }
922     }
923 }
924 
925 /++
926     Whether the given type is one of the built-in floating-point types, ignoring
927     all qualifiers.
928 
929     $(TABLE
930         $(TR $(TH Floating-Point Types))
931         $(TR $(TD float))
932         $(TR $(TD double))
933         $(TR $(TD real))
934     )
935 
936     Note that this does not include implicit conversions or enum types. The
937     type itself must be one of the built-in floating-point types.
938 
939     This trait does have some similarities with $(D __traits(isFloating, T)),
940     but $(D isFloating) accepts more types than isFloatingPoint does.
941     isFloatingPoint is specifically for testing for the built-in floating-point
942     types, whereas $(D isFloating) tests for a whole set of types that are
943     vaguely float-like (including enums with a base type which is a
944     floating-point type and some of the vector types from core.simd). So, for
945     most code, isFloatingPoint is going to be more appropriate, but obviously,
946     it depends on what the code is trying to do.
947 
948     See also:
949         $(DDSUBLINK spec/traits, isFloating, $(D __traits(isFloating, T)))
950         $(LREF isInteger)
951         $(LREF isSignedInteger)
952         $(LREF isNumeric)
953         $(LREF isUnsignedInteger)
954   +/
955 enum isFloatingPoint(T) = is(immutable T == immutable float) ||
956                           is(immutable T == immutable double) ||
957                           is(immutable T == immutable real);
958 
959 ///
960 @safe unittest
961 {
962     // Some types which are floating-point types.
963     static assert( isFloatingPoint!float);
964     static assert( isFloatingPoint!double);
965     static assert( isFloatingPoint!real);
966 
967     static assert( isFloatingPoint!(const float));
968     static assert( isFloatingPoint!(immutable float));
969     static assert( isFloatingPoint!(inout double));
970     static assert( isFloatingPoint!(shared double));
971     static assert( isFloatingPoint!(const shared real));
972 
973     static assert( isFloatingPoint!(typeof(42.0)));
974     static assert( isFloatingPoint!(typeof(42f)));
975     static assert( isFloatingPoint!(typeof(1e5)));
976     static assert( isFloatingPoint!(typeof(97.4L)));
977 
978     double d;
979     static assert( isFloatingPoint!(typeof(d)));
980 
981     // Some types which aren't floating-point types.
982     static assert(!isFloatingPoint!bool);
983     static assert(!isFloatingPoint!char);
984     static assert(!isFloatingPoint!dchar);
985     static assert(!isFloatingPoint!int);
986     static assert(!isFloatingPoint!long);
987     static assert(!isFloatingPoint!(float[]));
988     static assert(!isFloatingPoint!(double[4]));
989     static assert(!isFloatingPoint!(real*));
990     static assert(!isFloatingPoint!string);
991 
992     static struct S
993     {
994         double d;
995     }
996     static assert(!isFloatingPoint!S);
997 
998     // The struct itself isn't considered a floating-point type,
999     // but its member variable is when checked directly.
1000     static assert( isFloatingPoint!(typeof(S.d)));
1001 
1002     enum E : double
1003     {
1004         a = 12.34
1005     }
1006 
1007     // Enums do not count.
1008     static assert(!isFloatingPoint!E);
1009 
1010     static struct AliasThis
1011     {
1012         double d;
1013         alias this = d;
1014     }
1015 
1016     // Other implicit conversions do not count.
1017     static assert(!isFloatingPoint!AliasThis);
1018 }
1019 
1020 @safe unittest
1021 {
1022     import phobos.sys.meta : Alias, AliasSeq;
1023 
1024     static struct AliasThis(T)
1025     {
1026         T member;
1027         alias this = member;
1028     }
1029 
1030     // The actual core.simd types available vary from system to system, so we
1031     // have to be a bit creative here. The reason that we're testing these types
1032     // is because __traits(isFloating, T) accepts them, but isFloatingPoint is
1033     // not supposed to.
1034     template SIMDTypes()
1035     {
1036         import core.simd;
1037 
1038         alias SIMDTypes = AliasSeq!();
1039         static if (is(int4))
1040             SIMDTypes = AliasSeq!(SIMDTypes, int4);
1041         static if (is(double2))
1042             SIMDTypes = AliasSeq!(SIMDTypes, double2);
1043         static if (is(void16))
1044             SIMDTypes = AliasSeq!(SIMDTypes, void16);
1045     }
1046 
1047     foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, SharedOf))
1048     {
1049         foreach (T; AliasSeq!(float, double, real))
1050         {
1051             enum E : Q!T { a = Q!T.init }
1052 
1053             static assert( isFloatingPoint!(Q!T));
1054             static assert(!isFloatingPoint!E);
1055             static assert(!isFloatingPoint!(AliasThis!(Q!T)));
1056         }
1057 
1058         foreach (T; AliasSeq!(bool, char, wchar, dchar, byte, ubyte, short, ushort,
1059                               int, uint, long, ulong, SIMDTypes!(),
1060                               int[], float[8], real[], void[], double*))
1061         {
1062             enum E : Q!T { a = Q!T.init }
1063 
1064             static assert(!isFloatingPoint!(Q!T));
1065             static assert(!isFloatingPoint!E);
1066             static assert(!isFloatingPoint!(AliasThis!(Q!T)));
1067         }
1068     }
1069 }
1070 
1071 /++
1072     Whether the given type is one of the built-in numeric types, ignoring all
1073     qualifiers. It's equivalent to $(D isInteger!T || isFloatingPoint!T), but
1074     it only involves a single template instantation instead of two.
1075 
1076     $(TABLE
1077         $(TR $(TH Numeric Types))
1078         $(TR $(TD byte))
1079         $(TR $(TD ubyte))
1080         $(TR $(TD short))
1081         $(TR $(TD ushort))
1082         $(TR $(TD int))
1083         $(TR $(TD uint))
1084         $(TR $(TD long))
1085         $(TR $(TD ulong))
1086         $(TR $(TD float))
1087         $(TR $(TD double))
1088         $(TR $(TD real))
1089     )
1090 
1091     Note that this does not include implicit conversions or enum types. The
1092     type itself must be one of the built-in numeric types.
1093 
1094     See_Also:
1095         $(LREF isFloatingPoint)
1096         $(LREF isInteger)
1097         $(LREF isSignedInteger)
1098         $(LREF isUnsignedInteger)
1099   +/
1100 enum isNumeric(T) = is(immutable T == immutable byte) ||
1101                     is(immutable T == immutable ubyte) ||
1102                     is(immutable T == immutable short) ||
1103                     is(immutable T == immutable ushort) ||
1104                     is(immutable T == immutable int) ||
1105                     is(immutable T == immutable uint) ||
1106                     is(immutable T == immutable long) ||
1107                     is(immutable T == immutable ulong) ||
1108                     is(immutable T == immutable float) ||
1109                     is(immutable T == immutable double) ||
1110                     is(immutable T == immutable real);
1111 
1112 ///
1113 @safe unittest
1114 {
1115     // Some types which are numeric types.
1116     static assert( isNumeric!byte);
1117     static assert( isNumeric!ubyte);
1118     static assert( isNumeric!short);
1119     static assert( isNumeric!ushort);
1120     static assert( isNumeric!int);
1121     static assert( isNumeric!uint);
1122     static assert( isNumeric!long);
1123     static assert( isNumeric!ulong);
1124     static assert( isNumeric!float);
1125     static assert( isNumeric!double);
1126     static assert( isNumeric!real);
1127 
1128     static assert( isNumeric!(const short));
1129     static assert( isNumeric!(immutable int));
1130     static assert( isNumeric!(inout uint));
1131     static assert( isNumeric!(shared long));
1132     static assert( isNumeric!(const shared real));
1133 
1134     static assert( isNumeric!(typeof(42)));
1135     static assert( isNumeric!(typeof(1234657890L)));
1136     static assert( isNumeric!(typeof(42.0)));
1137     static assert( isNumeric!(typeof(42f)));
1138     static assert( isNumeric!(typeof(1e5)));
1139     static assert( isNumeric!(typeof(97.4L)));
1140 
1141     int i;
1142     static assert( isNumeric!(typeof(i)));
1143 
1144     // Some types which aren't numeric types.
1145     static assert(!isNumeric!bool);
1146     static assert(!isNumeric!char);
1147     static assert(!isNumeric!dchar);
1148     static assert(!isNumeric!(int[]));
1149     static assert(!isNumeric!(double[4]));
1150     static assert(!isNumeric!(real*));
1151     static assert(!isNumeric!string);
1152 
1153     static struct S
1154     {
1155         int i;
1156     }
1157     static assert(!isNumeric!S);
1158 
1159     // The struct itself isn't considered a numeric type,
1160     // but its member variable is when checked directly.
1161     static assert( isNumeric!(typeof(S.i)));
1162 
1163     enum E : int
1164     {
1165         a = 42
1166     }
1167 
1168     // Enums do not count.
1169     static assert(!isNumeric!E);
1170 
1171     static struct AliasThis
1172     {
1173         int i;
1174         alias this = i;
1175     }
1176 
1177     // Other implicit conversions do not count.
1178     static assert(!isNumeric!AliasThis);
1179 }
1180 
1181 @safe unittest
1182 {
1183     import phobos.sys.meta : Alias, AliasSeq;
1184 
1185     static struct AliasThis(T)
1186     {
1187         T member;
1188         alias this = member;
1189     }
1190 
1191     // The actual core.simd types available vary from system to system, so we
1192     // have to be a bit creative here. The reason that we're testing these types
1193     // is because __traits(isInteger, T) and __traits(isFloating, T) accept
1194     // them, but isNumeric is not supposed to.
1195     template SIMDTypes()
1196     {
1197         import core.simd;
1198 
1199         alias SIMDTypes = AliasSeq!();
1200         static if (is(int4))
1201             SIMDTypes = AliasSeq!(SIMDTypes, int4);
1202         static if (is(double2))
1203             SIMDTypes = AliasSeq!(SIMDTypes, double2);
1204         static if (is(void16))
1205             SIMDTypes = AliasSeq!(SIMDTypes, void16);
1206     }
1207 
1208     foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, SharedOf))
1209     {
1210         foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real))
1211         {
1212             enum E : Q!T { a = Q!T.init }
1213 
1214             static assert( isNumeric!(Q!T));
1215             static assert(!isNumeric!E);
1216             static assert(!isNumeric!(AliasThis!(Q!T)));
1217         }
1218 
1219         foreach (T; AliasSeq!(bool, char, wchar, dchar, SIMDTypes!(),
1220                               int[], float[8], real[], void[], double*))
1221         {
1222             enum E : Q!T { a = Q!T.init }
1223 
1224             static assert(!isNumeric!(Q!T));
1225             static assert(!isNumeric!E);
1226             static assert(!isNumeric!(AliasThis!(Q!T)));
1227         }
1228     }
1229 }
1230 
1231 /++
1232     Whether the given type is a pointer.
1233 
1234     Note that this does not include implicit conversions or enum types. The
1235     type itself must be a pointer.
1236 
1237     Also, remember that unlike C/C++, D's arrays are not pointers. Rather, a
1238     dynamic array in D is a slice of memory which has a member which is a
1239     pointer to its first element and another member which is the length of the
1240     array as $(D size_t). So, a dynamic array / slice has a $(D ptr) member
1241     which is a pointer, but the dynamic array itself is not a pointer.
1242 
1243     See_Also:
1244         $(LREF isDynamicArray)
1245   +/
1246 enum isPointer(T) = is(T == U*, U);
1247 
1248 ///
1249 @system unittest
1250 {
1251     // Some types which are pointers.
1252     static assert( isPointer!(bool*));
1253     static assert( isPointer!(int*));
1254     static assert( isPointer!(int**));
1255     static assert( isPointer!(real*));
1256     static assert( isPointer!(string*));
1257 
1258     static assert( isPointer!(const int*));
1259     static assert( isPointer!(immutable int*));
1260     static assert( isPointer!(inout int*));
1261     static assert( isPointer!(shared int*));
1262     static assert( isPointer!(const shared int*));
1263 
1264     static assert( isPointer!(typeof("foobar".ptr)));
1265 
1266     int* ptr;
1267     static assert( isPointer!(typeof(ptr)));
1268 
1269     int i;
1270     static assert( isPointer!(typeof(&i)));
1271 
1272     // Some types which aren't pointers.
1273     static assert(!isPointer!bool);
1274     static assert(!isPointer!int);
1275     static assert(!isPointer!dchar);
1276     static assert(!isPointer!(int[]));
1277     static assert(!isPointer!(double[4]));
1278     static assert(!isPointer!string);
1279 
1280     static struct S
1281     {
1282         int* ptr;
1283     }
1284     static assert(!isPointer!S);
1285 
1286     // The struct itself isn't considered a numeric type,
1287     // but its member variable is when checked directly.
1288     static assert( isPointer!(typeof(S.ptr)));
1289 
1290     enum E : immutable(char*)
1291     {
1292         a = "foobar".ptr
1293     }
1294 
1295     // Enums do not count.
1296     static assert(!isPointer!E);
1297 
1298     static struct AliasThis
1299     {
1300         int* ptr;
1301         alias this = ptr;
1302     }
1303 
1304     // Other implicit conversions do not count.
1305     static assert(!isPointer!AliasThis);
1306 }
1307 
1308 @safe unittest
1309 {
1310     import phobos.sys.meta : Alias, AliasSeq;
1311 
1312     static struct AliasThis(T)
1313     {
1314         T member;
1315         alias this = member;
1316     }
1317 
1318     static struct S
1319     {
1320         int i;
1321     }
1322 
1323     foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, SharedOf))
1324     {
1325         foreach (T; AliasSeq!(long*, S*, S**, S***, double[]*))
1326         {
1327             enum E : Q!T { a = Q!T.init }
1328 
1329             static assert( isPointer!(Q!T));
1330             static assert(!isPointer!E);
1331             static assert(!isPointer!(AliasThis!(Q!T)));
1332         }
1333 
1334         foreach (T; AliasSeq!(bool, char, wchar, dchar, byte, int, uint, long,
1335                               int[], float[8], real[], void[]))
1336         {
1337             enum E : Q!T { a = Q!T.init }
1338 
1339             static assert(!isPointer!(Q!T));
1340             static assert(!isPointer!E);
1341             static assert(!isPointer!(AliasThis!(Q!T)));
1342         }
1343     }
1344 }
1345 
1346 /++
1347     Evaluates to $(D true) if the given type or symbol is an instantiation of
1348     the given template.
1349 
1350     The overload which takes $(D T) operates on types and indicates whether an
1351     aggregate type (i.e. struct, class, interface, or union) is an
1352     instantiation of the given template.
1353 
1354     The overload which takes $(D Symbol) operates on function templates,
1355     because unlike with aggregate types, the type of a function does not retain
1356     the fact that it was instantiated from a template. So, for functions, it's
1357     necessary to pass the function itself as a symbol rather than pass the type
1358     of the function.
1359 
1360     The overload which takes $(D Symbol) also works with templates which are
1361     not types or functions.
1362 
1363     The single-argument overload makes it so that it can be partially
1364     instantiated with the first argument, which will often be necessary with
1365     template predicates.
1366   +/
1367 template isInstantiationOf(alias Template, T)
1368 if (__traits(isTemplate, Template))
1369 {
1370     enum isInstantiationOf = is(T == Template!Args, Args...);
1371 }
1372 
1373 /++ Ditto +/
1374 template isInstantiationOf(alias Template, alias Symbol)
1375 if (__traits(isTemplate, Template))
1376 {
1377     enum impl(alias T : Template!Args, Args...) = true;
1378     enum impl(alias T) = false;
1379     enum isInstantiationOf = impl!Symbol;
1380 }
1381 
1382 /++ Ditto +/
1383 template isInstantiationOf(alias Template)
1384 if (__traits(isTemplate, Template))
1385 {
1386     enum isInstantiationOf(T) = is(T == Template!Args, Args...);
1387 
1388     template isInstantiationOf(alias Symbol)
1389     {
1390         enum impl(alias T : Template!Args, Args...) = true;
1391         enum impl(alias T) = false;
1392         enum isInstantiationOf = impl!Symbol;
1393     }
1394 }
1395 
1396 /// Examples of templated types.
1397 @safe unittest
1398 {
1399     static struct S(T) {}
1400     static class C(T) {}
1401 
1402     static assert( isInstantiationOf!(S, S!int));
1403     static assert( isInstantiationOf!(S, S!int));
1404     static assert( isInstantiationOf!(S, S!string));
1405     static assert( isInstantiationOf!(S, const S!string));
1406     static assert( isInstantiationOf!(S, shared S!string));
1407     static assert(!isInstantiationOf!(S, int));
1408     static assert(!isInstantiationOf!(S, C!int));
1409     static assert(!isInstantiationOf!(S, C!string));
1410     static assert(!isInstantiationOf!(S, C!(S!int)));
1411 
1412     static assert( isInstantiationOf!(C, C!int));
1413     static assert( isInstantiationOf!(C, C!string));
1414     static assert( isInstantiationOf!(C, const C!string));
1415     static assert( isInstantiationOf!(C, shared C!string));
1416     static assert(!isInstantiationOf!(C, int));
1417     static assert(!isInstantiationOf!(C, S!int));
1418     static assert(!isInstantiationOf!(C, S!string));
1419     static assert(!isInstantiationOf!(C, S!(C!int)));
1420 
1421     static struct Variadic(T...) {}
1422 
1423     static assert( isInstantiationOf!(Variadic, Variadic!()));
1424     static assert( isInstantiationOf!(Variadic, Variadic!int));
1425     static assert( isInstantiationOf!(Variadic, Variadic!(int, string)));
1426     static assert( isInstantiationOf!(Variadic, Variadic!(int, string, int)));
1427     static assert( isInstantiationOf!(Variadic, const Variadic!(int, short)));
1428     static assert( isInstantiationOf!(Variadic, shared Variadic!(int, short)));
1429     static assert(!isInstantiationOf!(Variadic, int));
1430     static assert(!isInstantiationOf!(Variadic, S!int));
1431     static assert(!isInstantiationOf!(Variadic, C!int));
1432 
1433     static struct ValueArg(int i) {}
1434     static assert( isInstantiationOf!(ValueArg, ValueArg!42));
1435     static assert( isInstantiationOf!(ValueArg, ValueArg!256));
1436     static assert( isInstantiationOf!(ValueArg, const ValueArg!1024));
1437     static assert( isInstantiationOf!(ValueArg, shared ValueArg!1024));
1438     static assert(!isInstantiationOf!(ValueArg, int));
1439     static assert(!isInstantiationOf!(ValueArg, S!int));
1440 
1441     int i;
1442 
1443     static struct AliasArg(alias Symbol) {}
1444     static assert( isInstantiationOf!(AliasArg, AliasArg!42));
1445     static assert( isInstantiationOf!(AliasArg, AliasArg!int));
1446     static assert( isInstantiationOf!(AliasArg, AliasArg!i));
1447     static assert( isInstantiationOf!(AliasArg, const AliasArg!i));
1448     static assert( isInstantiationOf!(AliasArg, shared AliasArg!i));
1449     static assert(!isInstantiationOf!(AliasArg, int));
1450     static assert(!isInstantiationOf!(AliasArg, S!int));
1451 
1452     // An uninstantiated template is not an instance of any template,
1453     // not even itself.
1454     static assert(!isInstantiationOf!(S, S));
1455     static assert(!isInstantiationOf!(S, C));
1456     static assert(!isInstantiationOf!(C, C));
1457     static assert(!isInstantiationOf!(C, S));
1458 
1459     // Variables of a templated type are not considered instantiations of that
1460     // type. For templated types, the overload which takes a type must be used.
1461     S!int s;
1462     C!string c;
1463     static assert(!isInstantiationOf!(S, s));
1464     static assert(!isInstantiationOf!(C, c));
1465 }
1466 
1467 // Examples of templated functions.
1468 @safe unittest
1469 {
1470     static int foo(T...)() { return 42; }
1471     static void bar(T...)(T var) {}
1472     static void baz(T)(T var) {}
1473     static bool frobozz(alias pred)(int) { return true; }
1474 
1475     static assert( isInstantiationOf!(foo, foo!int));
1476     static assert( isInstantiationOf!(foo, foo!string));
1477     static assert( isInstantiationOf!(foo, foo!(int, string)));
1478     static assert(!isInstantiationOf!(foo, bar!int));
1479     static assert(!isInstantiationOf!(foo, bar!string));
1480     static assert(!isInstantiationOf!(foo, bar!(int, string)));
1481 
1482     static assert( isInstantiationOf!(bar, bar!int));
1483     static assert( isInstantiationOf!(bar, bar!string));
1484     static assert( isInstantiationOf!(bar, bar!(int, string)));
1485     static assert(!isInstantiationOf!(bar, foo!int));
1486     static assert(!isInstantiationOf!(bar, foo!string));
1487     static assert(!isInstantiationOf!(bar, foo!(int, string)));
1488 
1489     static assert( isInstantiationOf!(baz, baz!int));
1490     static assert( isInstantiationOf!(baz, baz!string));
1491     static assert(!isInstantiationOf!(baz, foo!(int, string)));
1492 
1493     static assert( isInstantiationOf!(frobozz, frobozz!(a => a)));
1494     static assert( isInstantiationOf!(frobozz, frobozz!(a => a > 2)));
1495     static assert(!isInstantiationOf!(frobozz, baz!int));
1496 
1497     // Unfortunately, the function type is not considered an instantiation of
1498     // the template, because that information is not part of the type, unlike
1499     // with templated structs or classes.
1500     static assert(!isInstantiationOf!(foo, typeof(foo!int)));
1501     static assert(!isInstantiationOf!(bar, typeof(bar!int)));
1502 }
1503 
1504 // Examples of templates which aren't types or functions.
1505 @safe unittest
1506 {
1507     template SingleArg(T) {}
1508     template Variadic(T...) {}
1509     template ValueArg(string s) {}
1510     template Alias(alias symbol) {}
1511 
1512     static assert( isInstantiationOf!(SingleArg, SingleArg!int));
1513     static assert( isInstantiationOf!(SingleArg, SingleArg!string));
1514     static assert(!isInstantiationOf!(SingleArg, int));
1515     static assert(!isInstantiationOf!(SingleArg, Variadic!int));
1516 
1517     static assert( isInstantiationOf!(Variadic, Variadic!()));
1518     static assert( isInstantiationOf!(Variadic, Variadic!int));
1519     static assert( isInstantiationOf!(Variadic, Variadic!string));
1520     static assert( isInstantiationOf!(Variadic, Variadic!(short, int, long)));
1521     static assert(!isInstantiationOf!(Variadic, int));
1522     static assert(!isInstantiationOf!(Variadic, SingleArg!int));
1523 
1524     static assert( isInstantiationOf!(ValueArg, ValueArg!"dlang"));
1525     static assert( isInstantiationOf!(ValueArg, ValueArg!"foobar"));
1526     static assert(!isInstantiationOf!(ValueArg, string));
1527     static assert(!isInstantiationOf!(ValueArg, Variadic!string));
1528 
1529     int i;
1530 
1531     static assert( isInstantiationOf!(Alias, Alias!int));
1532     static assert( isInstantiationOf!(Alias, Alias!42));
1533     static assert( isInstantiationOf!(Alias, Alias!i));
1534     static assert(!isInstantiationOf!(Alias, int));
1535     static assert(!isInstantiationOf!(Alias, SingleArg!int));
1536 }
1537 
1538 /// Examples of partial instantation.
1539 @safe unittest
1540 {
1541     static struct SingleArg(T) {}
1542     static struct Variadic(T...) {}
1543 
1544     alias isSingleArg = isInstantiationOf!SingleArg;
1545     alias isVariadic = isInstantiationOf!Variadic;
1546 
1547     static assert( isSingleArg!(SingleArg!int));
1548     static assert( isSingleArg!(const SingleArg!int));
1549     static assert(!isSingleArg!int);
1550     static assert(!isSingleArg!(Variadic!int));
1551 
1552     static assert( isVariadic!(Variadic!()));
1553     static assert( isVariadic!(Variadic!int));
1554     static assert( isVariadic!(shared Variadic!int));
1555     static assert( isVariadic!(Variadic!(int, string)));
1556     static assert(!isVariadic!int);
1557     static assert(!isVariadic!(SingleArg!int));
1558 
1559     T foo(T)(T t) { return t; }
1560     T likeFoo(T)(T t) { return t; }
1561     bool bar(alias pred)(int i) { return pred(i); }
1562 
1563     alias isFoo = isInstantiationOf!foo;
1564     alias isBar = isInstantiationOf!bar;
1565 
1566     static assert( isFoo!(foo!int));
1567     static assert( isFoo!(foo!string));
1568     static assert(!isFoo!int);
1569     static assert(!isFoo!(likeFoo!int));
1570     static assert(!isFoo!(bar!(a => true)));
1571 
1572     static assert( isBar!(bar!(a => true)));
1573     static assert( isBar!(bar!(a => a > 2)));
1574     static assert(!isBar!int);
1575     static assert(!isBar!(foo!int));
1576     static assert(!isBar!(likeFoo!int));
1577 }
1578 
1579 /++
1580     Evaluates to an $(D AliasSeq) containing the members of an enum type.
1581 
1582     The elements of the $(D AliasSeq) are in the same order as they are in the
1583     enum declaration.
1584 
1585     An enum can have multiple members with the same value, so if code needs the
1586     enum values to be unique (e.g. if it's generating a switch statement from
1587     them), then $(REF Unique, phobos, sys, meta) can be used to filter out the
1588     duplicate values - e.g. $(D Unique!(isEqual, EnumMembers!E)).
1589   +/
1590 template EnumMembers(E)
1591 if (is(E == enum))
1592 {
1593     import phobos.sys.meta : AliasSeq;
1594 
1595     alias EnumMembers = AliasSeq!();
1596     static foreach (member; __traits(allMembers, E))
1597         EnumMembers = AliasSeq!(EnumMembers, __traits(getMember, E, member));
1598 }
1599 
1600 /// Create an array of enum values.
1601 @safe unittest
1602 {
1603     enum Sqrts : real
1604     {
1605         one = 1,
1606         two = 1.41421,
1607         three = 1.73205
1608     }
1609     auto sqrts = [EnumMembers!Sqrts];
1610     assert(sqrts == [Sqrts.one, Sqrts.two, Sqrts.three]);
1611 }
1612 
1613 /++
1614     A generic function $(D rank(v)) in the following example uses this template
1615     for finding a member $(D e) in an enum type $(D E).
1616  +/
1617 @safe unittest
1618 {
1619     // Returns i if e is the i-th member of E.
1620     static size_t rank(E)(E e)
1621     if (is(E == enum))
1622     {
1623         static foreach (i, member; EnumMembers!E)
1624         {
1625             if (e == member)
1626                 return i;
1627         }
1628         assert(0, "Not an enum member");
1629     }
1630 
1631     enum Mode
1632     {
1633         read = 1,
1634         write = 2,
1635         map = 4
1636     }
1637     assert(rank(Mode.read) == 0);
1638     assert(rank(Mode.write) == 1);
1639     assert(rank(Mode.map) == 2);
1640 }
1641 
1642 /// Use EnumMembers to generate a switch statement using static foreach.
1643 @safe unittest
1644 {
1645     static class Foo
1646     {
1647         string calledMethod;
1648         void foo() @safe { calledMethod = "foo"; }
1649         void bar() @safe { calledMethod = "bar"; }
1650         void baz() @safe { calledMethod = "baz"; }
1651     }
1652 
1653     enum FuncName : string { foo = "foo", bar = "bar", baz = "baz" }
1654 
1655     auto foo = new Foo;
1656 
1657     s: final switch (FuncName.bar)
1658     {
1659         static foreach (member; EnumMembers!FuncName)
1660         {
1661             // Generate a case for each enum value.
1662             case member:
1663             {
1664                 // Call foo.{enum value}().
1665                 __traits(getMember, foo, member)();
1666                 break s;
1667             }
1668         }
1669     }
1670 
1671     // Since we passed FuncName.bar to the switch statement, the bar member
1672     // function was called.
1673     assert(foo.calledMethod == "bar");
1674 }
1675 
1676 @safe unittest
1677 {
1678     {
1679         enum A { a }
1680         static assert([EnumMembers!A] == [A.a]);
1681         enum B { a, b, c, d, e }
1682         static assert([EnumMembers!B] == [B.a, B.b, B.c, B.d, B.e]);
1683     }
1684     {
1685         enum A : string { a = "alpha", b = "beta" }
1686         static assert([EnumMembers!A] == [A.a, A.b]);
1687 
1688         static struct S
1689         {
1690             int value;
1691             int opCmp(S rhs) const nothrow { return value - rhs.value; }
1692         }
1693         enum B : S { a = S(1), b = S(2), c = S(3) }
1694         static assert([EnumMembers!B] == [B.a, B.b, B.c]);
1695     }
1696     {
1697         enum A { a = 0, b = 0, c = 1, d = 1, e }
1698         static assert([EnumMembers!A] == [A.a, A.b, A.c, A.d, A.e]);
1699     }
1700     {
1701         enum E { member, a = 0, b = 0 }
1702 
1703         static assert(__traits(isSame, EnumMembers!E[0], E.member));
1704         static assert(__traits(isSame, EnumMembers!E[1], E.a));
1705         static assert(__traits(isSame, EnumMembers!E[2], E.b));
1706 
1707         static assert(__traits(identifier, EnumMembers!E[0]) == "member");
1708         static assert(__traits(identifier, EnumMembers!E[1]) == "a");
1709         static assert(__traits(identifier, EnumMembers!E[2]) == "b");
1710     }
1711 }
1712 
1713 // https://issues.dlang.org/show_bug.cgi?id=14561: huge enums
1714 @safe unittest
1715 {
1716     static string genEnum()
1717     {
1718         string result = "enum TLAs {";
1719         foreach (c0; '0' .. '2' + 1)
1720         {
1721             foreach (c1; '0' .. '9' + 1)
1722             {
1723                 foreach (c2; '0' .. '9' + 1)
1724                 {
1725                     foreach (c3; '0' .. '9' + 1)
1726                     {
1727                         result ~= '_';
1728                         result ~= c0;
1729                         result ~= c1;
1730                         result ~= c2;
1731                         result ~= c3;
1732                         result ~= ',';
1733                     }
1734                 }
1735             }
1736         }
1737         result ~= '}';
1738         return result;
1739     }
1740     mixin(genEnum);
1741     static assert(EnumMembers!TLAs[0] == TLAs._0000);
1742     static assert(EnumMembers!TLAs[$ - 1] == TLAs._2999);
1743 }
1744 
1745 /++
1746     Whether the type $(D From) is implicitly convertible to the type $(D To).
1747 
1748     Note that template constraints should be very careful about when they test
1749     for implicit conversions and in general should prefer to either test for an
1750     exact set of types or for types which compile with a particular piece of
1751     code rather than being designed to accept any type which implicitly converts
1752     to a particular type.
1753 
1754     This is because having a type pass a template constraint based on an
1755     implicit conversion but then not have the implicit conversion actually take
1756     place (which it won't unless the template does something to force it
1757     internally) can lead to either compilation errors or subtle behavioral
1758     differences - and even when the conversion is done explicitly within a
1759     templated function, since it's not done at the call site, it can still lead
1760     to subtle bugs in some cases (e.g. if slicing a static array is involved).
1761 
1762     For situations where code needs to verify that a type is implicitly
1763     convertible based solely on its qualifiers, $(LREF isQualifierConvertible)
1764     would be a more appropriate choice than isImplicitlyConvertible.
1765 
1766     Given how trivial the $(D is) expression for isImplicitlyConvertible is -
1767     $(D is(To : From)) - this trait is provided primarily so that it can be
1768     used in conjunction with templates that use a template predicate (such as
1769     many of the templates in phobos.sys.meta).
1770 
1771     The single-argument overload makes it so that it can be partially
1772     instantiated with the first argument, which will often be necessary with
1773     template predicates.
1774 
1775     See_Also:
1776         $(DDSUBLINK dlang.org/spec/type, implicit-conversions, Spec on implicit conversions)
1777         $(DDSUBLINK spec/const3, implicit_qualifier_conversions, Spec for implicit qualifier conversions)
1778         $(LREF isQualifierConvertible)
1779   +/
1780 enum isImplicitlyConvertible(From, To) = is(From : To);
1781 
1782 /++ Ditto +/
1783 template isImplicitlyConvertible(From)
1784 {
1785     enum isImplicitlyConvertible(To) = is(From : To);
1786 }
1787 
1788 ///
1789 @safe unittest
1790 {
1791     static assert( isImplicitlyConvertible!(byte, long));
1792     static assert( isImplicitlyConvertible!(ushort, long));
1793     static assert( isImplicitlyConvertible!(int, long));
1794     static assert( isImplicitlyConvertible!(long, long));
1795     static assert( isImplicitlyConvertible!(ulong, long));
1796 
1797     static assert( isImplicitlyConvertible!(ubyte, int));
1798     static assert( isImplicitlyConvertible!(short, int));
1799     static assert( isImplicitlyConvertible!(int, int));
1800     static assert( isImplicitlyConvertible!(uint, int));
1801     static assert(!isImplicitlyConvertible!(long, int));
1802     static assert(!isImplicitlyConvertible!(ulong, int));
1803 
1804     static assert(!isImplicitlyConvertible!(int, string));
1805     static assert(!isImplicitlyConvertible!(int, int[]));
1806     static assert(!isImplicitlyConvertible!(int, int*));
1807 
1808     static assert(!isImplicitlyConvertible!(string, int));
1809     static assert(!isImplicitlyConvertible!(int[], int));
1810     static assert(!isImplicitlyConvertible!(int*, int));
1811 
1812     // For better or worse, bool and the built-in character types will
1813     // implicitly convert to integer or floating-point types if the target type
1814     // is large enough. Sometimes, this is desirable, whereas at other times,
1815     // it can have very surprising results, so it's one reason why code should
1816     // be very careful when testing for implicit conversions.
1817     static assert( isImplicitlyConvertible!(bool, int));
1818     static assert( isImplicitlyConvertible!(char, int));
1819     static assert( isImplicitlyConvertible!(wchar, int));
1820     static assert( isImplicitlyConvertible!(dchar, int));
1821 
1822     static assert( isImplicitlyConvertible!(bool, ubyte));
1823     static assert( isImplicitlyConvertible!(char, ubyte));
1824     static assert(!isImplicitlyConvertible!(wchar, ubyte));
1825     static assert(!isImplicitlyConvertible!(dchar, ubyte));
1826 
1827     static assert( isImplicitlyConvertible!(bool, double));
1828     static assert( isImplicitlyConvertible!(char, double));
1829     static assert( isImplicitlyConvertible!(wchar, double));
1830     static assert( isImplicitlyConvertible!(dchar, double));
1831 
1832     // Value types can be implicitly converted regardless of their qualifiers
1833     // thanks to the fact that they're copied.
1834     static assert( isImplicitlyConvertible!(int, int));
1835     static assert( isImplicitlyConvertible!(const int, int));
1836     static assert( isImplicitlyConvertible!(immutable int, int));
1837     static assert( isImplicitlyConvertible!(inout int, int));
1838 
1839     static assert( isImplicitlyConvertible!(int, const int));
1840     static assert( isImplicitlyConvertible!(int, immutable int));
1841     static assert( isImplicitlyConvertible!(int, inout int));
1842 
1843     // Reference types are far more restrictive about which implicit conversions
1844     // they allow, because qualifiers in D are transitive.
1845     static assert( isImplicitlyConvertible!(int*, int*));
1846     static assert(!isImplicitlyConvertible!(const int*, int*));
1847     static assert(!isImplicitlyConvertible!(immutable int*, int*));
1848 
1849     static assert( isImplicitlyConvertible!(int*, const int*));
1850     static assert( isImplicitlyConvertible!(const int*, const int*));
1851     static assert( isImplicitlyConvertible!(immutable int*, const int*));
1852 
1853     static assert(!isImplicitlyConvertible!(int*, immutable int*));
1854     static assert(!isImplicitlyConvertible!(const int*, immutable int*));
1855     static assert( isImplicitlyConvertible!(immutable int*, immutable int*));
1856 
1857     // Note that inout gets a bit weird, since it's only used with function
1858     // parameters, and it's a stand-in for whatever mutability qualifiers the
1859     // type actually has. So, a function parameter that's inout accepts any
1860     // mutability, but you can't actually implicitly convert to inout, because
1861     // it's unknown within the function what the actual mutability of the type
1862     // is. It will differ depending on the function arguments of a specific
1863     // call to that function, so the same code has to work with all combinations
1864     // of mutability qualifiers.
1865     static assert(!isImplicitlyConvertible!(int*, inout int*));
1866     static assert(!isImplicitlyConvertible!(const int*, inout int*));
1867     static assert(!isImplicitlyConvertible!(immutable int*, inout int*));
1868     static assert( isImplicitlyConvertible!(inout int*, inout int*));
1869 
1870     static assert(!isImplicitlyConvertible!(inout int*, int*));
1871     static assert( isImplicitlyConvertible!(inout int*, const int*));
1872     static assert(!isImplicitlyConvertible!(inout int*, immutable int*));
1873 
1874     // Enums implicitly convert to their base type.
1875     enum E : int
1876     {
1877         a = 42
1878     }
1879     static assert( isImplicitlyConvertible!(E, int));
1880     static assert( isImplicitlyConvertible!(E, long));
1881     static assert(!isImplicitlyConvertible!(E, int[]));
1882 
1883     // Structs only implicit convert to another type via declaring an
1884     // alias this.
1885     static struct S
1886     {
1887         int i;
1888     }
1889     static assert(!isImplicitlyConvertible!(S, int));
1890     static assert(!isImplicitlyConvertible!(S, long));
1891     static assert(!isImplicitlyConvertible!(S, string));
1892 
1893     static struct AliasThis
1894     {
1895         int i;
1896         alias this = i;
1897     }
1898     static assert( isImplicitlyConvertible!(AliasThis, int));
1899     static assert( isImplicitlyConvertible!(AliasThis, long));
1900     static assert(!isImplicitlyConvertible!(AliasThis, string));
1901 
1902     static struct AliasThis2
1903     {
1904         AliasThis at;
1905         alias this = at;
1906     }
1907     static assert( isImplicitlyConvertible!(AliasThis2, AliasThis));
1908     static assert( isImplicitlyConvertible!(AliasThis2, int));
1909     static assert( isImplicitlyConvertible!(AliasThis2, long));
1910     static assert(!isImplicitlyConvertible!(AliasThis2, string));
1911 
1912     static struct AliasThis3
1913     {
1914         AliasThis2 at;
1915         alias this = at;
1916     }
1917     static assert( isImplicitlyConvertible!(AliasThis3, AliasThis2));
1918     static assert( isImplicitlyConvertible!(AliasThis3, AliasThis));
1919     static assert( isImplicitlyConvertible!(AliasThis3, int));
1920     static assert( isImplicitlyConvertible!(AliasThis3, long));
1921     static assert(!isImplicitlyConvertible!(AliasThis3, string));
1922 
1923     // D does not support implicit conversions via construction.
1924     static struct Cons
1925     {
1926         this(int i)
1927         {
1928             this.i = i;
1929         }
1930 
1931         int i;
1932     }
1933     static assert(!isImplicitlyConvertible!(int, Cons));
1934 
1935     // Classes support implicit conversion based on their class and
1936     // interface hierarchies.
1937     static interface I1 {}
1938     static class Base : I1 {}
1939 
1940     static interface I2 {}
1941     static class Foo : Base, I2 {}
1942 
1943     static class Bar : Base {}
1944 
1945     static assert( isImplicitlyConvertible!(Base, Base));
1946     static assert(!isImplicitlyConvertible!(Base, Foo));
1947     static assert(!isImplicitlyConvertible!(Base, Bar));
1948     static assert( isImplicitlyConvertible!(Base, I1));
1949     static assert(!isImplicitlyConvertible!(Base, I2));
1950 
1951     static assert( isImplicitlyConvertible!(Foo, Base));
1952     static assert( isImplicitlyConvertible!(Foo, Foo));
1953     static assert(!isImplicitlyConvertible!(Foo, Bar));
1954     static assert( isImplicitlyConvertible!(Foo, I1));
1955     static assert( isImplicitlyConvertible!(Foo, I2));
1956 
1957     static assert( isImplicitlyConvertible!(Bar, Base));
1958     static assert(!isImplicitlyConvertible!(Bar, Foo));
1959     static assert( isImplicitlyConvertible!(Bar, Bar));
1960     static assert( isImplicitlyConvertible!(Bar, I1));
1961     static assert(!isImplicitlyConvertible!(Bar, I2));
1962 
1963     static assert(!isImplicitlyConvertible!(I1, Base));
1964     static assert(!isImplicitlyConvertible!(I1, Foo));
1965     static assert(!isImplicitlyConvertible!(I1, Bar));
1966     static assert( isImplicitlyConvertible!(I1, I1));
1967     static assert(!isImplicitlyConvertible!(I1, I2));
1968 
1969     static assert(!isImplicitlyConvertible!(I2, Base));
1970     static assert(!isImplicitlyConvertible!(I2, Foo));
1971     static assert(!isImplicitlyConvertible!(I2, Bar));
1972     static assert(!isImplicitlyConvertible!(I2, I1));
1973     static assert( isImplicitlyConvertible!(I2, I2));
1974 
1975     // Note that arrays are not implicitly convertible even when their elements
1976     // are implicitly convertible.
1977     static assert(!isImplicitlyConvertible!(ubyte[], uint[]));
1978     static assert(!isImplicitlyConvertible!(Foo[], Base[]));
1979     static assert(!isImplicitlyConvertible!(Bar[], Base[]));
1980 
1981     // However, like with pointers, dynamic arrays are convertible based on
1982     // constness.
1983     static assert( isImplicitlyConvertible!(Base[], const Base[]));
1984     static assert( isImplicitlyConvertible!(Base[], const(Base)[]));
1985     static assert(!isImplicitlyConvertible!(Base[], immutable(Base)[]));
1986     static assert(!isImplicitlyConvertible!(const Base[], immutable Base[]));
1987     static assert( isImplicitlyConvertible!(const Base[], const Base[]));
1988     static assert(!isImplicitlyConvertible!(const Base[], immutable Base[]));
1989 }
1990 
1991 /++
1992     isImplicitlyConvertible can be used with partial instantiation so that it
1993     can be passed to a template which takes a unary predicate.
1994   +/
1995 @safe unittest
1996 {
1997     import phobos.sys.meta : AliasSeq, all, indexOf;
1998 
1999     // byte is implicitly convertible to byte, short, int, and long.
2000     static assert(all!(isImplicitlyConvertible!byte, short, int, long));
2001 
2002     // const(char)[] at index 2 is the first type in the AliasSeq which string
2003     // can be implicitly converted to.
2004     alias Types = AliasSeq!(int, char[], const(char)[], string, int*);
2005     static assert(indexOf!(isImplicitlyConvertible!string, Types) == 2);
2006 }
2007 
2008 /++
2009     Whether $(D From) is
2010     $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible)
2011     to $(D To).
2012 
2013     This is testing whether $(D From) and $(D To) are the same type - minus the
2014     qualifiers - and whether the qualifiers on $(D From) can be implicitly
2015     converted to the qualifiers on $(D To). No other implicit conversions are
2016     taken into account.
2017 
2018     For instance, $(D const int*) is not implicitly convertible to $(D int*),
2019     because that would violate $(D const). That means that $(D const) is not
2020     qualifier convertible to mutable. And as such, $(I any) $(D const) type
2021     is not qualifier convertible to a mutable type even if it's implicitly
2022     convertible. E.G. $(D const int) is implicitly convertible to $(D int),
2023     because it can be copied to avoid violating $(D const), but it's still not
2024     qualifier convertible, because $(D const) types in general cannot be
2025     implicitly converted to mutable.
2026 
2027     The exact types being tested matter, because they need to be the same
2028     (minus the qualifiers) in order to be considered convertible, but beyond
2029     that, all that matters for the conversion is whether those qualifers would
2030     be convertible regardless of which types they were on. So, if you're having
2031     trouble picturing whether $(D From) would be qualifier convertible to
2032     $(D To), then consider which conversions would be allowed from $(D From[])
2033     to $(D To[]) (and remember that dynamic arrays are only implicitly
2034     convertible based on their qualifers).
2035 
2036     The $(DDSUBLINK spec/const3, implicit_qualifier_conversions, spec) provides
2037     a table of which qualifiers can be implcitly converted to which other
2038     qualifers (and of course, there a bunch of examples below).
2039 
2040     So, isQualifierConvertible can be used in a case like
2041     $(D isQualifierConvertible!(ReturnType!(typeof(foo(bar))), const char),
2042     which would be testing that the return type of $(D foo(bar)) was $(D char),
2043     $(D const char), or $(D immutable char) (since those are the only types
2044     which are qualifier convertible to $(D const char)).
2045 
2046     This is in contrast to
2047     $(D isImplicitlyConvertible!(ReturnType!(typeof(foo(bar))), const char),
2048     which would be $(D true) for $(I any) type which was implicitly convertible
2049     to $(D const char) rather than just $(D char), $(D const char), and
2050     $(D immutable char).
2051 
2052     The single-argument overload makes it so that it can be partially
2053     instantiated with the first argument, which will often be necessary with
2054     template predicates.
2055 
2056     See_Also:
2057         $(DDSUBLINK spec/const3, implicit_qualifier_conversions, Spec for implicit qualifier conversions)
2058         $(LREF isImplicitlyConvertible)
2059   +/
2060 enum isQualifierConvertible(From, To) = is(immutable From == immutable To) && is(From* : To*);
2061 
2062 /++ Ditto +/
2063 template isQualifierConvertible(From)
2064 {
2065     enum isQualifierConvertible(To) =  is(immutable From == immutable To) && is(From* : To*);
2066 }
2067 
2068 ///
2069 @safe unittest
2070 {
2071     // i.e. char* -> const char*
2072     static assert( isQualifierConvertible!(char, const char));
2073 
2074     // i.e. const char* -> char*
2075     static assert(!isQualifierConvertible!(const char, char));
2076 
2077     static assert( isQualifierConvertible!(int, int));
2078     static assert( isQualifierConvertible!(int, const int));
2079     static assert(!isQualifierConvertible!(int, immutable int));
2080 
2081     static assert(!isQualifierConvertible!(const int, int));
2082     static assert( isQualifierConvertible!(const int, const int));
2083     static assert(!isQualifierConvertible!(const int, immutable int));
2084 
2085     static assert(!isQualifierConvertible!(immutable int, int));
2086     static assert( isQualifierConvertible!(immutable int, const int));
2087     static assert( isQualifierConvertible!(immutable int, immutable int));
2088 
2089     // Note that inout gets a bit weird, since it's only used with function
2090     // parameters, and it's a stand-in for whatever mutability qualifiers the
2091     // type actually has. So, a function parameter that's inout accepts any
2092     // mutability, but you can't actually implicitly convert to inout, because
2093     // it's unknown within the function what the actual mutability of the type
2094     // is. It will differ depending on the function arguments of a specific
2095     // call to that function, so the same code has to work with all combinations
2096     // of mutability qualifiers.
2097     static assert(!isQualifierConvertible!(int, inout int));
2098     static assert(!isQualifierConvertible!(const int, inout int));
2099     static assert(!isQualifierConvertible!(immutable int, inout int));
2100     static assert( isQualifierConvertible!(inout int, inout int));
2101 
2102     static assert(!isQualifierConvertible!(inout int, int));
2103     static assert( isQualifierConvertible!(inout int, const int));
2104     static assert(!isQualifierConvertible!(inout int, immutable int));
2105 
2106     // shared is of course also a qualifier.
2107     static assert(!isQualifierConvertible!(int, shared int));
2108     static assert(!isQualifierConvertible!(int, const shared int));
2109     static assert(!isQualifierConvertible!(const int, shared int));
2110     static assert(!isQualifierConvertible!(const int, const shared int));
2111     static assert(!isQualifierConvertible!(immutable int, shared int));
2112     static assert( isQualifierConvertible!(immutable int, const shared int));
2113 
2114     static assert(!isQualifierConvertible!(shared int, int));
2115     static assert(!isQualifierConvertible!(shared int, const int));
2116     static assert(!isQualifierConvertible!(shared int, immutable int));
2117     static assert( isQualifierConvertible!(shared int, shared int));
2118     static assert( isQualifierConvertible!(shared int, const shared int));
2119 
2120     static assert(!isQualifierConvertible!(const shared int, int));
2121     static assert(!isQualifierConvertible!(const shared int, const int));
2122     static assert(!isQualifierConvertible!(const shared int, immutable int));
2123     static assert(!isQualifierConvertible!(const shared int, shared int));
2124     static assert( isQualifierConvertible!(const shared int, const shared int));
2125 
2126     // Implicit conversions don't count unless they're based purely on
2127     // qualifiers.
2128     enum E : int
2129     {
2130         a = 1
2131     }
2132 
2133     static assert(!isQualifierConvertible!(E, int));
2134     static assert(!isQualifierConvertible!(E, const int));
2135     static assert( isQualifierConvertible!(E, E));
2136     static assert( isQualifierConvertible!(E, const E));
2137     static assert(!isQualifierConvertible!(E, immutable E));
2138 
2139     static struct AliasThis
2140     {
2141         int i;
2142         alias this = i;
2143     }
2144 
2145     static assert(!isQualifierConvertible!(AliasThis, int));
2146     static assert(!isQualifierConvertible!(AliasThis, const int));
2147     static assert( isQualifierConvertible!(AliasThis, AliasThis));
2148     static assert( isQualifierConvertible!(AliasThis, const AliasThis));
2149     static assert(!isQualifierConvertible!(AliasThis, immutable AliasThis));
2150 
2151     // The qualifiers are irrelevant if the types aren't the same when
2152     // stripped of all qualifers.
2153     static assert(!isQualifierConvertible!(int, long));
2154     static assert(!isQualifierConvertible!(int, const long));
2155     static assert(!isQualifierConvertible!(string, const(ubyte)[]));
2156 }
2157 
2158 /++
2159     isQualifierConvertible can be used with partial instantiation so that it
2160     can be passed to a template which takes a unary predicate.
2161   +/
2162 @safe unittest
2163 {
2164     import phobos.sys.meta : AliasSeq, all, indexOf;
2165 
2166     // byte is qualifier convertible to byte and const byte.
2167     static assert(all!(isQualifierConvertible!byte, byte, const byte));
2168 
2169     // const(char[]) at index 2 is the first type in the AliasSeq which string
2170     // is qualifier convertible to.
2171     alias Types = AliasSeq!(int, char[], const(char[]), string, int*);
2172     static assert(indexOf!(isQualifierConvertible!string, Types) == 2);
2173 }
2174 
2175 @safe unittest
2176 {
2177     import phobos.sys.meta : AliasSeq;
2178 
2179     alias Types = AliasSeq!(int, const int, shared int, inout int, const shared int,
2180                             const inout int, inout shared int, const inout shared int, immutable int);
2181 
2182     // https://dlang.org/spec/const3.html#implicit_qualifier_conversions
2183     enum _ = 0;
2184     static immutable bool[Types.length][Types.length] conversions = [
2185     //   m   c   s   i   cs  ci  is  cis im
2186         [1,  1,  _,  _,  _,  _,  _,  _,  _],  // mutable
2187         [_,  1,  _,  _,  _,  _,  _,  _,  _],  // const
2188         [_,  _,  1,  _,  1,  _,  _,  _,  _],  // shared
2189         [_,  1,  _,  1,  _,  1,  _,  _,  _],  // inout
2190         [_,  _,  _,  _,  1,  _,  _,  _,  _],  // const shared
2191         [_,  1,  _,  _,  _,  1,  _,  _,  _],  // const inout
2192         [_,  _,  _,  _,  1,  _,  1,  1,  _],  // inout shared
2193         [_,  _,  _,  _,  1,  _,  _,  1,  _],  // const inout shared
2194         [_,  1,  _,  _,  1,  1,  _,  1,  1],  // immutable
2195     ];
2196 
2197     foreach (i, From; Types)
2198     {
2199         foreach (j, To; Types)
2200         {
2201             static assert(isQualifierConvertible!(From, To) == conversions[i][j],
2202                           "`isQualifierConvertible!(" ~ From.stringof ~ ", " ~ To.stringof ~ ")`" ~
2203                           " should be `" ~ (conversions[i][j] ? "true`" : "false`"));
2204         }
2205     }
2206 }
2207 
2208 /++
2209     Whether the given values are equal per $(D ==).
2210 
2211     All this does is $(D lhs == rhs) but in an eponymous template, so most code
2212     shouldn't use it. It's intended to be used in conjunction with templates
2213     that take a template predicate - such as those in phobos.sys.meta.
2214 
2215     The single-argument overload makes it so that it can be partially
2216     instantiated with the first argument, which will often be necessary with
2217     template predicates.
2218 
2219     Note that in most cases, even when comparing values at compile time, using
2220     isEqual makes no sense, because you can use CTFE to just compare two values
2221     (or expressions which evaluate to values), but in rare cases where you need
2222     to compare symbols in an $(D AliasSeq) by value with a template predicate
2223     while still leaving them as symbols in an $(D AliasSeq), then isEqual would
2224     be needed.
2225 
2226     A prime example of this would be $(D Unique!(isEqual, EnumMembers!MyEnum)),
2227     which results in an $(D AliasSeq) containing the list of members of
2228     $(D MyEnum) but without any duplicate values (e.g. to use when doing code
2229     generation to create a final switch).
2230 
2231     Alternatively, code such as $(D [EnumMembers!MyEnum].sort().unique()) could
2232     be used to get a dynamic array of the enum members with no duplicate values
2233     via CTFE, thus avoiding the need for template predicates or anything from
2234     phobos.sys.meta. However, you then have a dynamic array of enum values
2235     rather than an $(D AliasSeq) of symbols for those enum members, which
2236     affects what you can do with type introspection. So, which approach is
2237     better depends on what the code needs to do with the enum members.
2238 
2239     In general, however, if code doesn't need an $(D AliasSeq), and an array of
2240     values will do the trick, then it's more efficient to operate on an array of
2241     values with CTFE and avoid using isEqual or other templates to operate on
2242     the values as an $(D AliasSeq).
2243 
2244     See_Also:
2245         $(LREF isSameSymbol)
2246         $(LREF isSameType)
2247   +/
2248 enum isEqual(alias lhs, alias rhs) = lhs == rhs;
2249 
2250 /++ Ditto +/
2251 template isEqual(alias lhs)
2252 {
2253     enum isEqual(alias rhs) = lhs == rhs;
2254 }
2255 
2256 /// It acts just like ==, but it's a template.
2257 @safe unittest
2258 {
2259     enum a = 42;
2260 
2261     static assert( isEqual!(a, 42));
2262     static assert( isEqual!(20, 10 + 10));
2263 
2264     static assert(!isEqual!(a, 120));
2265     static assert(!isEqual!(77, 19 * 7 + 2));
2266 
2267     // b cannot be read at compile time, so it won't work with isEqual.
2268     int b = 99;
2269     static assert(!__traits(compiles, isEqual!(b, 99)));
2270 }
2271 
2272 /++
2273     Comparing some of the differences between an $(D AliasSeq) of enum members
2274     and an array of enum values created from an $(D AliasSeq) of enum members.
2275   +/
2276 @safe unittest
2277 {
2278     import phobos.sys.meta : AliasSeq, Unique;
2279 
2280     enum E
2281     {
2282         a = 0,
2283         b = 22,
2284         c = 33,
2285         d = 0,
2286         e = 256,
2287         f = 33,
2288         g = 7
2289     }
2290 
2291     alias uniqueMembers = Unique!(isEqual, EnumMembers!E);
2292     static assert(uniqueMembers.length == 5);
2293 
2294     static assert(__traits(isSame, uniqueMembers[0], E.a));
2295     static assert(__traits(isSame, uniqueMembers[1], E.b));
2296     static assert(__traits(isSame, uniqueMembers[2], E.c));
2297     static assert(__traits(isSame, uniqueMembers[3], E.e));
2298     static assert(__traits(isSame, uniqueMembers[4], E.g));
2299 
2300     static assert(__traits(identifier, uniqueMembers[0]) == "a");
2301     static assert(__traits(identifier, uniqueMembers[1]) == "b");
2302     static assert(__traits(identifier, uniqueMembers[2]) == "c");
2303     static assert(__traits(identifier, uniqueMembers[3]) == "e");
2304     static assert(__traits(identifier, uniqueMembers[4]) == "g");
2305 
2306     // Same value but different symbol.
2307     static assert(uniqueMembers[0] == E.d);
2308     static assert(!__traits(isSame, uniqueMembers[0], E.d));
2309 
2310     // is expressions compare types, not symbols or values, and these AliasSeqs
2311     // contain the list of symbols for the enum members, not types, so the is
2312     // expression evaluates to false even though the symbols are the same.
2313     static assert(!is(uniqueMembers == AliasSeq!(E.a, E.b, E.c, E.e, E.g)));
2314 
2315     // Once the members are converted to an array, the types are the same, and
2316     // the values are the same, but the symbols are not the same. Instead of
2317     // being the symbols E.a, E.b, etc., they're just values with the type E
2318     // which match the values of E.a, E.b, etc.
2319     enum arr = [uniqueMembers];
2320     static assert(is(typeof(arr) == E[]));
2321 
2322     static assert(arr == [E.a, E.b, E.c, E.e, E.g]);
2323     static assert(arr == [E.d, E.b, E.f, E.e, E.g]);
2324 
2325     static assert(!__traits(isSame, arr[0], E.a));
2326     static assert(!__traits(isSame, arr[1], E.b));
2327     static assert(!__traits(isSame, arr[2], E.c));
2328     static assert(!__traits(isSame, arr[3], E.e));
2329     static assert(!__traits(isSame, arr[4], E.g));
2330 
2331     // Since arr[0] is just a value of type E, it's no longer the symbol, E.a,
2332     // even though its type is E, and its value is the same as that of E.a. And
2333     // unlike the actual members of an enum, an element of an array does not
2334     // have an identifier, so __traits(identifier, ...) doesn't work with it.
2335     static assert(!__traits(compiles, __traits(identifier, arr[0])));
2336 
2337     // Similarly, once an enum member from the AliasSeq is assigned to a
2338     // variable, __traits(identifer, ...) operates on the variable, not the
2339     // symbol from the AliasSeq or the value of the variable.
2340     auto var = uniqueMembers[0];
2341     static assert(__traits(identifier, var) == "var");
2342 
2343     // The same with a manifest constant.
2344     enum constant = uniqueMembers[0];
2345     static assert(__traits(identifier, constant) == "constant");
2346 }
2347 
2348 /++
2349     Whether the given symbols are the same symbol.
2350 
2351     All this does is $(D __traits(isSame, lhs, rhs)), so most code shouldn't
2352     use it. It's intended to be used in conjunction with templates that take a
2353     template predicate - such as those in phobos.sys.meta.
2354 
2355     The single-argument overload makes it so that it can be partially
2356     instantiated with the first argument, which will often be necessary with
2357     template predicates.
2358 
2359     See_Also:
2360         $(DDSUBLINK spec/traits, isSame, $(D __traits(isSame, lhs, rhs)))
2361         $(LREF isEqual)
2362         $(LREF isSameType)
2363   +/
2364 enum isSameSymbol(alias lhs, alias rhs) = __traits(isSame, lhs, rhs);
2365 
2366 /++ Ditto +/
2367 template isSameSymbol(alias lhs)
2368 {
2369     enum isSameSymbol(alias rhs) = __traits(isSame, lhs, rhs);
2370 }
2371 
2372 ///
2373 @safe unittest
2374 {
2375     int i;
2376     int j;
2377     real r;
2378 
2379     static assert( isSameSymbol!(i, i));
2380     static assert(!isSameSymbol!(i, j));
2381     static assert(!isSameSymbol!(i, r));
2382 
2383     static assert(!isSameSymbol!(j, i));
2384     static assert( isSameSymbol!(j, j));
2385     static assert(!isSameSymbol!(j, r));
2386 
2387     static assert(!isSameSymbol!(r, i));
2388     static assert(!isSameSymbol!(r, j));
2389     static assert( isSameSymbol!(r, r));
2390 
2391     auto foo() { return 0; }
2392     auto bar() { return 0; }
2393 
2394     static assert( isSameSymbol!(foo, foo));
2395     static assert(!isSameSymbol!(foo, bar));
2396     static assert(!isSameSymbol!(foo, i));
2397 
2398     static assert(!isSameSymbol!(bar, foo));
2399     static assert( isSameSymbol!(bar, bar));
2400     static assert(!isSameSymbol!(bar, i));
2401 
2402     // Types are symbols too. However, in most cases, they should be compared
2403     // as types, not symbols (be it with is expressions or with isSameType),
2404     // because the results aren't consistent between scalar types and
2405     // user-defined types with regards to type qualifiers when they're compared
2406     // as symbols.
2407     static assert( isSameSymbol!(double, double));
2408     static assert(!isSameSymbol!(double, const double));
2409     static assert(!isSameSymbol!(double, int));
2410     static assert( isSameSymbol!(Object, Object));
2411     static assert( isSameSymbol!(Object, const Object));
2412 
2413     static assert(!isSameSymbol!(i, int));
2414     static assert( isSameSymbol!(typeof(i), int));
2415 
2416     // Lambdas can be compared with __traits(isSame, ...),
2417     // so they can be compared with isSameSymbol.
2418     static assert( isSameSymbol!(a => a + 42, a => a + 42));
2419     static assert(!isSameSymbol!(a => a + 42, a => a + 99));
2420 
2421     // Partial instantiation allows it to be used with templates that expect
2422     // a predicate that takes only a single argument.
2423     import phobos.sys.meta : AliasSeq, indexOf;
2424     alias Types = AliasSeq!(i, j, r, int, long, foo);
2425     static assert(indexOf!(isSameSymbol!j, Types) == 1);
2426     static assert(indexOf!(isSameSymbol!int, Types) == 3);
2427     static assert(indexOf!(isSameSymbol!bar, Types) == -1);
2428 }
2429 
2430 /++
2431     Whether the given types are the same type.
2432 
2433     All this does is $(D is(T == U)), so most code shouldn't use it. It's
2434     intended to be used in conjunction with templates that take a template
2435     predicate - such as those in phobos.sys.meta.
2436 
2437     The single-argument overload makes it so that it can be partially
2438     instantiated with the first argument, which will often be necessary with
2439     template predicates.
2440 
2441     See_Also:
2442         $(LREF isEqual)
2443         $(LREF isSameSymbol)
2444   +/
2445 enum isSameType(T, U) = is(T == U);
2446 
2447 /++ Ditto +/
2448 template isSameType(T)
2449 {
2450     enum isSameType(U) = is(T == U);
2451 }
2452 
2453 ///
2454 @safe unittest
2455 {
2456     static assert( isSameType!(long, long));
2457     static assert(!isSameType!(long, const long));
2458     static assert(!isSameType!(long, string));
2459     static assert( isSameType!(string, string));
2460 
2461     int i;
2462     real r;
2463     static assert( isSameType!(int, typeof(i)));
2464     static assert(!isSameType!(int, typeof(r)));
2465 
2466     static assert(!isSameType!(real, typeof(i)));
2467     static assert( isSameType!(real, typeof(r)));
2468 
2469     // Partial instantiation allows it to be used with templates that expect
2470     // a predicate that takes only a single argument.
2471     import phobos.sys.meta : AliasSeq, indexOf;
2472     alias Types = AliasSeq!(float, string, int, double);
2473     static assert(indexOf!(isSameType!int, Types) == 2);
2474 }
2475 
2476 /++
2477     Evaluates to an $(D AliasSeq) of the names (as $(D string)s) of the member
2478     variables of an aggregate type (i.e. a struct, class, interface, or union).
2479 
2480     These are fields which take up memory space within an instance of the type
2481     (i.e. not enums / manifest constants, since they don't take up memory
2482     space, and not static member variables, since they don't take up memory
2483     space within an instance).
2484 
2485     Hidden fields (like the virtual function table pointer or the context
2486     pointer for nested types) are not included.
2487 
2488     For classes, only the direct member variables are included and not those
2489     of any base classes.
2490 
2491     For interfaces, the result of FieldNames is always empty, because
2492     interfaces cannot have member variables. However, because interfaces are
2493     aggregate types, they work with FieldNames for consistency so that code
2494     that's written to work on aggregate types doesn't have to worry about
2495     whether it's dealing with an interface.
2496 
2497     See_Also:
2498         $(LREF FieldSymbols)
2499         $(LREF FieldTypes)
2500         $(DDSUBLINK spec/struct.html, struct_instance_properties, $(D tupleof))
2501   +/
2502 template FieldNames(T)
2503 if (isAggregateType!T)
2504 {
2505     import phobos.sys.meta : AliasSeq;
2506 
2507     static if (is(T == struct) && __traits(isNested, T))
2508         private alias Fields = AliasSeq!(T.tupleof[0 .. $ - 1]);
2509     else
2510         private alias Fields = T.tupleof;
2511 
2512     alias FieldNames = AliasSeq!();
2513     static foreach (Field; Fields)
2514         FieldNames = AliasSeq!(FieldNames, Field.stringof);
2515 }
2516 
2517 ///
2518 @safe unittest
2519 {
2520     import phobos.sys.meta : AliasSeq;
2521 
2522     struct S
2523     {
2524         int x;
2525         float y;
2526     }
2527     static assert(FieldNames!S == AliasSeq!("x", "y"));
2528 
2529     // Since the AliasSeq contains values, all of which are of the same type,
2530     // it can be used to create a dynamic array, which would be more
2531     // efficient than operating on an AliasSeq in the cases where an
2532     // AliasSeq is not necessary.
2533     static assert([FieldNames!S] == ["x", "y"]);
2534 
2535     class C
2536     {
2537         // static variables are not included.
2538         static int var;
2539 
2540         // Manifest constants are not included.
2541         enum lang = "dlang";
2542 
2543         // Functions are not included, even if they're @property functions.
2544         @property int foo() { return 42; }
2545 
2546         string s;
2547         int i;
2548         int[] arr;
2549     }
2550     static assert(FieldNames!C == AliasSeq!("s", "i", "arr"));
2551 
2552     static assert([FieldNames!C] == ["s", "i", "arr"]);
2553 
2554     // Only direct member variables are included. Member variables from any base
2555     // classes are not.
2556     class D : C
2557     {
2558         real r;
2559     }
2560     static assert(FieldNames!D == AliasSeq!"r");
2561 
2562     static assert([FieldNames!D] == ["r"]);
2563 
2564     // FieldNames will always be empty for an interface, since it's not legal
2565     // for interfaces to have member variables.
2566     interface I
2567     {
2568     }
2569     static assert(FieldNames!I.length == 0);
2570 
2571     union U
2572     {
2573         int i;
2574         double d;
2575         long l;
2576         S s;
2577     }
2578     static assert(FieldNames!U == AliasSeq!("i", "d", "l", "s"));
2579 
2580     static assert([FieldNames!U] == ["i", "d", "l", "s"]);;
2581 
2582     // FieldNames only operates on aggregate types.
2583     static assert(!__traits(compiles, FieldNames!int));
2584     static assert(!__traits(compiles, FieldNames!(S*)));
2585     static assert(!__traits(compiles, FieldNames!(C[])));
2586 }
2587 
2588 @safe unittest
2589 {
2590     import phobos.sys.meta : AliasSeq;
2591 
2592     {
2593         static struct S0 {}
2594         static assert(FieldNames!S0.length == 0);
2595 
2596         static struct S1 { int a; }
2597         static assert(FieldNames!S1 == AliasSeq!"a");
2598 
2599         static struct S2 { int a; string b; }
2600         static assert(FieldNames!S2 == AliasSeq!("a", "b"));
2601 
2602         static struct S3 { int a; string b; real c; }
2603         static assert(FieldNames!S3 == AliasSeq!("a", "b", "c"));
2604     }
2605     {
2606         int i;
2607         struct S0 { void foo() { i = 0; }}
2608         static assert(FieldNames!S0.length == 0);
2609         static assert(__traits(isNested, S0));
2610 
2611         struct S1 { int a; void foo() { i = 0; } }
2612         static assert(FieldNames!S1 == AliasSeq!"a");
2613         static assert(__traits(isNested, S1));
2614 
2615         struct S2 { int a; string b; void foo() { i = 0; } }
2616         static assert(FieldNames!S2 == AliasSeq!("a", "b"));
2617         static assert(__traits(isNested, S2));
2618 
2619         struct S3 { int a; string b; real c; void foo() { i = 0; } }
2620         static assert(FieldNames!S3 == AliasSeq!("a", "b", "c"));
2621         static assert(__traits(isNested, S3));
2622     }
2623     {
2624         static class C0 {}
2625         static assert(FieldNames!C0.length == 0);
2626 
2627         static class C1 { int a; }
2628         static assert(FieldNames!C1 == AliasSeq!"a");
2629 
2630         static class C2 { int a; string b; }
2631         static assert(FieldNames!C2 == AliasSeq!("a", "b"));
2632 
2633         static class C3 { int a; string b; real c; }
2634         static assert(FieldNames!C3 == AliasSeq!("a", "b", "c"));
2635 
2636         static class D0 : C3 {}
2637         static assert(FieldNames!D0.length == 0);
2638 
2639         static class D1 : C3 { bool x; }
2640         static assert(FieldNames!D1 == AliasSeq!"x");
2641 
2642         static class D2 : C3 { bool x; int* y; }
2643         static assert(FieldNames!D2 == AliasSeq!("x", "y"));
2644 
2645         static class D3 : C3 { bool x; int* y; short[] z; }
2646         static assert(FieldNames!D3 == AliasSeq!("x", "y", "z"));
2647     }
2648     {
2649         int i;
2650         class C0 { void foo() { i = 0; }}
2651         static assert(FieldNames!C0.length == 0);
2652         static assert(__traits(isNested, C0));
2653 
2654         class C1 { int a; void foo() { i = 0; } }
2655         static assert(FieldNames!C1 == AliasSeq!"a");
2656         static assert(__traits(isNested, C1));
2657 
2658         class C2 { int a; string b; void foo() { i = 0; } }
2659         static assert(FieldNames!C2 == AliasSeq!("a", "b"));
2660         static assert(__traits(isNested, C2));
2661 
2662         class C3 { int a; string b; real c; void foo() { i = 0; } }
2663         static assert(FieldNames!C3 == AliasSeq!("a", "b", "c"));
2664         static assert(__traits(isNested, C3));
2665 
2666         class D0 : C3 {}
2667         static assert(FieldNames!D0.length == 0);
2668         static assert(__traits(isNested, D0));
2669 
2670         class D1 : C3 { bool x; }
2671         static assert(FieldNames!D1 == AliasSeq!"x");
2672         static assert(__traits(isNested, D1));
2673 
2674         class D2 : C3 { bool x; int* y; }
2675         static assert(FieldNames!D2 == AliasSeq!("x", "y"));
2676         static assert(__traits(isNested, D2));
2677 
2678         class D3 : C3 { bool x; int* y; short[] z; }
2679         static assert(FieldNames!D3 == AliasSeq!("x", "y", "z"));
2680         static assert(__traits(isNested, D3));
2681     }
2682     {
2683         static union U0 {}
2684         static assert(FieldNames!U0.length == 0);
2685 
2686         static union U1 { int a; }
2687         static assert(FieldNames!U1 == AliasSeq!"a");
2688 
2689         static union U2 { int a; string b; }
2690         static assert(FieldNames!U2 == AliasSeq!("a", "b"));
2691 
2692         static union U3 { int a; string b; real c; }
2693         static assert(FieldNames!U3 == AliasSeq!("a", "b", "c"));
2694     }
2695     {
2696         static struct S
2697         {
2698             enum e = 42;
2699             static str = "foobar";
2700 
2701             string name() { return "foo"; }
2702 
2703             int[] arr;
2704 
2705             struct Inner1 { int i; }
2706 
2707             static struct Inner2 { long gnol; }
2708 
2709             union { int a; string b; }
2710 
2711             alias Foo = Inner1;
2712         }
2713 
2714         static assert(FieldNames!S == AliasSeq!("arr", "a", "b"));
2715         static assert(FieldNames!(const S) == AliasSeq!("arr", "a", "b"));
2716         static assert(FieldNames!(S.Inner1) == AliasSeq!"i");
2717         static assert(FieldNames!(S.Inner2) == AliasSeq!"gnol");
2718     }
2719 }
2720 
2721 /++
2722     Evaluates to an $(D AliasSeq) of the symbols for the member variables of an
2723     aggregate type (i.e. a struct, class, interface, or union).
2724 
2725     These are fields which take up memory space within an instance of the type
2726     (i.e. not enums / manifest constants, since they don't take up memory
2727     space, and not static member variables, since they don't take up memory
2728     space within an instance).
2729 
2730     Hidden fields (like the virtual function table pointer or the context
2731     pointer for nested types) are not included.
2732 
2733     For classes, only the direct member variables are included and not those
2734     of any base classes.
2735 
2736     For interfaces, the result of FieldSymbols is always empty, because
2737     interfaces cannot have member variables. However, because interfaces are
2738     aggregate types, they work with FieldSymbols for consistency so that code
2739     that's written to work on aggregate types doesn't have to worry about
2740     whether it's dealing with an interface.
2741 
2742     In most cases, $(D FieldSymbols!T) has the same result as $(D T.tupleof).
2743     The difference is that for nested structs with a context pointer,
2744     $(D T.tupleof) includes the context pointer, whereas $(D FieldSymbols!T)
2745     does not. For non-nested structs, and for classes, interfaces, and unions,
2746     $(D FieldSymbols!T) and $(D T.tupleof) are the same.
2747 
2748     So, for most cases, $(D T.tupleof) is sufficient and avoids instantiating
2749     an additional template, but FieldSymbols is provided so that the code that
2750     needs to avoid including context pointers in the list of fields can do so
2751     without the programmer having to figure how to do that correctly. It also
2752     provides a template that's equivalent to what $(LREF FieldNames) and
2753     $(LREF FieldTypes) do in terms of which fields it gives (the difference of
2754     course then being whether you get the symbols, names, or types for the
2755     fields), whereas the behavior for $(D tupleof) is subtly different.
2756 
2757     See_Also:
2758         $(LREF FieldNames)
2759         $(LREF FieldTypes)
2760         $(DDSUBLINK spec/struct.html, struct_instance_properties, $(D tupleof))
2761         $(DDSUBLINK spec/traits, isNested, $(D __traits(isNested, ...))).
2762         $(DDSUBLINK spec/traits, isSame, $(D __traits(isSame, ...))).
2763   +/
2764 template FieldSymbols(T)
2765 if (isAggregateType!T)
2766 {
2767     static if (is(T == struct) && __traits(isNested, T))
2768     {
2769         import phobos.sys.meta : AliasSeq;
2770         alias FieldSymbols = AliasSeq!(T.tupleof[0 .. $ - 1]);
2771     }
2772     else
2773         alias FieldSymbols = T.tupleof;
2774 }
2775 
2776 ///
2777 @safe unittest
2778 {
2779     import phobos.sys.meta : AliasSeq;
2780 
2781     struct S
2782     {
2783         int x;
2784         float y;
2785     }
2786     static assert(__traits(isSame, FieldSymbols!S, AliasSeq!(S.x, S.y)));
2787 
2788     // FieldSymbols!S and S.tupleof are the same, because S is not nested.
2789     static assert(__traits(isSame, FieldSymbols!S, S.tupleof));
2790 
2791     // Note that type qualifiers _should_ be passed on to the result, but due
2792     // to https://issues.dlang.org/show_bug.cgi?id=24516, they aren't.
2793     // FieldTypes does not have this problem, because it aliases the types
2794     // rather than the symbols, so if you need the types from the symbols, you
2795     // should use either FieldTypes or tupleof until the compiler bug has been
2796     // fixed (and if you use tupleof, you need to avoid aliasing the result
2797     // before getting the types from it).
2798     static assert(is(typeof(FieldSymbols!S[0]) == int));
2799 
2800     // These currently fail when they shouldn't:
2801     //static assert(is(typeof(FieldSymbols!(const S)[0]) == const int));
2802     //static assert(is(typeof(FieldSymbols!(shared S)[0]) == shared int));
2803 
2804     class C
2805     {
2806         // static variables are not included.
2807         static int var;
2808 
2809         // Manifest constants are not included.
2810         enum lang = "dlang";
2811 
2812         // Functions are not included, even if they're @property functions.
2813         @property int foo() { return 42; }
2814 
2815         string s;
2816         int i;
2817         int[] arr;
2818     }
2819     static assert(__traits(isSame, FieldSymbols!C, AliasSeq!(C.s, C.i, C.arr)));
2820 
2821     // FieldSymbols!C and C.tupleof have the same symbols, because they are
2822     // always the same for classes.
2823     static assert(__traits(isSame, FieldSymbols!C, C.tupleof));
2824 
2825     // Only direct member variables are included. Member variables from any base
2826     // classes are not.
2827     class D : C
2828     {
2829         real r;
2830     }
2831     static assert(__traits(isSame, FieldSymbols!D, AliasSeq!(D.r)));
2832     static assert(__traits(isSame, FieldSymbols!D, D.tupleof));
2833 
2834     // FieldSymbols will always be empty for an interface, since it's not legal
2835     // for interfaces to have member variables.
2836     interface I
2837     {
2838     }
2839     static assert(FieldSymbols!I.length == 0);
2840     static assert(I.tupleof.length == 0);
2841 
2842     union U
2843     {
2844         int i;
2845         double d;
2846         long l;
2847         S s;
2848     }
2849     static assert(__traits(isSame, FieldSymbols!U, AliasSeq!(U.i, U.d, U.l, U.s)));
2850 
2851     // FieldSymbols!C and C.tupleof have the same symbols, because they are
2852     // always the same for unions.
2853     static assert(__traits(isSame, FieldSymbols!U, U.tupleof));
2854 
2855     // FieldSymbols only operates on aggregate types.
2856     static assert(!__traits(compiles, FieldSymbols!int));
2857     static assert(!__traits(compiles, FieldSymbols!(S*)));
2858     static assert(!__traits(compiles, FieldSymbols!(C[])));
2859 }
2860 
2861 /// Some examples with nested types.
2862 @safe unittest
2863 {
2864     import phobos.sys.meta : AliasSeq;
2865 
2866     int outside;
2867 
2868     struct S
2869     {
2870         long l;
2871         string s;
2872 
2873         void foo() { outside = 2; }
2874     }
2875     static assert(__traits(isNested, S));
2876     static assert(__traits(isSame, FieldSymbols!S, AliasSeq!(S.l, S.s)));
2877 
2878     // FieldSymbols!S and S.tupleof are not the same, because S is nested, and
2879     // the context pointer to the outer scope is included in S.tupleof, whereas
2880     // it is excluded from FieldSymbols!S.
2881     static assert(__traits(isSame, S.tupleof[0 .. $ - 1], AliasSeq!(S.l, S.s)));
2882     static assert(S.tupleof[$ - 1].stringof == "this");
2883 
2884     class C
2885     {
2886         bool b;
2887         int* ptr;
2888 
2889         void foo() { outside = 7; }
2890     }
2891     static assert(__traits(isNested, C));
2892     static assert(__traits(isSame, FieldSymbols!C, AliasSeq!(C.b, C.ptr)));
2893 
2894     // FieldSymbols!C and C.tupleof have the same symbols, because they are
2895     // always the same for classes. No context pointer is provided as part of
2896     // tupleof for nested classes.
2897     static assert(__traits(isSame, FieldSymbols!C, C.tupleof));
2898 
2899     // __traits(isNested, ...) is never true for interfaces or unions, since
2900     // they cannot have a context pointer to an outer scope. So, tupleof and
2901     // FieldSymbols will always be the same for interfaces and unions.
2902 }
2903 
2904 @safe unittest
2905 {
2906     import phobos.sys.meta : AliasSeq;
2907 
2908     {
2909         static struct S0 {}
2910         static assert(FieldSymbols!S0.length == 0);
2911 
2912         static struct S1 { int a; }
2913         static assert(__traits(isSame, FieldSymbols!S1, AliasSeq!(S1.a)));
2914 
2915         static struct S2 { int a; string b; }
2916         static assert(__traits(isSame, FieldSymbols!S2, AliasSeq!(S2.a, S2.b)));
2917 
2918         static struct S3 { int a; string b; real c; }
2919         static assert(__traits(isSame, FieldSymbols!S3, AliasSeq!(S3.a, S3.b, S3.c)));
2920     }
2921     {
2922         int i;
2923         struct S0 { void foo() { i = 0; }}
2924         static assert(FieldSymbols!S0.length == 0);
2925         static assert(__traits(isNested, S0));
2926 
2927         struct S1 { int a; void foo() { i = 0; } }
2928         static assert(__traits(isSame, FieldSymbols!S1, AliasSeq!(S1.a)));
2929         static assert(__traits(isNested, S1));
2930 
2931         struct S2 { int a; string b; void foo() { i = 0; } }
2932         static assert(__traits(isSame, FieldSymbols!S2, AliasSeq!(S2.a, S2.b)));
2933         static assert(__traits(isNested, S2));
2934 
2935         struct S3 { int a; string b; real c; void foo() { i = 0; } }
2936         static assert(__traits(isSame, FieldSymbols!S3, AliasSeq!(S3.a, S3.b, S3.c)));
2937         static assert(__traits(isNested, S3));
2938     }
2939     {
2940         static class C0 {}
2941         static assert(FieldSymbols!C0.length == 0);
2942 
2943         static class C1 { int a; }
2944         static assert(__traits(isSame, FieldSymbols!C1, AliasSeq!(C1.a)));
2945 
2946         static class C2 { int a; string b; }
2947         static assert(__traits(isSame, FieldSymbols!C2, AliasSeq!(C2.a, C2.b)));
2948 
2949         static class C3 { int a; string b; real c; }
2950         static assert(__traits(isSame, FieldSymbols!C3, AliasSeq!(C3.a, C3.b, C3.c)));
2951 
2952         static class D0 : C3 {}
2953         static assert(FieldSymbols!D0.length == 0);
2954 
2955         static class D1 : C3 { bool x; }
2956         static assert(__traits(isSame, FieldSymbols!D1, AliasSeq!(D1.x)));
2957 
2958         static class D2 : C3 { bool x; int* y; }
2959         static assert(__traits(isSame, FieldSymbols!D2, AliasSeq!(D2.x, D2.y)));
2960 
2961         static class D3 : C3 { bool x; int* y; short[] z; }
2962         static assert(__traits(isSame, FieldSymbols!D3, AliasSeq!(D3.x, D3.y, D3.z)));
2963     }
2964     {
2965         int i;
2966         class C0 { void foo() { i = 0; }}
2967         static assert(FieldSymbols!C0.length == 0);
2968         static assert(__traits(isNested, C0));
2969 
2970         class C1 { int a; void foo() { i = 0; } }
2971         static assert(__traits(isSame, FieldSymbols!C1, AliasSeq!(C1.a)));
2972         static assert(__traits(isNested, C1));
2973 
2974         class C2 { int a; string b; void foo() { i = 0; } }
2975         static assert(__traits(isSame, FieldSymbols!C2, AliasSeq!(C2.a, C2.b)));
2976         static assert(__traits(isNested, C2));
2977 
2978         class C3 { int a; string b; real c; void foo() { i = 0; } }
2979         static assert(__traits(isSame, FieldSymbols!C3, AliasSeq!(C3.a, C3.b, C3.c)));
2980         static assert(__traits(isNested, C3));
2981 
2982         class D0 : C3 {}
2983         static assert(FieldSymbols!D0.length == 0);
2984         static assert(__traits(isNested, D0));
2985 
2986         class D1 : C3 { bool x; }
2987         static assert(__traits(isSame, FieldSymbols!D1, AliasSeq!(D1.x)));
2988         static assert(__traits(isNested, D1));
2989 
2990         class D2 : C3 { bool x; int* y; }
2991         static assert(__traits(isSame, FieldSymbols!D2, AliasSeq!(D2.x, D2.y)));
2992         static assert(__traits(isNested, D2));
2993 
2994         class D3 : C3 { bool x; int* y; short[] z; }
2995         static assert(__traits(isSame, FieldSymbols!D3, AliasSeq!(D3.x, D3.y, D3.z)));
2996         static assert(__traits(isNested, D3));
2997     }
2998     {
2999         static union U0 {}
3000         static assert(FieldSymbols!U0.length == 0);
3001 
3002         static union U1 { int a; }
3003         static assert(__traits(isSame, FieldSymbols!U1, AliasSeq!(U1.a)));
3004 
3005         static union U2 { int a; string b; }
3006         static assert(__traits(isSame, FieldSymbols!U2, AliasSeq!(U2.a, U2.b)));
3007 
3008         static union U3 { int a; string b; real c; }
3009         static assert(__traits(isSame, FieldSymbols!U3, AliasSeq!(U3.a, U3.b, U3.c)));
3010     }
3011     {
3012         static struct S
3013         {
3014             enum e = 42;
3015             static str = "foobar";
3016 
3017             string name() { return "foo"; }
3018 
3019             int[] arr;
3020 
3021             struct Inner1 { int i; }
3022 
3023             static struct Inner2 { long gnol; }
3024 
3025             union { int a; string b; }
3026 
3027             alias Foo = Inner1;
3028         }
3029 
3030         static assert(__traits(isSame, FieldSymbols!S, AliasSeq!(S.arr, S.a, S.b)));
3031         static assert(__traits(isSame, FieldSymbols!(const S), AliasSeq!(S.arr, S.a, S.b)));
3032         static assert(__traits(isSame, FieldSymbols!(S.Inner1), AliasSeq!(S.Inner1.i)));
3033         static assert(__traits(isSame, FieldSymbols!(S.Inner2), AliasSeq!(S.Inner2.gnol)));
3034     }
3035 }
3036 
3037 /++
3038     Evaluates to an $(D AliasSeq) of the types of the member variables of an
3039     aggregate type (i.e. a struct, class, interface, or union).
3040 
3041     These are fields which take up memory space within an instance of the type
3042     (i.e. not enums / manifest constants, since they don't take up memory
3043     space, and not static member variables, since they don't take up memory
3044     space within an instance).
3045 
3046     Hidden fields (like the virtual function table pointer or the context
3047     pointer for nested types) are not included.
3048 
3049     For classes, only the direct member variables are included and not those
3050     of any base classes.
3051 
3052     For interfaces, the result of FieldTypes is always empty, because
3053     interfaces cannot have member variables. However, because interfaces are
3054     aggregate types, they work with FieldTypes for consistency so that code
3055     that's written to work on aggregate types doesn't have to worry about
3056     whether it's dealing with an interface.
3057 
3058     See_Also:
3059         $(LREF FieldNames)
3060         $(LREF FieldSymbols)
3061         $(DDSUBLINK spec/struct.html, struct_instance_properties, $(D tupleof))
3062   +/
3063 template FieldTypes(T)
3064 if (isAggregateType!T)
3065 {
3066     static if (is(T == struct) && __traits(isNested, T))
3067         alias FieldTypes = typeof(T.tupleof[0 .. $ - 1]);
3068     else
3069         alias FieldTypes = typeof(T.tupleof);
3070 }
3071 
3072 ///
3073 @safe unittest
3074 {
3075     import phobos.sys.meta : AliasSeq;
3076 
3077     struct S
3078     {
3079         int x;
3080         float y;
3081     }
3082     static assert(is(FieldTypes!S == AliasSeq!(int, float)));
3083 
3084     // Type qualifers will be passed on to the result.
3085     static assert(is(FieldTypes!(const S) == AliasSeq!(const int, const float)));
3086     static assert(is(FieldTypes!(shared S) == AliasSeq!(shared int, shared float)));
3087 
3088     class C
3089     {
3090         // static variables are not included.
3091         static int var;
3092 
3093         // Manifest constants are not included.
3094         enum lang = "dlang";
3095 
3096         // Functions are not included, even if they're @property functions.
3097         @property int foo() { return 42; }
3098 
3099         string s;
3100         int i;
3101         int[] arr;
3102     }
3103     static assert(is(FieldTypes!C == AliasSeq!(string, int, int[])));
3104 
3105     // Only direct member variables are included. Member variables from any base
3106     // classes are not.
3107     class D : C
3108     {
3109         real r;
3110     }
3111     static assert(is(FieldTypes!D == AliasSeq!real));
3112 
3113     // FieldTypes will always be empty for an interface, since it's not legal
3114     // for interfaces to have member variables.
3115     interface I
3116     {
3117     }
3118     static assert(FieldTypes!I.length == 0);
3119 
3120     union U
3121     {
3122         int i;
3123         double d;
3124         long l;
3125         S s;
3126     }
3127     static assert(is(FieldTypes!U == AliasSeq!(int, double, long, S)));
3128 
3129     // FieldTypes only operates on aggregate types.
3130     static assert(!__traits(compiles, FieldTypes!int));
3131     static assert(!__traits(compiles, FieldTypes!(S*)));
3132     static assert(!__traits(compiles, FieldTypes!(C[])));
3133 }
3134 
3135 @safe unittest
3136 {
3137     import phobos.sys.meta : AliasSeq;
3138 
3139     {
3140         static struct S0 {}
3141         static assert(FieldTypes!S0.length == 0);
3142 
3143         static struct S1 { int a; }
3144         static assert(is(FieldTypes!S1 == AliasSeq!int));
3145 
3146         static struct S2 { int a; string b; }
3147         static assert(is(FieldTypes!S2 == AliasSeq!(int, string)));
3148 
3149         static struct S3 { int a; string b; real c; }
3150         static assert(is(FieldTypes!S3 == AliasSeq!(int, string, real)));
3151     }
3152     {
3153         int i;
3154         struct S0 { void foo() { i = 0; }}
3155         static assert(FieldTypes!S0.length == 0);
3156         static assert(__traits(isNested, S0));
3157 
3158         struct S1 { int a; void foo() { i = 0; } }
3159         static assert(is(FieldTypes!S1 == AliasSeq!int));
3160         static assert(__traits(isNested, S1));
3161 
3162         struct S2 { int a; string b; void foo() { i = 0; } }
3163         static assert(is(FieldTypes!S2 == AliasSeq!(int, string)));
3164         static assert(__traits(isNested, S2));
3165 
3166         struct S3 { int a; string b; real c; void foo() { i = 0; } }
3167         static assert(is(FieldTypes!S3 == AliasSeq!(int, string, real)));
3168         static assert(__traits(isNested, S3));
3169     }
3170     {
3171         static class C0 {}
3172         static assert(FieldTypes!C0.length == 0);
3173 
3174         static class C1 { int a; }
3175         static assert(is(FieldTypes!C1 == AliasSeq!int));
3176 
3177         static class C2 { int a; string b; }
3178         static assert(is(FieldTypes!C2 == AliasSeq!(int, string)));
3179 
3180         static class C3 { int a; string b; real c; }
3181         static assert(is(FieldTypes!C3 == AliasSeq!(int, string, real)));
3182 
3183         static class D0 : C3 {}
3184         static assert(FieldTypes!D0.length == 0);
3185 
3186         static class D1 : C3 { bool x; }
3187         static assert(is(FieldTypes!D1 == AliasSeq!bool));
3188 
3189         static class D2 : C3 { bool x; int* y; }
3190         static assert(is(FieldTypes!D2 == AliasSeq!(bool, int*)));
3191 
3192         static class D3 : C3 { bool x; int* y; short[] z; }
3193         static assert(is(FieldTypes!D3 == AliasSeq!(bool, int*, short[])));
3194     }
3195     {
3196         int i;
3197         class C0 { void foo() { i = 0; }}
3198         static assert(FieldTypes!C0.length == 0);
3199         static assert(__traits(isNested, C0));
3200 
3201         class C1 { int a; void foo() { i = 0; } }
3202         static assert(is(FieldTypes!C1 == AliasSeq!int));
3203         static assert(__traits(isNested, C1));
3204 
3205         class C2 { int a; string b; void foo() { i = 0; } }
3206         static assert(is(FieldTypes!C2 == AliasSeq!(int, string)));
3207         static assert(__traits(isNested, C2));
3208 
3209         class C3 { int a; string b; real c; void foo() { i = 0; } }
3210         static assert(is(FieldTypes!C3 == AliasSeq!(int, string, real)));
3211         static assert(__traits(isNested, C3));
3212 
3213         class D0 : C3 {}
3214         static assert(FieldTypes!D0.length == 0);
3215         static assert(__traits(isNested, D0));
3216 
3217         class D1 : C3 { bool x; }
3218         static assert(is(FieldTypes!D1 == AliasSeq!bool));
3219         static assert(__traits(isNested, D1));
3220 
3221         class D2 : C3 { bool x; int* y; }
3222         static assert(is(FieldTypes!D2 == AliasSeq!(bool, int*)));
3223         static assert(__traits(isNested, D2));
3224 
3225         class D3 : C3 { bool x; int* y; short[] z; }
3226         static assert(is(FieldTypes!D3 == AliasSeq!(bool, int*, short[])));
3227         static assert(__traits(isNested, D3));
3228     }
3229     {
3230         static union U0 {}
3231         static assert(FieldTypes!U0.length == 0);
3232 
3233         static union U1 { int a; }
3234         static assert(is(FieldTypes!U1 == AliasSeq!int));
3235 
3236         static union U2 { int a; string b; }
3237         static assert(is(FieldTypes!U2 == AliasSeq!(int, string)));
3238 
3239         static union U3 { int a; string b; real c; }
3240         static assert(is(FieldTypes!U3 == AliasSeq!(int, string, real)));
3241     }
3242     {
3243         static struct S
3244         {
3245             enum e = 42;
3246             static str = "foobar";
3247 
3248             string name() { return "foo"; }
3249 
3250             int[] arr;
3251 
3252             struct Inner1 { int i; }
3253 
3254             static struct Inner2 { long gnol; }
3255 
3256             union { int a; string b; }
3257 
3258             alias Foo = Inner1;
3259         }
3260 
3261         static assert(is(FieldTypes!S == AliasSeq!(int[], int, string)));
3262         static assert(is(FieldTypes!(const S) == AliasSeq!(const(int[]), const int, const string)));
3263         static assert(is(FieldTypes!(S.Inner1) == AliasSeq!int));
3264         static assert(is(FieldTypes!(S.Inner2) == AliasSeq!long));
3265     }
3266 }
3267 
3268 /++
3269     Takes a type which is an associative array and evaluates to the type of the
3270     keys in that associative array.
3271 
3272     See_Also:
3273         $(LREF ValueType)
3274   +/
3275 alias KeyType(V : V[K], K) = K;
3276 
3277 ///
3278 @safe unittest
3279 {
3280     static assert(is(KeyType!(int[string]) == string));
3281     static assert(is(KeyType!(string[int]) == int));
3282 
3283     static assert(is(KeyType!(string[const int]) == const int));
3284     static assert(is(KeyType!(const int[string]) == string));
3285 
3286     struct S
3287     {
3288         int i;
3289     }
3290 
3291     string[S] aa1;
3292     static assert(is(KeyType!(typeof(aa1)) == S));
3293 
3294     S[string] aa2;
3295     static assert(is(KeyType!(typeof(aa2)) == string));
3296 
3297     KeyType!(typeof(aa1)) key1 = S(42);
3298     KeyType!(typeof(aa2)) key2 = "foo";
3299 
3300     // Key types with indirections have their inner layers treated as const
3301     // by the compiler, because the values of keys can't change, or the hash
3302     // value could change, putting the associative array in an invalid state.
3303     static assert(is(KeyType!(bool[string[]]) == const(string)[]));
3304     static assert(is(KeyType!(bool[int*]) == const(int)*));
3305 
3306     // If the given type is not an AA, then KeyType won't compile.
3307     static assert(!__traits(compiles, KeyType!int));
3308     static assert(!__traits(compiles, KeyType!(int[])));
3309 }
3310 
3311 /++
3312     Takes a type which is an associative array and evaluates to the type of the
3313     values in that associative array.
3314 
3315     See_Also:
3316         $(LREF KeyType)
3317   +/
3318 alias ValueType(V : V[K], K) = V;
3319 
3320 ///
3321 @safe unittest
3322 {
3323     static assert(is(ValueType!(int[string]) == int));
3324     static assert(is(ValueType!(string[int]) == string));
3325 
3326     static assert(is(ValueType!(string[const int]) == string));
3327     static assert(is(ValueType!(const int[string]) == const int));
3328 
3329     struct S
3330     {
3331         int i;
3332     }
3333 
3334     string[S] aa1;
3335     static assert(is(ValueType!(typeof(aa1)) == string));
3336 
3337     S[string] aa2;
3338     static assert(is(ValueType!(typeof(aa2)) == S));
3339 
3340     ValueType!(typeof(aa1)) value1 = "foo";
3341     ValueType!(typeof(aa2)) value2 = S(42);
3342 
3343     // If the given type is not an AA, then ValueType won't compile.
3344     static assert(!__traits(compiles, ValueType!int));
3345     static assert(!__traits(compiles, ValueType!(int[])));
3346 }
3347 
3348 /++
3349     Evaluates to the original / ultimate base type of an enum type - or for
3350     non-enum types, it evaluates to the type that it's given.
3351 
3352     If the base type of the given enum type is not an enum, then the result of
3353     OriginalType is its direct base type. However, if the base type of the
3354     given enum is also an enum, then OriginalType gives the ultimate base type
3355     - that is, it keeps getting the base type for each succesive enum in the
3356     chain until it gets to a base type that isn't an enum, and that's the
3357     result. So, the result will never be an enum type.
3358 
3359     If the given type has any qualifiers, the result will have those same
3360     qualifiers.
3361   +/
3362 version (StdDdoc) template OriginalType(T)
3363 {
3364     import core.internal.traits : CoreOriginalType = OriginalType;
3365     alias OriginalType = CoreOriginalType!T;
3366 }
3367 else
3368 {
3369     import core.internal.traits : CoreOriginalType = OriginalType;
3370     alias OriginalType = CoreOriginalType;
3371 }
3372 
3373 ///
3374 @safe unittest
3375 {
3376     enum E { a, b, c }
3377     static assert(is(OriginalType!E == int));
3378 
3379     enum F : E { x = E.a }
3380     static assert(is(OriginalType!F == int));
3381 
3382     enum G : F { y = F.x }
3383     static assert(is(OriginalType!G == int));
3384     static assert(is(OriginalType!(const G) == const int));
3385     static assert(is(OriginalType!(immutable G) == immutable int));
3386     static assert(is(OriginalType!(shared G) == shared int));
3387 
3388     enum C : char { a = 'a', b = 'b' }
3389     static assert(is(OriginalType!C == char));
3390 
3391     enum D : string { d = "dlang" }
3392     static assert(is(OriginalType!D == string));
3393 
3394     static assert(is(OriginalType!int == int));
3395     static assert(is(OriginalType!(const long) == const long));
3396     static assert(is(OriginalType!string == string));
3397 
3398     // OriginalType gets the base type of enums and for all other types gives
3399     // the same type back. It does nothing special for other types - like
3400     // classes - where one could talk about the type having a base type.
3401     class Base {}
3402     class Derived : Base {}
3403     static assert(is(OriginalType!Base == Base));
3404     static assert(is(OriginalType!Derived == Derived));
3405 }
3406 
3407 /++
3408     Removes the outer layer of $(D const), $(D inout), or $(D immutable)
3409     from type $(D T).
3410 
3411     If none of those qualifiers have been applied to the outer layer of
3412     type $(D T), then the result is $(D T).
3413 
3414     For the built-in scalar types (that is $(D bool), the character types, and
3415     the numeric types), they only have one layer, so $(D const U) simply becomes
3416     $(D U).
3417 
3418     Where the layers come in is pointers and arrays. $(D const(U*)) becomes
3419     $(D const(U)*), and $(D const(U[])), becomes $(D const(U)[]). So, a pointer
3420     goes from being fully $(D const) to being a mutable pointer to $(D const),
3421     and a dynamic array goes from being fully $(D const) to being a mutable
3422     dynamic array of $(D const) elements. And if there are multiple layers of
3423     pointers or arrays, it's just that outer layer which is affected - e.g.
3424     $(D const(U**)) would become $(D const(U*)*).
3425 
3426     For user-defined types, the effect is that $(D const U) becomes $(D U), and
3427     how that affects member variables depends on the type of the member
3428     variable. If a member variable is explicitly marked with any mutability
3429     qualifiers, then it will continue to have those qualifiers even after
3430     Unconst has stripped all mutability qualifiers from the containing type.
3431     However, if a mutability qualifier was on the member variable only because
3432     the containing type had that qualifier, then when Unconst removes the
3433     qualifier from the containing type, it is removed from the member variable
3434     as well.
3435 
3436     Also, Unconst has no effect on what a templated type is instantiated
3437     with, so if a templated type is instantiated with a template argument which
3438     has a mutability qualifier, the template instantiation will not change.
3439   +/
3440 version (StdDdoc) template Unconst(T)
3441 {
3442     import core.internal.traits : CoreUnconst = Unconst;
3443     alias Unconst = CoreUnconst!T;
3444 }
3445 else
3446 {
3447     import core.internal.traits : CoreUnconst = Unconst;
3448     alias Unconst = CoreUnconst;
3449 }
3450 
3451 ///
3452 @safe unittest
3453 {
3454     static assert(is(Unconst!(                   int) == int));
3455     static assert(is(Unconst!(             const int) == int));
3456     static assert(is(Unconst!(       inout       int) == int));
3457     static assert(is(Unconst!(       inout const int) == int));
3458     static assert(is(Unconst!(shared             int) == shared int));
3459     static assert(is(Unconst!(shared       const int) == shared int));
3460     static assert(is(Unconst!(shared inout       int) == shared int));
3461     static assert(is(Unconst!(shared inout const int) == shared int));
3462     static assert(is(Unconst!(         immutable int) == int));
3463 
3464     // Only the outer layer of immutable is removed.
3465     // immutable(int[]) -> immutable(int)[]
3466     alias ImmIntArr = immutable(int[]);
3467     static assert(is(Unconst!ImmIntArr == immutable(int)[]));
3468 
3469     // Only the outer layer of const is removed.
3470     // immutable(int*) -> immutable(int)*
3471     alias ConstIntPtr = const(int*);
3472     static assert(is(Unconst!ConstIntPtr == const(int)*));
3473 
3474     // const(int)* -> const(int)*
3475     alias PtrToConstInt = const(int)*;
3476     static assert(is(Unconst!PtrToConstInt == const(int)*));
3477 
3478     static struct S
3479     {
3480         int* ptr;
3481         const int* cPtr;
3482         shared int* sPtr;
3483     }
3484 
3485     const S s;
3486     static assert(is(typeof(s) == const S));
3487     static assert(is(typeof(typeof(s).ptr) == const int*));
3488     static assert(is(typeof(typeof(s).cPtr) == const int*));
3489     static assert(is(typeof(typeof(s).sPtr) == const shared int*));
3490 
3491     // For user-defined types, all mutability qualifiers that are applied to
3492     // member variables only because the containing type has them are removed,
3493     // but the ones that are directly on those member variables remain.
3494 
3495     // const S -> S
3496     static assert(is(Unconst!(typeof(s)) == S));
3497     static assert(is(typeof(Unconst!(typeof(s)).ptr) == int*));
3498     static assert(is(typeof(Unconst!(typeof(s)).cPtr) == const int*));
3499     static assert(is(typeof(Unconst!(typeof(s)).sPtr) == shared int*));
3500 
3501     static struct Foo(T)
3502     {
3503         T* ptr;
3504     }
3505 
3506     // The qualifier on the type is removed, but the qualifier on the template
3507     // argument is not.
3508     static assert(is(Unconst!(const(Foo!(const int))) == Foo!(const int)));
3509     static assert(is(Unconst!(Foo!(const int)) == Foo!(const int)));
3510     static assert(is(Unconst!(const(Foo!int)) == Foo!int));
3511 }
3512 
3513 /++
3514     Removes the outer layer of $(D shared) from type $(D T).
3515 
3516     If $(D shared) has not been applied to the outer layer of type $(D T), then
3517     the result is $(D T).
3518 
3519     Note that while $(D immutable) is implicitly $(D shared), it is unaffected
3520     by Unshared. Only explicit $(D shared) is removed.
3521 
3522     For the built-in scalar types (that is $(D bool), the character types, and
3523     the numeric types), they only have one layer, so $(D shared U) simply
3524     becomes $(D U).
3525 
3526     Where the layers come in is pointers and arrays. $(D shared(U*)) becomes
3527     $(D shared(U)*), and $(D shared(U[])), becomes $(D shared(U)[]). So, a
3528     pointer goes from being fully $(D shared) to being a mutable pointer to
3529     $(D shared), and a dynamic array goes from being fully $(D shared) to being
3530     a mutable dynamic array of $(D shared) elements. And if there are multiple
3531     layers of pointers or arrays, it's just that outer layer which is affected
3532     - e.g. $(D shared(U**)) would become $(D shared(U*)*).
3533 
3534     For user-defined types, the effect is that $(D shared U) becomes $(D U),
3535     and how that affects member variables depends on the type of the member
3536     variable. If a member variable is explicitly marked with $(D shared), then
3537     it will continue to be $(D shared) even after Unshared has stripped
3538     $(D shared) from the containing type. However, if $(D shared) was on the
3539     member variable only because the containing type was $(D shared), then when
3540     Unshared removes the qualifier from the containing type, it is removed from
3541     the member variable as well.
3542 
3543     Also, Unshared has no effect on what a templated type is instantiated
3544     with, so if a templated type is instantiated with a template argument which
3545     has a type qualifier, the template instantiation will not change.
3546   +/
3547 template Unshared(T)
3548 {
3549     static if (is(T == shared U, U))
3550         alias Unshared = U;
3551     else
3552         alias Unshared = T;
3553 }
3554 
3555 ///
3556 @safe unittest
3557 {
3558     static assert(is(Unshared!(                   int) == int));
3559     static assert(is(Unshared!(             const int) == const int));
3560     static assert(is(Unshared!(       inout       int) == inout int));
3561     static assert(is(Unshared!(       inout const int) == inout const int));
3562     static assert(is(Unshared!(shared             int) == int));
3563     static assert(is(Unshared!(shared       const int) == const int));
3564     static assert(is(Unshared!(shared inout       int) == inout int));
3565     static assert(is(Unshared!(shared inout const int) == inout const int));
3566     static assert(is(Unshared!(         immutable int) == immutable int));
3567 
3568     // Only the outer layer of shared is removed.
3569     // shared(int[]) -> shared(int)[]
3570     alias SharedIntArr = shared(int[]);
3571     static assert(is(Unshared!SharedIntArr == shared(int)[]));
3572 
3573     // Only the outer layer of shared is removed.
3574     // shared(int*) -> shared(int)*
3575     alias SharedIntPtr = shared(int*);
3576     static assert(is(Unshared!SharedIntPtr == shared(int)*));
3577 
3578     // shared(int)* -> shared(int)*
3579     alias PtrToSharedInt = shared(int)*;
3580     static assert(is(Unshared!PtrToSharedInt == shared(int)*));
3581 
3582     // immutable is unaffected
3583     alias ImmutableArr = immutable(int[]);
3584     static assert(is(Unshared!ImmutableArr == immutable(int[])));
3585 
3586     static struct S
3587     {
3588         int* ptr;
3589         const int* cPtr;
3590         shared int* sPtr;
3591     }
3592 
3593     shared S s;
3594     static assert(is(typeof(s) == shared S));
3595     static assert(is(typeof(typeof(s).ptr) == shared int*));
3596     static assert(is(typeof(typeof(s).cPtr) == const shared int*));
3597     static assert(is(typeof(typeof(s).sPtr) == shared int*));
3598 
3599     // For user-defined types, if shared is applied to a member variable only
3600     // because the containing type is shared, then shared is removed from that
3601     // member variable, but if the member variable is directly marked as shared,
3602     // then it continues to be shared.
3603 
3604     // shared S -> S
3605     static assert(is(Unshared!(typeof(s)) == S));
3606     static assert(is(typeof(Unshared!(typeof(s)).ptr) == int*));
3607     static assert(is(typeof(Unshared!(typeof(s)).cPtr) == const int*));
3608     static assert(is(typeof(Unshared!(typeof(s)).sPtr) == shared int*));
3609 
3610     static struct Foo(T)
3611     {
3612         T* ptr;
3613     }
3614 
3615     // The qualifier on the type is removed, but the qualifier on the template
3616     // argument is not.
3617     static assert(is(Unshared!(shared(Foo!(shared int))) == Foo!(shared int)));
3618     static assert(is(Unshared!(Foo!(shared int)) == Foo!(shared int)));
3619     static assert(is(Unshared!(shared(Foo!int)) == Foo!int));
3620 }
3621 
3622 /++
3623     Removes the outer layer of all type qualifiers from type $(D T) - this
3624     includes $(D shared).
3625 
3626     If no type qualifiers have been applied to the outer layer of type $(D T),
3627     then the result is $(D T).
3628 
3629     For the built-in scalar types (that is $(D bool), the character types, and
3630     the numeric types), they only have one layer, so $(D const U) simply becomes
3631     $(D U).
3632 
3633     Where the layers come in is pointers and arrays. $(D const(U*)) becomes
3634     $(D const(U)*), and $(D const(U[])), becomes $(D const(U)[]). So, a pointer
3635     goes from being fully $(D const) to being a mutable pointer to $(D const),
3636     and a dynamic array goes from being fully $(D const) to being a mutable
3637     dynamic array of $(D const) elements. And if there are multiple layers of
3638     pointers or arrays, it's just that outer layer which is affected - e.g.
3639     $(D shared(U**)) would become $(D shared(U*)*).
3640 
3641     For user-defined types, the effect is that $(D const U) becomes $(D U), and
3642     how that affects member variables depends on the type of the member
3643     variable. If a member variable is explicitly marked with any qualifiers,
3644     then it will continue to have those qualifiers even after Unqualified has
3645     stripped all qualifiers from the containing type. However, if a qualifier
3646     was on the member variable only because the containing type had that
3647     qualifier, then when Unqualified removes the qualifier from the containing
3648     type, it is removed from the member variable as well.
3649 
3650     Also, Unqualified has no effect on what a templated type is instantiated
3651     with, so if a templated type is instantiated with a template argument which
3652     has a type qualifier, the template instantiation will not change.
3653 
3654     Note that in most cases, $(LREF Unconst) or $(LREF Unshared) should be used
3655     rather than Unqualified, because in most cases, code is not designed to
3656     work with $(D shared) and thus doing type checks which remove $(D shared)
3657     will allow $(D shared) types to pass template constraints when they won't
3658     actually work with the code. And when code is designed to work with
3659     $(D shared), it's often the case that the type checks need to take
3660     $(D const) into account in order to avoid accidentally mutating $(D const)
3661     data and violating the type system.
3662 
3663     In particular, historically, a lot of D code has used
3664     $(REF Unqual, std, traits) (which is equivalent to phobos.sys.traits'
3665     Unqualified) when the programmer's intent was to remove $(D const), and
3666     $(D shared) wasn't actually considered at all. And in such cases, the code
3667     really should use $(LREF Unconst) instead.
3668 
3669     But of course, if a template constraint or $(D static if) really needs to
3670     strip off both the mutability qualifiers and $(D shared) for what it's
3671     testing for, then that's what Unqualified is for. It's just that it's best
3672     practice to use $(LREF Unconst) when it's not clear that $(D shared) should
3673     be removed as well.
3674   +/
3675 version (StdDdoc) template Unqualified(T)
3676 {
3677     import core.internal.traits : CoreUnqualified = Unqual;
3678     alias Unqualified = CoreUnqualified!(T);
3679 }
3680 else
3681 {
3682     import core.internal.traits : CoreUnqualified = Unqual;
3683     alias Unqualified = CoreUnqualified;
3684 }
3685 
3686 ///
3687 @safe unittest
3688 {
3689     static assert(is(Unqualified!(                   int) == int));
3690     static assert(is(Unqualified!(             const int) == int));
3691     static assert(is(Unqualified!(       inout       int) == int));
3692     static assert(is(Unqualified!(       inout const int) == int));
3693     static assert(is(Unqualified!(shared             int) == int));
3694     static assert(is(Unqualified!(shared       const int) == int));
3695     static assert(is(Unqualified!(shared inout       int) == int));
3696     static assert(is(Unqualified!(shared inout const int) == int));
3697     static assert(is(Unqualified!(         immutable int) == int));
3698 
3699     // Only the outer layer of immutable is removed.
3700     // immutable(int[]) -> immutable(int)[]
3701     alias ImmIntArr = immutable(int[]);
3702     static assert(is(Unqualified!ImmIntArr == immutable(int)[]));
3703 
3704     // Only the outer layer of const is removed.
3705     // const(int*) -> const(int)*
3706     alias ConstIntPtr = const(int*);
3707     static assert(is(Unqualified!ConstIntPtr == const(int)*));
3708 
3709     // const(int)* -> const(int)*
3710     alias PtrToConstInt = const(int)*;
3711     static assert(is(Unqualified!PtrToConstInt == const(int)*));
3712 
3713     // Only the outer layer of shared is removed.
3714     // shared(int*) -> shared(int)*
3715     alias SharedIntPtr = shared(int*);
3716     static assert(is(Unqualified!SharedIntPtr == shared(int)*));
3717 
3718     // shared(int)* -> shared(int)*
3719     alias PtrToSharedInt = shared(int)*;
3720     static assert(is(Unqualified!PtrToSharedInt == shared(int)*));
3721 
3722     // Both const and shared are removed from the outer layer.
3723     // shared const int[] -> shared(const(int))[]
3724     alias SharedConstIntArr = shared const(int[]);
3725     static assert(is(Unqualified!SharedConstIntArr == shared(const(int))[]));
3726 
3727     static struct S
3728     {
3729         int* ptr;
3730         const int* cPtr;
3731         shared int* sPtr;
3732     }
3733 
3734     shared const S s;
3735     static assert(is(typeof(s) == shared const S));
3736     static assert(is(typeof(typeof(s).ptr) == shared const int*));
3737     static assert(is(typeof(typeof(s).cPtr) == shared const int*));
3738     static assert(is(typeof(typeof(s).sPtr) == shared const int*));
3739 
3740     // For user-defined types, all qualifiers that are applied to member
3741     // variables only because the containing type has them are removed, but the
3742     // ones that are directly on those member variables remain.
3743 
3744     // shared const S -> S
3745     static assert(is(Unqualified!(typeof(s)) == S));
3746     static assert(is(typeof(Unqualified!(typeof(s)).ptr) == int*));
3747     static assert(is(typeof(Unqualified!(typeof(s)).cPtr) == const int*));
3748     static assert(is(typeof(Unqualified!(typeof(s)).sPtr) == shared int*));
3749 
3750     static struct Foo(T)
3751     {
3752         T* ptr;
3753     }
3754 
3755     // The qualifiers on the type are removed, but the qualifiers on the
3756     // template argument are not.
3757     static assert(is(Unqualified!(const(Foo!(const int))) == Foo!(const int)));
3758     static assert(is(Unqualified!(Foo!(const int)) == Foo!(const int)));
3759     static assert(is(Unqualified!(const(Foo!int)) == Foo!int));
3760 }
3761 
3762 /++
3763     Applies $(D const) to the given type.
3764 
3765     This is primarily useful in conjunction with templates that take a template
3766     predicate (such as many of the templates in phobos.sys.meta), since while in
3767     most cases, you can simply do $(D const T) or $(D const(T)) to make $(D T)
3768     $(D const), with something like $(REF Map, phobos, sys, meta), you need to
3769     pass a template to be applied.
3770 
3771     See_Also:
3772         $(LREF ImmutableOf)
3773         $(LREF InoutOf)
3774         $(LREF SharedOf)
3775   +/
3776 alias ConstOf(T) = const T;
3777 
3778 ///
3779 @safe unittest
3780 {
3781     static assert(is(ConstOf!int == const int));
3782     static assert(is(ConstOf!(const int) == const int));
3783     static assert(is(ConstOf!(inout int) == inout const int));
3784     static assert(is(ConstOf!(shared int) == const shared int));
3785 
3786     // Note that const has no effect on immutable.
3787     static assert(is(ConstOf!(immutable int) == immutable int));
3788 
3789     import phobos.sys.meta : AliasSeq, Map;
3790 
3791     alias Types = AliasSeq!(int, long,
3792                             bool*, ubyte[],
3793                             string, immutable(string));
3794     alias WithConst = Map!(ConstOf, Types);
3795     static assert(is(WithConst ==
3796                      AliasSeq!(const int, const long,
3797                                const(bool*), const(ubyte[]),
3798                                const(string), immutable(string))));
3799 }
3800 
3801 /++
3802     Applies $(D immutable) to the given type.
3803 
3804     This is primarily useful in conjunction with templates that take a template
3805     predicate (such as many of the templates in phobos.sys.meta), since while in
3806     most cases, you can simply do $(D immutable T) or $(D immutable(T)) to make
3807     $(D T) $(D immutable), with something like $(REF Map, phobos, sys, meta),
3808     you need to pass a template to be applied.
3809 
3810     See_Also:
3811         $(LREF ConstOf)
3812         $(LREF InoutOf)
3813         $(LREF SharedOf)
3814   +/
3815 alias ImmutableOf(T) = immutable T;
3816 
3817 ///
3818 @safe unittest
3819 {
3820     static assert(is(ImmutableOf!int == immutable int));
3821 
3822     // Note that immutable overrides const and inout.
3823     static assert(is(ImmutableOf!(const int) == immutable int));
3824     static assert(is(ImmutableOf!(inout int) == immutable int));
3825 
3826     // Note that immutable overrides shared, since immutable is implicitly
3827     // shared.
3828     static assert(is(ImmutableOf!(shared int) == immutable int));
3829 
3830     static assert(is(ImmutableOf!(immutable int) == immutable int));
3831 
3832     import phobos.sys.meta : AliasSeq, Map;
3833 
3834     alias Types = AliasSeq!(int, long,
3835                             bool*, ubyte[],
3836                             string, immutable(string));
3837     alias WithImmutable = Map!(ImmutableOf, Types);
3838     static assert(is(WithImmutable ==
3839                      AliasSeq!(immutable int, immutable long,
3840                                immutable(bool*), immutable(ubyte[]),
3841                                immutable(string), immutable(string))));
3842 }
3843 
3844 /++
3845     Applies $(D inout) to the given type.
3846 
3847     This is primarily useful in conjunction with templates that take a template
3848     predicate (such as many of the templates in phobos.sys.meta), since while in
3849     most cases, you can simply do $(D inout T) or $(D inout(T)) to make $(D T)
3850     $(D inout), with something like $(REF Map, phobos, sys, meta), you need to
3851     pass a template to be applied.
3852 
3853     See_Also:
3854         $(LREF ConstOf)
3855         $(LREF ImmutableOf)
3856         $(LREF SharedOf)
3857   +/
3858 alias InoutOf(T) = inout T;
3859 
3860 ///
3861 @safe unittest
3862 {
3863     static assert(is(InoutOf!int == inout int));
3864     static assert(is(InoutOf!(const int) == inout const int));
3865     static assert(is(InoutOf!(inout int) == inout int));
3866     static assert(is(InoutOf!(shared int) == inout shared int));
3867 
3868     // Note that inout has no effect on immutable.
3869     static assert(is(InoutOf!(immutable int) == immutable int));
3870 
3871     import phobos.sys.meta : AliasSeq, Map;
3872 
3873     alias Types = AliasSeq!(int, long,
3874                             bool*, ubyte[],
3875                             string, immutable(string));
3876     alias WithInout = Map!(InoutOf, Types);
3877     static assert(is(WithInout ==
3878                      AliasSeq!(inout int, inout long,
3879                                inout(bool*), inout(ubyte[]),
3880                                inout(string), immutable(string))));
3881 }
3882 
3883 /++
3884     Applies $(D shared) to the given type.
3885 
3886     This is primarily useful in conjunction with templates that take a template
3887     predicate (such as many of the templates in phobos.sys.meta), since while in
3888     most cases, you can simply do $(D shared T) or $(D shared(T)) to make $(D T)
3889     $(D shared), with something like $(REF Map, phobos, sys, meta), you need to
3890     pass a template to be applied.
3891 
3892     See_Also:
3893         $(LREF ConstOf)
3894         $(LREF ImmutableOf)
3895         $(LREF InoutOf)
3896   +/
3897 alias SharedOf(T) = shared T;
3898 
3899 ///
3900 @safe unittest
3901 {
3902     static assert(is(SharedOf!int == shared int));
3903     static assert(is(SharedOf!(const int) == const shared int));
3904     static assert(is(SharedOf!(inout int) == inout shared int));
3905     static assert(is(SharedOf!(shared int) == shared int));
3906 
3907     // Note that shared has no effect on immutable, since immutable is
3908     // implicitly shared.
3909     static assert(is(SharedOf!(immutable int) == immutable int));
3910 
3911     import phobos.sys.meta : AliasSeq, Map;
3912 
3913     alias Types = AliasSeq!(int, long,
3914                             bool*, ubyte[],
3915                             string, immutable(string));
3916     alias WithShared = Map!(SharedOf, Types);
3917     static assert(is(WithShared ==
3918                      AliasSeq!(shared int, shared long,
3919                                shared(bool*), shared(ubyte[]),
3920                                shared(string), immutable(string))));
3921 }
3922 
3923 // Needed for rvalueOf/lvalueOf because
3924 // "inout on return means inout must be on a parameter as well"
3925 private struct __InoutWorkaroundStruct {}
3926 
3927 /++
3928     Creates an lvalue or rvalue of type T to be used in conjunction with
3929     $(D is(typeof(...))) or
3930     $(DDSUBLINK spec/traits, compiles, $(D __traits(compiles, ...))).
3931 
3932     The idea is that some traits or other forms of conditional compilation need
3933     to verify that a particular piece of code compiles with an rvalue or an
3934     lvalue of a specific type, and these $(D @property) functions allow you to
3935     get an rvalue or lvalue of a specific type to use within an expression that
3936     is then tested to see whether it compiles.
3937 
3938     They're $(D @property) functions so that using $(D typeof) on them gives
3939     the return type rather than the type of the function.
3940 
3941     Note that these functions are $(I not) defined, so if they're actually used
3942     outside of type introspection, they'll result in linker errors. They're
3943     entirely for testing that a particular piece of code compiles with an rvalue
3944     or lvalue of the given type.
3945 
3946     The $(D __InoutWorkaroundStruct) parameter is entirely to make it so that
3947     these work when the given type has the $(D inout) qualifier, since the
3948     language requires that a function that returns an $(D inout) type also have
3949     an $(D inout) type as a parameter. It should just be ignored.
3950   +/
3951 @property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
3952 
3953 /++ Ditto +/
3954 @property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
3955 
3956 ///
3957 @safe unittest
3958 {
3959     static int foo(int);
3960     static assert(is(typeof(foo(lvalueOf!int)) == int));
3961     static assert(is(typeof(foo(rvalueOf!int)) == int));
3962 
3963     static bool bar(ref int);
3964     static assert(is(typeof(bar(lvalueOf!int)) == bool));
3965     static assert(!is(typeof(bar(rvalueOf!int))));
3966 
3967     static assert( is(typeof({ lvalueOf!int = 42; })));
3968     static assert(!is(typeof({ rvalueOf!int = 42; })));
3969 
3970     static struct S {}
3971     static assert( is(typeof({ lvalueOf!S = S.init; })));
3972     static assert(!is(typeof({ rvalueOf!S = S.init; })));
3973 
3974     static struct NoAssign
3975     {
3976         @disable void opAssign(ref NoAssign);
3977     }
3978     static assert(!is(typeof({ lvalueOf!NoAssign = NoAssign.init; })));
3979     static assert(!is(typeof({ rvalueOf!NoAssign = NoAssign.init; })));
3980 }
3981 
3982 @system unittest
3983 {
3984     import phobos.sys.meta : AliasSeq;
3985 
3986     void needLvalue(T)(ref T);
3987     static struct S {}
3988     int i;
3989     struct Nested { void f() { ++i; } }
3990 
3991     static foreach (T; AliasSeq!(int, const int, immutable int, inout int, string, S, Nested, Object))
3992     {
3993         static assert(!__traits(compiles, needLvalue(rvalueOf!T)));
3994         static assert( __traits(compiles, needLvalue(lvalueOf!T)));
3995         static assert(is(typeof(rvalueOf!T) == T));
3996         static assert(is(typeof(lvalueOf!T) == T));
3997     }
3998 
3999     static assert(!__traits(compiles, rvalueOf!int = 1));
4000     static assert( __traits(compiles, lvalueOf!byte = 127));
4001     static assert(!__traits(compiles, lvalueOf!byte = 128));
4002 }