1 /**
2  * $(SCRIPT inhibitQuickIndex = 1;)
3  * $(DIVC quickindex,
4  * $(BOOKTABLE,
5  * $(TR $(TH Category) $(TH Symbols))
6  * $(TR $(TD Arrays) $(TD
7  *     $(MYREF assumeSafeAppend)
8  *     $(MYREF capacity)
9  *     $(A #.dup.2, $(TT dup))
10  *     $(MYREF idup)
11  *     $(MYREF reserve)
12  * ))
13  * $(TR $(TD Associative arrays) $(TD
14  *     $(MYREF byKey)
15  *     $(MYREF byKeyValue)
16  *     $(MYREF byValue)
17  *     $(MYREF clear)
18  *     $(MYREF dup)
19  *     $(MYREF get)
20  *     $(MYREF keys)
21  *     $(MYREF rehash)
22  *     $(MYREF require)
23  *     $(MYREF update)
24  *     $(MYREF values)
25  * ))
26  * $(TR $(TD General) $(TD
27  *     $(MYREF destroy)
28  *     $(MYREF hashOf)
29  *     $(MYREF imported)
30  *     $(MYREF noreturn)
31  * ))
32  * $(TR $(TD Classes) $(TD
33  *     $(MYREF Error)
34  *     $(MYREF Exception)
35  *     $(MYREF Object)
36  *     $(MYREF opEquals)
37  *     $(MYREF Throwable)
38  * ))
39  * $(TR $(TD Type info) $(TD
40  *     $(MYREF Interface)
41  *     $(MYREF ModuleInfo)
42  *     $(MYREF OffsetTypeInfo)
43  *     $(MYREF RTInfoImpl)
44  *     $(MYREF rtinfoNoPointers)
45  *     $(MYREF TypeInfo)
46  *     $(MYREF TypeInfo_Class)
47  * ))
48  * ))
49  *
50  * Forms the symbols available to all D programs. Includes Object, which is
51  * the root of the class object hierarchy.  This module is implicitly
52  * imported.
53  *
54  * Copyright: Copyright Digital Mars 2000 - 2011.
55  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
56  * Authors:   Walter Bright, Sean Kelly
57  * Source: $(DRUNTIMESRC object.d)
58  */
59 
60 module object;
61 
62 alias size_t = typeof(int.sizeof);
63 alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0);
64 
65 alias sizediff_t = ptrdiff_t; // For backwards compatibility only.
66 /**
67  * Bottom type.
68  * See $(DDSUBLINK spec/type, noreturn).
69  */
70 alias noreturn = typeof(*null);
71 
72 alias hash_t = size_t; // For backwards compatibility only.
73 alias equals_t = bool; // For backwards compatibility only.
74 
75 alias string  = immutable(char)[];
76 alias wstring = immutable(wchar)[];
77 alias dstring = immutable(dchar)[];
78 
79 version (D_ObjectiveC)
80 {
81     deprecated("explicitly import `selector` instead using: `import core.attribute : selector;`")
82         public import core.attribute : selector;
83 }
84 version (Posix) public import core.attribute : gnuAbiTag;
85 
86 // Some ABIs use a complex varargs implementation requiring TypeInfo.argTypes().
87 version (GNU)
88 {
89     // No TypeInfo-based core.vararg.va_arg().
90 }
91 else version (X86_64)
92 {
93     version (DigitalMars) version = WithArgTypes;
94     else version (Windows) { /* no need for Win64 ABI */ }
95     else version = WithArgTypes;
96 }
97 else version (AArch64)
98 {
99     // Apple uses a trivial varargs implementation
100     version (OSX) {}
101     else version (iOS) {}
102     else version (TVOS) {}
103     else version (WatchOS) {}
104     else version = WithArgTypes;
105 }
106 
107 /**
108  * All D class objects inherit from Object.
109  */
110 class Object
111 {
112     /**
113      * Convert Object to a human readable string.
114      */
115     string toString()
116     {
117         return typeid(this).name;
118     }
119 
120     @system unittest
121     {
122         enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
123         enum fqn_unittest = "object.Object." ~ unittest_sym_name; // object.__unittest_LX_CY
124 
125         class C {}
126 
127         Object obj = new Object;
128         C c = new C;
129 
130         assert(obj.toString() == "object.Object");
131         assert(c.toString() == fqn_unittest ~ ".C");
132     }
133 
134     /**
135      * Compute hash function for Object.
136      */
137     size_t toHash() @trusted nothrow
138     {
139         // BUG: this prevents a compacting GC from working, needs to be fixed
140         size_t addr = cast(size_t) cast(void*) this;
141         // The bottom log2((void*).alignof) bits of the address will always
142         // be 0. Moreover it is likely that each Object is allocated with a
143         // separate call to malloc. The alignment of malloc differs from
144         // platform to platform, but rather than having special cases for
145         // each platform it is safe to use a shift of 4. To minimize
146         // collisions in the low bits it is more important for the shift to
147         // not be too small than for the shift to not be too big.
148         return addr ^ (addr >>> 4);
149     }
150 
151     /**
152      * Compare with another Object obj.
153      * Returns:
154      *  $(TABLE
155      *  $(TR $(TD this < obj) $(TD < 0))
156      *  $(TR $(TD this == obj) $(TD 0))
157      *  $(TR $(TD this > obj) $(TD > 0))
158      *  )
159      */
160     int opCmp(Object o)
161     {
162         // BUG: this prevents a compacting GC from working, needs to be fixed
163         //return cast(int)cast(void*)this - cast(int)cast(void*)o;
164 
165         throw new Exception("need opCmp for class " ~ typeid(this).name);
166         //return this !is o;
167     }
168 
169     @system unittest
170     {
171         Object obj = new Object;
172 
173         bool gotCaught;
174         try
175         {
176             obj.opCmp(new Object);
177         }
178         catch (Exception e)
179         {
180             gotCaught = true;
181             assert(e.msg == "need opCmp for class object.Object");
182         }
183         assert(gotCaught);
184     }
185 
186     /**
187      * Test whether $(D this) is equal to $(D o).
188      * The default implementation only compares by identity (using the $(D is) operator).
189      * Generally, overrides and overloads for $(D opEquals) should attempt to compare objects by their contents.
190      * A class will most likely want to add an overload that takes your specific type as the argument
191      * and does the content comparison. Then you can override this and forward it to your specific
192      * typed overload with a cast. Remember to check for `null` on the typed overload.
193      *
194      * Examples:
195      * ---
196      * class Child {
197      *    int contents;
198      *    // the typed overload first. It can use all the attribute you want
199      *    bool opEquals(const Child c) const @safe pure nothrow @nogc
200      *    {
201      *        if (c is null)
202      *            return false;
203      *        return this.contents == c.contents;
204      *    }
205      *
206      *    // and now the generic override forwards with a cast
207      *    override bool opEquals(Object o)
208      *    {
209      *        return this.opEquals(cast(Child) o);
210      *    }
211      * }
212      * ---
213      */
214     bool opEquals(Object o)
215     {
216         return this is o;
217     }
218 
219     interface Monitor
220     {
221         void lock();
222         void unlock();
223     }
224 
225     /**
226      * Create instance of class specified by the fully qualified name
227      * classname.
228      * The class must either have no constructors or have
229      * a default constructor.
230      * Returns:
231      *   null if failed
232      * Example:
233      * ---
234      * module foo.bar;
235      *
236      * class C
237      * {
238      *     this() { x = 10; }
239      *     int x;
240      * }
241      *
242      * void main()
243      * {
244      *     auto c = cast(C)Object.factory("foo.bar.C");
245      *     assert(c !is null && c.x == 10);
246      * }
247      * ---
248      */
249     static Object factory(string classname)
250     {
251         auto ci = TypeInfo_Class.find(classname);
252         if (ci)
253         {
254             return ci.create();
255         }
256         return null;
257     }
258 
259     @system unittest
260     {
261         Object valid_obj = Object.factory("object.Object");
262         Object invalid_obj = Object.factory("object.__this_class_doesnt_exist__");
263 
264         assert(valid_obj !is null);
265         assert(invalid_obj is null);
266     }
267 }
268 
269 /++
270     Implementation for class opEquals override. Calls the class-defined methods after a null check.
271     Please note this is not nogc right now, even if your implementation is, because of
272     the typeinfo name string compare. This is because of dmd's dll implementation. However,
273     it can infer to @safe if your class' opEquals is.
274 +/
275 bool opEquals(LHS, RHS)(LHS lhs, RHS rhs)
276 if ((is(LHS : const Object) || is(LHS : const shared Object)) &&
277     (is(RHS : const Object) || is(RHS : const shared Object)))
278 {
279     static if (__traits(compiles, lhs.opEquals(rhs)) && __traits(compiles, rhs.opEquals(lhs)))
280     {
281         // If aliased to the same object or both null => equal
282         if (lhs is rhs) return true;
283 
284         // If either is null => non-equal
285         if (lhs is null || rhs is null) return false;
286 
287         if (!lhs.opEquals(rhs)) return false;
288 
289         // If same exact type => one call to method opEquals
290         if (typeid(lhs) is typeid(rhs) ||
291             !__ctfe && typeid(lhs).opEquals(typeid(rhs)))
292                 /* CTFE doesn't like typeid much. 'is' works, but opEquals doesn't
293                 (issue 7147). But CTFE also guarantees that equal TypeInfos are
294                 always identical. So, no opEquals needed during CTFE. */
295         {
296             return true;
297         }
298 
299         // General case => symmetric calls to method opEquals
300         return rhs.opEquals(lhs);
301     }
302     else
303     {
304         // this is a compatibility hack for the old const cast behavior
305         // if none of the new overloads compile, we'll go back plain Object,
306         // including casting away const. It does this through the pointer
307         // to bypass any opCast that may be present on the original class.
308         return .opEquals!(Object, Object)(*cast(Object*) &lhs, *cast(Object*) &rhs);
309 
310     }
311 }
312 
313 /// If aliased to the same object or both null => equal
314 @system unittest // this one is not @safe because it goes through the Object base method
315 {
316     class F { int flag; this(int flag) { this.flag = flag; } }
317 
318     F f;
319     assert(f == f); // both null
320     f = new F(1);
321     assert(f == f); // both aliased to the same object
322 }
323 
324 /// If either is null => non-equal
325 @system unittest
326 {
327     class F { int flag; this(int flag) { this.flag = flag; } }
328     F f;
329     assert(!(new F(0) == f));
330     assert(!(f == new F(0)));
331 }
332 
333 /// If same exact type => one call to method opEquals
334 /// This test passes `@safe` because it defines a new opEquals with `@safe`
335 @safe unittest
336 {
337     class F
338     {
339         int flag;
340 
341         this(int flag)
342         {
343             this.flag = flag;
344         }
345 
346         bool opEquals(const F o) const @safe nothrow pure
347         {
348             return flag == o.flag;
349         }
350     }
351 
352     F f;
353     assert(new F(0) == new F(0));
354     assert(!(new F(0) == new F(1)));
355 }
356 
357 /// General case => symmetric calls to method opEquals
358 @safe unittest
359 {
360     int fEquals, gEquals;
361 
362     class Base
363     {
364         int flag;
365         this(int flag)
366         {
367             this.flag = flag;
368         }
369     }
370 
371     class F : Base
372     {
373         this(int flag) { super(flag); }
374 
375         bool opEquals(const Base o) @safe
376         {
377             fEquals++;
378             return flag == o.flag;
379         }
380     }
381 
382     class G : Base
383     {
384         this(int flag) { super(flag); }
385 
386         bool opEquals(const Base o) @safe
387         {
388             gEquals++;
389             return flag == o.flag;
390         }
391     }
392 
393     assert(new F(1) == new G(1));
394     assert(fEquals == 1);
395     assert(gEquals == 1);
396 }
397 
398 /++
399     This test shows an example for a comprehensive inheritance equality chain too.
400 +/
401 unittest
402 {
403     static class Base
404     {
405         int member;
406 
407         this(int member) pure @safe nothrow @nogc
408         {
409             this.member = member;
410         }
411 
412         override bool opEquals(Object rhs) const
413         {
414             return this.opEquals(cast(Base) rhs);
415         }
416 
417         bool opEquals(const Base rhs) const @nogc pure nothrow @safe
418         {
419             if (rhs is null)
420                 return false;
421             return this.member == rhs.member;
422         }
423     }
424 
425     // works through the direct class with attributes enabled, except for pure and nogc in the current TypeInfo implementation
426     bool testThroughBase() nothrow @safe
427     {
428         Base b1 = new Base(0);
429         Base b2 = new Base(0);
430         assert(b1 == b2);
431         Base b3 = new Base(1);
432         assert(b1 != b3);
433         return true;
434     }
435 
436     static assert(testThroughBase());
437 
438     // also works through the base class interface thanks to the override, but no more attributes
439     bool testThroughObject()
440     {
441         Object o1 = new Base(0);
442         Object o2 = new Base(0);
443         assert(o1 == o2);
444         Object o3 = new Base(1);
445         assert(o1 != o3);
446         return true;
447     }
448 
449     static assert(testThroughObject());
450 
451     // Each time you make a child, you want to override all old opEquals
452     // and add a new overload for the new child.
453     static class Child : Base
454     {
455         int member2;
456 
457         this(int member, int member2) pure @safe nothrow @nogc
458         {
459             super(member);
460             this.member2 = member2;
461         }
462 
463         // override the whole chain so it works consistently though any base
464         override bool opEquals(Object rhs) const
465         {
466             return this.opEquals(cast(Child) rhs);
467         }
468         override bool opEquals(const Base rhs) const
469         {
470             return this.opEquals(cast(const Child) rhs);
471         }
472         // and then add the new overload, if necessary, to handle new members
473         bool opEquals(const Child rhs) const @nogc pure nothrow @safe
474         {
475             if (rhs is null)
476                 return false;
477             // can call back to the devirtualized base test with implicit conversion
478             // then compare the new member too. or we could have just compared the base
479             // member directly here as well.
480             return Base.opEquals(rhs) && this.member2 == rhs.member2;
481         }
482 
483         // a mixin template, of course, could automate this.
484     }
485 
486     bool testThroughChild()
487     {
488         Child a = new Child(0, 0);
489         Child b = new Child(0, 1);
490         assert(a != b);
491 
492         Base ba = a;
493         Base bb = b;
494         assert(ba != bb);
495 
496         Object oa = a;
497         Object ob = b;
498         assert(oa != ob);
499 
500         return true;
501     }
502 
503     static assert(testThroughChild());
504 }
505 
506 // To cover const Object opEquals
507 @system unittest
508 {
509     const Object obj1 = new Object;
510     const Object obj2 = new Object;
511 
512     assert(obj1 == obj1);
513     assert(obj1 != obj2);
514 }
515 
516 // https://issues.dlang.org/show_bug.cgi?id=23291
517 @system unittest
518 {
519     static shared class C { bool opEquals(const(shared(C)) rhs) const shared  { return true;}}
520     const(C) c = new C();
521     const(C)[] a = [c];
522     const(C)[] b = [c];
523     assert(a[0] == b[0]);
524 }
525 
526 private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow;
527 
528 void setSameMutex(shared Object ownee, shared Object owner)
529 {
530     _d_setSameMutex(ownee, owner);
531 }
532 
533 @system unittest
534 {
535     shared Object obj1 = new Object;
536     synchronized class C
537     {
538         void bar() {}
539     }
540     shared C obj2 = new shared(C);
541     obj2.bar();
542 
543     assert(obj1.__monitor != obj2.__monitor);
544     assert(obj1.__monitor is null);
545 
546     setSameMutex(obj1, obj2);
547     assert(obj1.__monitor == obj2.__monitor);
548     assert(obj1.__monitor !is null);
549 }
550 
551 /**
552  * Information about an interface.
553  * When an object is accessed via an interface, an Interface* appears as the
554  * first entry in its vtbl.
555  */
556 struct Interface
557 {
558     /// Class info returned by `typeid` for this interface (not for containing class)
559     TypeInfo_Class   classinfo;
560     void*[]     vtbl;
561     size_t      offset;     /// offset to Interface 'this' from Object 'this'
562 }
563 
564 /**
565  * Array of pairs giving the offset and type information for each
566  * member in an aggregate.
567  */
568 struct OffsetTypeInfo
569 {
570     size_t   offset;    /// Offset of member from start of object
571     TypeInfo ti;        /// TypeInfo for this member
572 }
573 
574 /**
575  * Runtime type information about a type.
576  * Can be retrieved for any type using a
577  * $(GLINK2 expression,TypeidExpression, TypeidExpression).
578  */
579 class TypeInfo
580 {
581     override string toString() const @safe nothrow
582     {
583         return typeid(this).name;
584     }
585 
586     override size_t toHash() @trusted const nothrow
587     {
588         return hashOf(this.toString());
589     }
590 
591     override int opCmp(Object rhs)
592     {
593         if (this is rhs)
594             return 0;
595         auto ti = cast(TypeInfo) rhs;
596         if (ti is null)
597             return 1;
598         return __cmp(this.toString(), ti.toString());
599     }
600 
601     @system unittest
602     {
603         assert(typeid(void) <= typeid(void));
604         assert(typeid(void).opCmp(null));
605         assert(!typeid(void).opCmp(typeid(void)));
606     }
607 
608     override bool opEquals(Object o)
609     {
610         return opEquals(cast(TypeInfo) o);
611     }
612 
613     bool opEquals(const TypeInfo ti) @safe nothrow const
614     {
615         /* TypeInfo instances are singletons, but duplicates can exist
616          * across DLL's. Therefore, comparing for a name match is
617          * sufficient.
618          */
619         if (this is ti)
620             return true;
621         return ti && this.toString() == ti.toString();
622     }
623 
624     @system unittest
625     {
626         auto anotherObj = new Object();
627 
628         assert(typeid(void).opEquals(typeid(void)));
629         assert(typeid(void) != anotherObj); // calling .opEquals here directly is a type mismatch
630     }
631 
632     /**
633      * Computes a hash of the instance of a type.
634      * Params:
635      *    p = pointer to start of instance of the type
636      * Returns:
637      *    the hash
638      * Bugs:
639      *    fix https://issues.dlang.org/show_bug.cgi?id=12516 e.g. by changing this to a truly safe interface.
640      */
641     size_t getHash(scope const void* p) @trusted nothrow const
642     {
643         return hashOf(p);
644     }
645 
646     /// Compares two instances for equality.
647     bool equals(in void* p1, in void* p2) const { return p1 == p2; }
648 
649     /// Compares two instances for &lt;, ==, or &gt;.
650     int compare(in void* p1, in void* p2) const { return _xopCmp(p1, p2); }
651 
652     /// Returns size of the type.
653     @property size_t tsize() nothrow pure const @safe @nogc { return 0; }
654 
655     /// Swaps two instances of the type.
656     void swap(void* p1, void* p2) const
657     {
658         size_t remaining = tsize;
659         // If the type might contain pointers perform the swap in pointer-sized
660         // chunks in case a garbage collection pass interrupts this function.
661         if ((cast(size_t) p1 | cast(size_t) p2) % (void*).alignof == 0)
662         {
663             while (remaining >= (void*).sizeof)
664             {
665                 void* tmp = *cast(void**) p1;
666                 *cast(void**) p1 = *cast(void**) p2;
667                 *cast(void**) p2 = tmp;
668                 p1 += (void*).sizeof;
669                 p2 += (void*).sizeof;
670                 remaining -= (void*).sizeof;
671             }
672         }
673         for (size_t i = 0; i < remaining; i++)
674         {
675             byte t = (cast(byte *)p1)[i];
676             (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
677             (cast(byte*)p2)[i] = t;
678         }
679     }
680 
681     @system unittest
682     {
683         class _TypeInfo_Dummy : TypeInfo
684         {
685             override const(void)[] initializer() const { return []; }
686             @property override size_t tsize() nothrow pure const @safe @nogc { return tsize_val; }
687 
688             size_t tsize_val;
689         }
690         auto dummy = new _TypeInfo_Dummy();
691         cast(void)dummy.initializer(); // For coverage completeness
692 
693         int a = 2, b = -2;
694         dummy.swap(&a, &b);
695         // does nothing because tsize is 0
696         assert(a == 2);
697         assert(b == -2);
698 
699         dummy.tsize_val = int.sizeof;
700         dummy.swap(&a, &b);
701         assert(a == -2);
702         assert(b == 2);
703 
704         void* ptr_a = null, ptr_b = cast(void*)1;
705         dummy.tsize_val = (void*).sizeof;
706         dummy.swap(&ptr_a, &ptr_b);
707         assert(ptr_a is cast(void*)1);
708         assert(ptr_b is null);
709     }
710 
711     /** Get TypeInfo for 'next' type, as defined by what kind of type this is,
712     null if none. */
713     @property inout(TypeInfo) next() nothrow pure inout @nogc { return null; }
714 
715     /**
716      * Return default initializer.  If the type should be initialized to all
717      * zeros, an array with a null ptr and a length equal to the type size will
718      * be returned. For static arrays, this returns the default initializer for
719      * a single element of the array, use `tsize` to get the correct size.
720      */
721     abstract const(void)[] initializer() nothrow pure const @safe @nogc;
722 
723     /** Get flags for type: 1 means GC should scan for pointers,
724     2 means arg of this type is passed in SIMD register(s) if available */
725     @property uint flags() nothrow pure const @safe @nogc { return 0; }
726 
727     /// Get type information on the contents of the type; null if not available
728     const(OffsetTypeInfo)[] offTi() const { return null; }
729     /// Run the destructor on the object and all its sub-objects
730     void destroy(void* p) const {}
731     /// Run the postblit on the object and all its sub-objects
732     void postblit(void* p) const {}
733 
734 
735     /// Return alignment of type
736     @property size_t talign() nothrow pure const @safe @nogc { return tsize; }
737 
738     /** Return internal info on arguments fitting into 8byte.
739      * See X86-64 ABI 3.2.3
740      */
741     version (WithArgTypes) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow
742     {
743         arg1 = this;
744         return 0;
745     }
746 
747     /** Return info used by the garbage collector to do precise collection.
748      */
749     @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return rtinfoHasPointers; } // better safe than sorry
750 }
751 
752 @system unittest
753 {
754     class _TypeInfo_Dummy : TypeInfo
755     {
756         override const(void)[] initializer() const { return []; }
757     }
758     auto dummy = new _TypeInfo_Dummy();
759     cast(void)dummy.initializer(); // For coverage completeness
760 
761     assert(dummy.rtInfo() is rtinfoHasPointers);
762     assert(typeid(void).rtInfo() is rtinfoNoPointers);
763 
764     assert(dummy.tsize() == 0);
765 
766     bool gotCaught;
767     try
768     {
769         dummy.compare(null, null);
770     } catch (Error e)
771     {
772         gotCaught = true;
773         assert(e.msg == "TypeInfo.compare is not implemented");
774     }
775     assert(gotCaught);
776 
777     assert(dummy.equals(null, null));
778     assert(!dummy.equals(cast(void*)1, null));
779 }
780 
781 @system unittest
782 {
783     assert(typeid(void).next() is null);
784     assert(typeid(void).offTi() is null);
785     assert(typeid(void).tsize() == 1);
786 
787     version (WithArgTypes)
788     {
789         TypeInfo ti1;
790         TypeInfo ti2;
791         assert(typeid(void).argTypes(ti1, ti2) == 0);
792         assert(typeid(void) is ti1);
793 
794         assert(ti1 !is null);
795         assert(ti2 is null);
796     }
797 }
798 
799 @system unittest
800 {
801     class _ZypeInfo_Dummy : TypeInfo
802     {
803         override const(void)[] initializer() const { return []; }
804     }
805     auto dummy2 = new _ZypeInfo_Dummy();
806     cast(void)dummy2.initializer(); // For coverage completeness
807 
808     assert(typeid(void) > dummy2);
809     assert(dummy2 < typeid(void));
810 }
811 
812 @safe unittest
813 {
814     enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
815     enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
816 
817     class _TypeInfo_Dummy : TypeInfo
818     {
819         override const(void)[] initializer() const { return []; }
820     }
821 
822     auto dummy = new _TypeInfo_Dummy();
823     cast(void)dummy.initializer(); // For coverage completeness
824 
825     assert(dummy.toString() == fqn_unittest ~ "._TypeInfo_Dummy");
826     assert(dummy.toHash() == hashOf(dummy.toString()));
827     assert(dummy.getHash(null) == 0);
828 }
829 
830 class TypeInfo_Enum : TypeInfo
831 {
832     override string toString() const pure { return name; }
833 
834     override bool opEquals(Object o)
835     {
836         if (this is o)
837             return true;
838         auto c = cast(const TypeInfo_Enum)o;
839         return c && this.name == c.name &&
840                     this.base == c.base;
841     }
842 
843     @system unittest
844     {
845         enum E { A, B, C }
846         enum EE { A, B, C }
847 
848         assert(typeid(E).opEquals(typeid(E)));
849         assert(!typeid(E).opEquals(typeid(EE)));
850     }
851 
852     override size_t getHash(scope const void* p) const { return base.getHash(p); }
853 
854     @system unittest
855     {
856         enum E { A, B, C }
857         E e1 = E.A;
858         E e2 = E.B;
859 
860         assert(typeid(E).getHash(&e1) == hashOf(E.A));
861         assert(typeid(E).getHash(&e2) == hashOf(E.B));
862 
863         enum ES : string { A = "foo", B = "bar" }
864         ES es1 = ES.A;
865         ES es2 = ES.B;
866 
867         assert(typeid(ES).getHash(&es1) == hashOf("foo"));
868         assert(typeid(ES).getHash(&es2) == hashOf("bar"));
869     }
870 
871     override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
872 
873     @system unittest
874     {
875         enum E { A, B, C }
876 
877         E e1 = E.A;
878         E e2 = E.B;
879 
880         assert(typeid(E).equals(&e1, &e1));
881         assert(!typeid(E).equals(&e1, &e2));
882     }
883 
884     override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
885 
886     @system unittest
887     {
888         enum E { A, B, C }
889 
890         E e1 = E.A;
891         E e2 = E.B;
892 
893         assert(typeid(E).compare(&e1, &e1) == 0);
894         assert(typeid(E).compare(&e1, &e2) < 0);
895         assert(typeid(E).compare(&e2, &e1) > 0);
896     }
897 
898     override @property size_t tsize() nothrow pure const { return base.tsize; }
899 
900     @safe unittest
901     {
902         enum E { A, B, C }
903         enum ES : string { A = "a", B = "b", C = "c"}
904 
905         assert(typeid(E).tsize == E.sizeof);
906         assert(typeid(ES).tsize == ES.sizeof);
907         assert(typeid(E).tsize != ES.sizeof);
908     }
909 
910     override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
911 
912     @system unittest
913     {
914         enum E { A, B, C }
915 
916         E e1 = E.A;
917         E e2 = E.B;
918 
919         typeid(E).swap(&e1, &e2);
920         assert(e1 == E.B);
921         assert(e2 == E.A);
922     }
923 
924     override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
925 
926     @system unittest
927     {
928         enum E { A, B, C }
929 
930         assert(typeid(E).next is null);
931     }
932 
933     override @property uint flags() nothrow pure const { return base.flags; }
934 
935     @safe unittest
936     {
937         enum E { A, B, C }
938 
939         assert(typeid(E).flags == 0);
940     }
941 
942     override const(OffsetTypeInfo)[] offTi() const { return base.offTi; }
943 
944     @system unittest
945     {
946         enum E { A, B, C }
947 
948         assert(typeid(E).offTi is null);
949     }
950 
951     override void destroy(void* p) const { return base.destroy(p); }
952     override void postblit(void* p) const { return base.postblit(p); }
953 
954     override const(void)[] initializer() const
955     {
956         return m_init.length ? m_init : base.initializer();
957     }
958 
959     override @property size_t talign() nothrow pure const { return base.talign; }
960 
961     version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
962     {
963         return base.argTypes(arg1, arg2);
964     }
965 
966     override @property immutable(void)* rtInfo() const { return base.rtInfo; }
967 
968     TypeInfo base;
969     string   name;
970     void[]   m_init;
971 }
972 
973 @safe unittest
974 {
975     enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
976     enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
977 
978     enum E { A, B, C }
979     enum EE { A, B, C }
980 
981     assert(typeid(E).toString() == fqn_unittest ~ ".E");
982 }
983 
984 
985 @safe unittest // issue 12233
986 {
987     static assert(is(typeof(TypeInfo.init) == TypeInfo));
988     assert(TypeInfo.init is null);
989 }
990 
991 
992 // Please make sure to keep this in sync with TypeInfo_P (src/rt/typeinfo/ti_ptr.d)
993 class TypeInfo_Pointer : TypeInfo
994 {
995     override string toString() const { return m_next.toString() ~ "*"; }
996 
997     override bool opEquals(Object o)
998     {
999         if (this is o)
1000             return true;
1001         auto c = cast(const TypeInfo_Pointer)o;
1002         return c && this.m_next == c.m_next;
1003     }
1004 
1005     override size_t getHash(scope const void* p) @trusted const
1006     {
1007         size_t addr = cast(size_t) *cast(const void**)p;
1008         return addr ^ (addr >> 4);
1009     }
1010 
1011     override bool equals(in void* p1, in void* p2) const
1012     {
1013         return *cast(void**)p1 == *cast(void**)p2;
1014     }
1015 
1016     override int compare(in void* p1, in void* p2) const
1017     {
1018         const v1 = *cast(void**) p1, v2 = *cast(void**) p2;
1019         return (v1 > v2) - (v1 < v2);
1020     }
1021 
1022     override @property size_t tsize() nothrow pure const
1023     {
1024         return (void*).sizeof;
1025     }
1026 
1027     override const(void)[] initializer() const @trusted
1028     {
1029         return (cast(void *)null)[0 .. (void*).sizeof];
1030     }
1031 
1032     override void swap(void* p1, void* p2) const
1033     {
1034         void* tmp = *cast(void**)p1;
1035         *cast(void**)p1 = *cast(void**)p2;
1036         *cast(void**)p2 = tmp;
1037     }
1038 
1039     override @property inout(TypeInfo) next() nothrow pure inout { return m_next; }
1040     override @property uint flags() nothrow pure const { return 1; }
1041 
1042     TypeInfo m_next;
1043 }
1044 
1045 class TypeInfo_Array : TypeInfo
1046 {
1047     override string toString() const { return value.toString() ~ "[]"; }
1048 
1049     override bool opEquals(Object o)
1050     {
1051         if (this is o)
1052             return true;
1053         auto c = cast(const TypeInfo_Array)o;
1054         return c && this.value == c.value;
1055     }
1056 
1057     override size_t getHash(scope const void* p) @trusted const
1058     {
1059         void[] a = *cast(void[]*)p;
1060         return getArrayHash(value, a.ptr, a.length);
1061     }
1062 
1063     override bool equals(in void* p1, in void* p2) const
1064     {
1065         void[] a1 = *cast(void[]*)p1;
1066         void[] a2 = *cast(void[]*)p2;
1067         if (a1.length != a2.length)
1068             return false;
1069         size_t sz = value.tsize;
1070         for (size_t i = 0; i < a1.length; i++)
1071         {
1072             if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))
1073                 return false;
1074         }
1075         return true;
1076     }
1077 
1078     override int compare(in void* p1, in void* p2) const
1079     {
1080         void[] a1 = *cast(void[]*)p1;
1081         void[] a2 = *cast(void[]*)p2;
1082         size_t sz = value.tsize;
1083         size_t len = a1.length;
1084 
1085         if (a2.length < len)
1086             len = a2.length;
1087         for (size_t u = 0; u < len; u++)
1088         {
1089             immutable int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
1090             if (result)
1091                 return result;
1092         }
1093         return (a1.length > a2.length) - (a1.length < a2.length);
1094     }
1095 
1096     override @property size_t tsize() nothrow pure const
1097     {
1098         return (void[]).sizeof;
1099     }
1100 
1101     override const(void)[] initializer() const @trusted
1102     {
1103         return (cast(void *)null)[0 .. (void[]).sizeof];
1104     }
1105 
1106     override void swap(void* p1, void* p2) const
1107     {
1108         void[] tmp = *cast(void[]*)p1;
1109         *cast(void[]*)p1 = *cast(void[]*)p2;
1110         *cast(void[]*)p2 = tmp;
1111     }
1112 
1113     TypeInfo value;
1114 
1115     override @property inout(TypeInfo) next() nothrow pure inout
1116     {
1117         return value;
1118     }
1119 
1120     override @property uint flags() nothrow pure const { return 1; }
1121 
1122     override @property size_t talign() nothrow pure const
1123     {
1124         return (void[]).alignof;
1125     }
1126 
1127     version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1128     {
1129         arg1 = typeid(size_t);
1130         arg2 = typeid(void*);
1131         return 0;
1132     }
1133 
1134     override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(void[]); }
1135 }
1136 
1137 class TypeInfo_StaticArray : TypeInfo
1138 {
1139     override string toString() const
1140     {
1141         import core.internal.string : unsignedToTempString;
1142 
1143         char[20] tmpBuff = void;
1144         const lenString = unsignedToTempString(len, tmpBuff);
1145 
1146         return (() @trusted => cast(string) (value.toString() ~ "[" ~ lenString ~ "]"))();
1147     }
1148 
1149     override bool opEquals(Object o)
1150     {
1151         if (this is o)
1152             return true;
1153         auto c = cast(const TypeInfo_StaticArray)o;
1154         return c && this.len == c.len &&
1155                     this.value == c.value;
1156     }
1157 
1158     override size_t getHash(scope const void* p) @trusted const
1159     {
1160         return getArrayHash(value, p, len);
1161     }
1162 
1163     override bool equals(in void* p1, in void* p2) const
1164     {
1165         size_t sz = value.tsize;
1166 
1167         for (size_t u = 0; u < len; u++)
1168         {
1169             if (!value.equals(p1 + u * sz, p2 + u * sz))
1170                 return false;
1171         }
1172         return true;
1173     }
1174 
1175     override int compare(in void* p1, in void* p2) const
1176     {
1177         size_t sz = value.tsize;
1178 
1179         for (size_t u = 0; u < len; u++)
1180         {
1181             immutable int result = value.compare(p1 + u * sz, p2 + u * sz);
1182             if (result)
1183                 return result;
1184         }
1185         return 0;
1186     }
1187 
1188     override @property size_t tsize() nothrow pure const
1189     {
1190         return len * value.tsize;
1191     }
1192 
1193     override void swap(void* p1, void* p2) const
1194     {
1195         import core.stdc.string : memcpy;
1196 
1197         size_t remaining = value.tsize * len;
1198         void[size_t.sizeof * 4] buffer = void;
1199         while (remaining > buffer.length)
1200         {
1201             memcpy(buffer.ptr, p1, buffer.length);
1202             memcpy(p1, p2, buffer.length);
1203             memcpy(p2, buffer.ptr, buffer.length);
1204             p1 += buffer.length;
1205             p2 += buffer.length;
1206             remaining -= buffer.length;
1207         }
1208         memcpy(buffer.ptr, p1, remaining);
1209         memcpy(p1, p2, remaining);
1210         memcpy(p2, buffer.ptr, remaining);
1211     }
1212 
1213     override const(void)[] initializer() nothrow pure const
1214     {
1215         return value.initializer();
1216     }
1217 
1218     override @property inout(TypeInfo) next() nothrow pure inout { return value; }
1219     override @property uint flags() nothrow pure const { return value.flags; }
1220 
1221     override void destroy(void* p) const
1222     {
1223         immutable sz = value.tsize;
1224         p += sz * len;
1225         foreach (i; 0 .. len)
1226         {
1227             p -= sz;
1228             value.destroy(p);
1229         }
1230     }
1231 
1232     override void postblit(void* p) const
1233     {
1234         immutable sz = value.tsize;
1235         foreach (i; 0 .. len)
1236         {
1237             value.postblit(p);
1238             p += sz;
1239         }
1240     }
1241 
1242     TypeInfo value;
1243     size_t   len;
1244 
1245     override @property size_t talign() nothrow pure const
1246     {
1247         return value.talign;
1248     }
1249 
1250     version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1251     {
1252         arg1 = typeid(void*);
1253         return 0;
1254     }
1255 
1256     // just return the rtInfo of the element, we have no generic type T to run RTInfo!T on
1257     override @property immutable(void)* rtInfo() nothrow pure const @safe { return value.rtInfo(); }
1258 }
1259 
1260 // https://issues.dlang.org/show_bug.cgi?id=21315
1261 @system unittest
1262 {
1263     int[16] a, b;
1264     foreach (int i; 0 .. 16)
1265     {
1266         a[i] = i;
1267         b[i] = ~i;
1268     }
1269     typeid(int[16]).swap(&a, &b);
1270     foreach (int i; 0 .. 16)
1271     {
1272         assert(a[i] == ~i);
1273         assert(b[i] == i);
1274     }
1275 }
1276 
1277 class TypeInfo_AssociativeArray : TypeInfo
1278 {
1279     override string toString() const
1280     {
1281         return value.toString() ~ "[" ~ key.toString() ~ "]";
1282     }
1283 
1284     override bool opEquals(Object o)
1285     {
1286         if (this is o)
1287             return true;
1288         auto c = cast(const TypeInfo_AssociativeArray)o;
1289         return c && this.key == c.key &&
1290                     this.value == c.value;
1291     }
1292 
1293     override bool equals(in void* p1, in void* p2) @trusted const
1294     {
1295         return !!_aaEqual(this, *cast(const AA*) p1, *cast(const AA*) p2);
1296     }
1297 
1298     override hash_t getHash(scope const void* p) nothrow @trusted const
1299     {
1300         return _aaGetHash(cast(AA*)p, this);
1301     }
1302 
1303     // BUG: need to add the rest of the functions
1304 
1305     override @property size_t tsize() nothrow pure const
1306     {
1307         return (char[int]).sizeof;
1308     }
1309 
1310     override const(void)[] initializer() const @trusted
1311     {
1312         return (cast(void *)null)[0 .. (char[int]).sizeof];
1313     }
1314 
1315     override @property inout(TypeInfo) next() nothrow pure inout { return value; }
1316     override @property uint flags() nothrow pure const { return 1; }
1317 
1318     TypeInfo value;
1319     TypeInfo key;
1320 
1321     override @property size_t talign() nothrow pure const
1322     {
1323         return (char[int]).alignof;
1324     }
1325 
1326     version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1327     {
1328         arg1 = typeid(void*);
1329         return 0;
1330     }
1331 }
1332 
1333 class TypeInfo_Vector : TypeInfo
1334 {
1335     override string toString() const { return "__vector(" ~ base.toString() ~ ")"; }
1336 
1337     override bool opEquals(Object o)
1338     {
1339         if (this is o)
1340             return true;
1341         auto c = cast(const TypeInfo_Vector)o;
1342         return c && this.base == c.base;
1343     }
1344 
1345     override size_t getHash(scope const void* p) const { return base.getHash(p); }
1346     override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
1347     override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
1348     override @property size_t tsize() nothrow pure const { return base.tsize; }
1349     override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
1350 
1351     override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
1352     override @property uint flags() nothrow pure const { return 2; /* passed in SIMD register */ }
1353 
1354     override const(void)[] initializer() nothrow pure const
1355     {
1356         return base.initializer();
1357     }
1358 
1359     override @property size_t talign() nothrow pure const { return 16; }
1360 
1361     version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1362     {
1363         return base.argTypes(arg1, arg2);
1364     }
1365 
1366     TypeInfo base;
1367 }
1368 
1369 class TypeInfo_Function : TypeInfo
1370 {
1371     override string toString() const pure @trusted
1372     {
1373         import core.demangle : demangleType;
1374 
1375         alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;
1376         SafeDemangleFunctionType demangle = cast(SafeDemangleFunctionType) &demangleType;
1377 
1378         return cast(string) demangle(deco);
1379     }
1380 
1381     override bool opEquals(Object o)
1382     {
1383         if (this is o)
1384             return true;
1385         auto c = cast(const TypeInfo_Function)o;
1386         return c && this.deco == c.deco;
1387     }
1388 
1389     // BUG: need to add the rest of the functions
1390 
1391     override @property size_t tsize() nothrow pure const
1392     {
1393         return 0;       // no size for functions
1394     }
1395 
1396     override const(void)[] initializer() const @safe
1397     {
1398         return null;
1399     }
1400 
1401     override @property immutable(void)* rtInfo() nothrow pure const @safe { return rtinfoNoPointers; }
1402 
1403     TypeInfo next;
1404 
1405     /**
1406     * Mangled function type string
1407     */
1408     string deco;
1409 }
1410 
1411 @safe unittest
1412 {
1413     abstract class C
1414     {
1415        void func();
1416        void func(int a);
1417        int func(int a, int b);
1418     }
1419 
1420     alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
1421     assert(typeid(functionTypes[0]).toString() == "void function()");
1422     assert(typeid(functionTypes[1]).toString() == "void function(int)");
1423     assert(typeid(functionTypes[2]).toString() == "int function(int, int)");
1424 }
1425 
1426 @system unittest
1427 {
1428     abstract class C
1429     {
1430        void func();
1431        void func(int a);
1432     }
1433 
1434     alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
1435 
1436     Object obj = typeid(functionTypes[0]);
1437     assert(obj.opEquals(typeid(functionTypes[0])));
1438     assert(typeid(functionTypes[0]) == typeid(functionTypes[0]));
1439     assert(typeid(functionTypes[0]) != typeid(functionTypes[1]));
1440 
1441     assert(typeid(functionTypes[0]).tsize() == 0);
1442     assert(typeid(functionTypes[0]).initializer() is null);
1443     assert(typeid(functionTypes[0]).rtInfo() is null);
1444 }
1445 
1446 class TypeInfo_Delegate : TypeInfo
1447 {
1448     override string toString() const pure @trusted
1449     {
1450         import core.demangle : demangleType;
1451 
1452         alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;
1453         SafeDemangleFunctionType demangle = cast(SafeDemangleFunctionType) &demangleType;
1454 
1455         return cast(string) demangle(deco);
1456     }
1457 
1458     @safe unittest
1459     {
1460         double sqr(double x) { return x * x; }
1461         sqr(double.init); // for coverage completeness
1462 
1463         auto delegate_str = "double delegate(double) pure nothrow @nogc @safe";
1464 
1465         assert(typeid(typeof(&sqr)).toString() == delegate_str);
1466         assert(delegate_str.hashOf() == typeid(typeof(&sqr)).hashOf());
1467         assert(typeid(typeof(&sqr)).toHash() == typeid(typeof(&sqr)).hashOf());
1468 
1469         int g;
1470 
1471         alias delegate_type = typeof((int a, int b) => a + b + g);
1472         delegate_str = "int delegate(int, int) pure nothrow @nogc @safe";
1473 
1474         assert(typeid(delegate_type).toString() == delegate_str);
1475         assert(delegate_str.hashOf() == typeid(delegate_type).hashOf());
1476         assert(typeid(delegate_type).toHash() == typeid(delegate_type).hashOf());
1477     }
1478 
1479     override bool opEquals(Object o)
1480     {
1481         if (this is o)
1482             return true;
1483         auto c = cast(const TypeInfo_Delegate)o;
1484         return c && this.deco == c.deco;
1485     }
1486 
1487     @system unittest
1488     {
1489         double sqr(double x) { return x * x; }
1490         int dbl(int x) { return x + x; }
1491         sqr(double.init); // for coverage completeness
1492         dbl(int.init); // for coverage completeness
1493 
1494         Object obj = typeid(typeof(&sqr));
1495         assert(obj.opEquals(typeid(typeof(&sqr))));
1496         assert(typeid(typeof(&sqr)) == typeid(typeof(&sqr)));
1497         assert(typeid(typeof(&dbl)) != typeid(typeof(&sqr)));
1498     }
1499 
1500     override size_t getHash(scope const void* p) @trusted const
1501     {
1502         return hashOf(*cast(const void delegate() *)p);
1503     }
1504 
1505     override bool equals(in void* p1, in void* p2) const
1506     {
1507         auto dg1 = *cast(void delegate()*)p1;
1508         auto dg2 = *cast(void delegate()*)p2;
1509         return dg1 == dg2;
1510     }
1511 
1512     override int compare(in void* p1, in void* p2) const
1513     {
1514         auto dg1 = *cast(void delegate()*)p1;
1515         auto dg2 = *cast(void delegate()*)p2;
1516 
1517         if (dg1 < dg2)
1518             return -1;
1519         else if (dg1 > dg2)
1520             return 1;
1521         else
1522             return 0;
1523     }
1524 
1525     override @property size_t tsize() nothrow pure const
1526     {
1527         alias dg = int delegate();
1528         return dg.sizeof;
1529     }
1530 
1531     override const(void)[] initializer() const @trusted
1532     {
1533         return (cast(void *)null)[0 .. (int delegate()).sizeof];
1534     }
1535 
1536     override @property uint flags() nothrow pure const { return 1; }
1537 
1538     TypeInfo next;
1539     string deco;
1540 
1541     override @property size_t talign() nothrow pure const
1542     {
1543         alias dg = int delegate();
1544         return dg.alignof;
1545     }
1546 
1547     version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1548     {
1549         arg1 = typeid(void*);
1550         arg2 = typeid(void*);
1551         return 0;
1552     }
1553 
1554     override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(int delegate()); }
1555 }
1556 
1557 private extern (C) Object _d_newclass(const TypeInfo_Class ci);
1558 private extern (C) int _d_isbaseof(scope TypeInfo_Class child,
1559     scope const TypeInfo_Class parent) @nogc nothrow pure @safe; // rt.cast_
1560 
1561 /**
1562  * Runtime type information about a class.
1563  * Can be retrieved from an object instance by using the
1564  * $(DDSUBLINK spec/expression,typeid_expressions,typeid expression).
1565  */
1566 class TypeInfo_Class : TypeInfo
1567 {
1568     override string toString() const pure { return name; }
1569 
1570     override bool opEquals(const TypeInfo o) const
1571     {
1572         if (this is o)
1573             return true;
1574         auto c = cast(const TypeInfo_Class)o;
1575         return c && this.name == c.name;
1576     }
1577 
1578     override size_t getHash(scope const void* p) @trusted const
1579     {
1580         auto o = *cast(Object*)p;
1581         return o ? o.toHash() : 0;
1582     }
1583 
1584     override bool equals(in void* p1, in void* p2) const
1585     {
1586         Object o1 = *cast(Object*)p1;
1587         Object o2 = *cast(Object*)p2;
1588 
1589         return (o1 is o2) || (o1 && o1.opEquals(o2));
1590     }
1591 
1592     override int compare(in void* p1, in void* p2) const
1593     {
1594         Object o1 = *cast(Object*)p1;
1595         Object o2 = *cast(Object*)p2;
1596         int c = 0;
1597 
1598         // Regard null references as always being "less than"
1599         if (o1 !is o2)
1600         {
1601             if (o1)
1602             {
1603                 if (!o2)
1604                     c = 1;
1605                 else
1606                     c = o1.opCmp(o2);
1607             }
1608             else
1609                 c = -1;
1610         }
1611         return c;
1612     }
1613 
1614     override @property size_t tsize() nothrow pure const
1615     {
1616         return Object.sizeof;
1617     }
1618 
1619     override const(void)[] initializer() nothrow pure const @safe
1620     {
1621         return m_init;
1622     }
1623 
1624     override @property uint flags() nothrow pure const { return 1; }
1625 
1626     override @property const(OffsetTypeInfo)[] offTi() nothrow pure const
1627     {
1628         return m_offTi;
1629     }
1630 
1631     final @property auto info() @safe @nogc nothrow pure const return { return this; }
1632     final @property auto typeinfo() @safe @nogc nothrow pure const return { return this; }
1633 
1634     byte[]      m_init;         /** class static initializer
1635                                  * (init.length gives size in bytes of class)
1636                                  */
1637     string      name;           /// class name
1638     void*[]     vtbl;           /// virtual function pointer table
1639     Interface[] interfaces;     /// interfaces this class implements
1640     TypeInfo_Class   base;           /// base class
1641     void*       destructor;
1642     void function(Object) classInvariant;
1643     enum ClassFlags : uint
1644     {
1645         isCOMclass = 0x1,
1646         noPointers = 0x2,
1647         hasOffTi = 0x4,
1648         hasCtor = 0x8,
1649         hasGetMembers = 0x10,
1650         hasTypeInfo = 0x20,
1651         isAbstract = 0x40,
1652         isCPPclass = 0x80,
1653         hasDtor = 0x100,
1654     }
1655     ClassFlags m_flags;
1656     void*       deallocator;
1657     OffsetTypeInfo[] m_offTi;
1658     void function(Object) defaultConstructor;   // default Constructor
1659 
1660     immutable(void)* m_RTInfo;        // data for precise GC
1661     override @property immutable(void)* rtInfo() const { return m_RTInfo; }
1662 
1663     /**
1664      * Search all modules for TypeInfo_Class corresponding to classname.
1665      * Returns: null if not found
1666      */
1667     static const(TypeInfo_Class) find(const scope char[] classname)
1668     {
1669         foreach (m; ModuleInfo)
1670         {
1671             if (m)
1672             {
1673                 //writefln("module %s, %d", m.name, m.localClasses.length);
1674                 foreach (c; m.localClasses)
1675                 {
1676                     if (c is null)
1677                         continue;
1678                     //writefln("\tclass %s", c.name);
1679                     if (c.name == classname)
1680                         return c;
1681                 }
1682             }
1683         }
1684         return null;
1685     }
1686 
1687     /**
1688      * Create instance of Object represented by 'this'.
1689      */
1690     Object create() const
1691     {
1692         if (m_flags & 8 && !defaultConstructor)
1693             return null;
1694         if (m_flags & 64) // abstract
1695             return null;
1696         Object o = _d_newclass(this);
1697         if (m_flags & 8 && defaultConstructor)
1698         {
1699             defaultConstructor(o);
1700         }
1701         return o;
1702     }
1703 
1704    /**
1705     * Returns true if the class described by `child` derives from or is
1706     * the class described by this `TypeInfo_Class`. Always returns false
1707     * if the argument is null.
1708     *
1709     * Params:
1710     *  child = TypeInfo for some class
1711     * Returns:
1712     *  true if the class described by `child` derives from or is the
1713     *  class described by this `TypeInfo_Class`.
1714     */
1715     final bool isBaseOf(scope const TypeInfo_Class child) const @nogc nothrow pure @trusted
1716     {
1717         if (m_init.length)
1718         {
1719             // If this TypeInfo_Class represents an actual class we only need
1720             // to check the child and its direct ancestors.
1721             for (auto ti = cast() child; ti !is null; ti = ti.base)
1722                 if (ti is this)
1723                     return true;
1724             return false;
1725         }
1726         else
1727         {
1728             // If this TypeInfo_Class is the .info field of a TypeInfo_Interface
1729             // we also need to recursively check the child's interfaces.
1730             return child !is null && _d_isbaseof(cast() child, this);
1731         }
1732     }
1733 }
1734 
1735 alias ClassInfo = TypeInfo_Class;
1736 
1737 @safe unittest
1738 {
1739     // Bugzilla 14401
1740     static class X
1741     {
1742         int a;
1743     }
1744 
1745     assert(typeid(X).initializer is typeid(X).m_init);
1746     assert(typeid(X).initializer.length == typeid(const(X)).initializer.length);
1747     assert(typeid(X).initializer.length == typeid(shared(X)).initializer.length);
1748     assert(typeid(X).initializer.length == typeid(immutable(X)).initializer.length);
1749 }
1750 
1751 class TypeInfo_Interface : TypeInfo
1752 {
1753     override string toString() const pure { return info.name; }
1754 
1755     override bool opEquals(Object o)
1756     {
1757         if (this is o)
1758             return true;
1759         auto c = cast(const TypeInfo_Interface)o;
1760         return c && this.info.name == typeid(c).name;
1761     }
1762 
1763     override size_t getHash(scope const void* p) @trusted const
1764     {
1765         if (!*cast(void**)p)
1766         {
1767             return 0;
1768         }
1769         Interface* pi = **cast(Interface ***)*cast(void**)p;
1770         Object o = cast(Object)(*cast(void**)p - pi.offset);
1771         assert(o);
1772         return o.toHash();
1773     }
1774 
1775     override bool equals(in void* p1, in void* p2) const
1776     {
1777         Interface* pi = **cast(Interface ***)*cast(void**)p1;
1778         Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
1779         pi = **cast(Interface ***)*cast(void**)p2;
1780         Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
1781 
1782         return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
1783     }
1784 
1785     override int compare(in void* p1, in void* p2) const
1786     {
1787         Interface* pi = **cast(Interface ***)*cast(void**)p1;
1788         Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
1789         pi = **cast(Interface ***)*cast(void**)p2;
1790         Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
1791         int c = 0;
1792 
1793         // Regard null references as always being "less than"
1794         if (o1 != o2)
1795         {
1796             if (o1)
1797             {
1798                 if (!o2)
1799                     c = 1;
1800                 else
1801                     c = o1.opCmp(o2);
1802             }
1803             else
1804                 c = -1;
1805         }
1806         return c;
1807     }
1808 
1809     override @property size_t tsize() nothrow pure const
1810     {
1811         return Object.sizeof;
1812     }
1813 
1814     override const(void)[] initializer() const @trusted
1815     {
1816         return (cast(void *)null)[0 .. Object.sizeof];
1817     }
1818 
1819     override @property uint flags() nothrow pure const { return 1; }
1820 
1821     TypeInfo_Class info;
1822 
1823    /**
1824     * Returns true if the class described by `child` derives from the
1825     * interface described by this `TypeInfo_Interface`. Always returns
1826     * false if the argument is null.
1827     *
1828     * Params:
1829     *  child = TypeInfo for some class
1830     * Returns:
1831     *  true if the class described by `child` derives from the
1832     *  interface described by this `TypeInfo_Interface`.
1833     */
1834     final bool isBaseOf(scope const TypeInfo_Class child) const @nogc nothrow pure @trusted
1835     {
1836         return child !is null && _d_isbaseof(cast() child, this.info);
1837     }
1838 
1839    /**
1840     * Returns true if the interface described by `child` derives from
1841     * or is the interface described by this `TypeInfo_Interface`.
1842     * Always returns false if the argument is null.
1843     *
1844     * Params:
1845     *  child = TypeInfo for some interface
1846     * Returns:
1847     *  true if the interface described by `child` derives from or is
1848     *  the interface described by this `TypeInfo_Interface`.
1849     */
1850     final bool isBaseOf(scope const TypeInfo_Interface child) const @nogc nothrow pure @trusted
1851     {
1852         return child !is null && _d_isbaseof(cast() child.info, this.info);
1853     }
1854 }
1855 
1856 @safe unittest
1857 {
1858     enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
1859     enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
1860 
1861     interface I {}
1862 
1863     assert(fqn_unittest ~ ".I" == typeid(I).info.name);
1864     assert((fqn_unittest ~ ".I").hashOf() == typeid(I).hashOf());
1865     assert(typeid(I).toHash() == typeid(I).hashOf());
1866 }
1867 
1868 class TypeInfo_Struct : TypeInfo
1869 {
1870     override string toString() const { return name; }
1871 
1872     override size_t toHash() const
1873     {
1874         return hashOf(this.mangledName);
1875     }
1876 
1877     override bool opEquals(Object o)
1878     {
1879         if (this is o)
1880             return true;
1881         auto s = cast(const TypeInfo_Struct)o;
1882         return s && this.mangledName == s.mangledName;
1883     }
1884 
1885     override size_t getHash(scope const void* p) @trusted pure nothrow const
1886     {
1887         assert(p);
1888         if (xtoHash)
1889         {
1890             return (*xtoHash)(p);
1891         }
1892         else
1893         {
1894             return hashOf(p[0 .. initializer().length]);
1895         }
1896     }
1897 
1898     override bool equals(in void* p1, in void* p2) @trusted pure nothrow const
1899     {
1900         import core.stdc.string : memcmp;
1901 
1902         if (!p1 || !p2)
1903             return false;
1904         else if (xopEquals)
1905         {
1906             const dg = _memberFunc(p1, xopEquals);
1907             return dg.xopEquals(p2);
1908         }
1909         else if (p1 == p2)
1910             return true;
1911         else
1912             // BUG: relies on the GC not moving objects
1913             return memcmp(p1, p2, initializer().length) == 0;
1914     }
1915 
1916     override int compare(in void* p1, in void* p2) @trusted pure nothrow const
1917     {
1918         import core.stdc.string : memcmp;
1919 
1920         // Regard null references as always being "less than"
1921         if (p1 != p2)
1922         {
1923             if (p1)
1924             {
1925                 if (!p2)
1926                     return true;
1927                 else if (xopCmp)
1928                 {
1929                     const dg = _memberFunc(p1, xopCmp);
1930                     return dg.xopCmp(p2);
1931                 }
1932                 else
1933                     // BUG: relies on the GC not moving objects
1934                     return memcmp(p1, p2, initializer().length);
1935             }
1936             else
1937                 return -1;
1938         }
1939         return 0;
1940     }
1941 
1942     override @property size_t tsize() nothrow pure const
1943     {
1944         return initializer().length;
1945     }
1946 
1947     override const(void)[] initializer() nothrow pure const @safe
1948     {
1949         return m_init;
1950     }
1951 
1952     override @property uint flags() nothrow pure const { return m_flags; }
1953 
1954     override @property size_t talign() nothrow pure const { return m_align; }
1955 
1956     final override void destroy(void* p) const
1957     {
1958         if (xdtor)
1959         {
1960             if (m_flags & StructFlags.isDynamicType)
1961                 (*xdtorti)(p, this);
1962             else
1963                 (*xdtor)(p);
1964         }
1965     }
1966 
1967     override void postblit(void* p) const
1968     {
1969         if (xpostblit)
1970             (*xpostblit)(p);
1971     }
1972 
1973     string mangledName;
1974 
1975     final @property string name() nothrow const @trusted
1976     {
1977         import core.demangle : demangleType;
1978 
1979         if (mangledName is null) // e.g., opaque structs
1980             return null;
1981 
1982         const key = cast(const void*) this; // faster lookup than TypeInfo_Struct, at the cost of potential duplicates per binary
1983         static string[typeof(key)] demangledNamesCache; // per thread
1984 
1985         // not nothrow:
1986         //return demangledNamesCache.require(key, cast(string) demangleType(mangledName));
1987 
1988         if (auto pDemangled = key in demangledNamesCache)
1989             return *pDemangled;
1990 
1991         const demangled = cast(string) demangleType(mangledName);
1992         demangledNamesCache[key] = demangled;
1993         return demangled;
1994     }
1995 
1996     void[] m_init;      // initializer; m_init.ptr == null if 0 initialize
1997 
1998     @safe pure nothrow
1999     {
2000         size_t   function(in void*)           xtoHash;
2001         bool     function(in void*, in void*) xopEquals;
2002         int      function(in void*, in void*) xopCmp;
2003         string   function(in void*)           xtoString;
2004 
2005         enum StructFlags : uint
2006         {
2007             hasPointers = 0x1,
2008             isDynamicType = 0x2, // built at runtime, needs type info in xdtor
2009         }
2010         StructFlags m_flags;
2011     }
2012     union
2013     {
2014         void function(void*)                xdtor;
2015         void function(void*, const TypeInfo_Struct ti) xdtorti;
2016     }
2017     void function(void*)                    xpostblit;
2018 
2019     uint m_align;
2020 
2021     override @property immutable(void)* rtInfo() nothrow pure const @safe { return m_RTInfo; }
2022 
2023     version (WithArgTypes)
2024     {
2025         override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2026         {
2027             arg1 = m_arg1;
2028             arg2 = m_arg2;
2029             return 0;
2030         }
2031         TypeInfo m_arg1;
2032         TypeInfo m_arg2;
2033     }
2034     immutable(void)* m_RTInfo;                // data for precise GC
2035 
2036     // The xopEquals and xopCmp members are function pointers to member
2037     // functions, which is not guaranteed to share the same ABI, as it is not
2038     // known whether the `this` parameter is the first or second argument.
2039     // This wrapper is to convert it to a delegate which will always pass the
2040     // `this` parameter in the correct way.
2041     private struct _memberFunc
2042     {
2043         union
2044         {
2045             struct // delegate
2046             {
2047                 const void* ptr;
2048                 const void* funcptr;
2049             }
2050             @safe pure nothrow
2051             {
2052                 bool delegate(in void*) xopEquals;
2053                 int delegate(in void*) xopCmp;
2054             }
2055         }
2056     }
2057 }
2058 
2059 @system unittest
2060 {
2061     struct S
2062     {
2063         bool opEquals(ref const S rhs) const
2064         {
2065             return false;
2066         }
2067     }
2068     S s;
2069     assert(!typeid(S).equals(&s, &s));
2070 }
2071 
2072 class TypeInfo_Tuple : TypeInfo
2073 {
2074     TypeInfo[] elements;
2075 
2076     override string toString() const
2077     {
2078         string s = "(";
2079         foreach (i, element; elements)
2080         {
2081             if (i)
2082                 s ~= ',';
2083             s ~= element.toString();
2084         }
2085         s ~= ")";
2086         return s;
2087     }
2088 
2089     override bool opEquals(Object o)
2090     {
2091         if (this is o)
2092             return true;
2093 
2094         auto t = cast(const TypeInfo_Tuple)o;
2095         if (t && elements.length == t.elements.length)
2096         {
2097             for (size_t i = 0; i < elements.length; i++)
2098             {
2099                 if (elements[i] != t.elements[i])
2100                     return false;
2101             }
2102             return true;
2103         }
2104         return false;
2105     }
2106 
2107     override size_t getHash(scope const void* p) const
2108     {
2109         assert(0);
2110     }
2111 
2112     override bool equals(in void* p1, in void* p2) const
2113     {
2114         assert(0);
2115     }
2116 
2117     override int compare(in void* p1, in void* p2) const
2118     {
2119         assert(0);
2120     }
2121 
2122     override @property size_t tsize() nothrow pure const
2123     {
2124         assert(0);
2125     }
2126 
2127     override const(void)[] initializer() const @trusted
2128     {
2129         assert(0);
2130     }
2131 
2132     override void swap(void* p1, void* p2) const
2133     {
2134         assert(0);
2135     }
2136 
2137     override void destroy(void* p) const
2138     {
2139         assert(0);
2140     }
2141 
2142     override void postblit(void* p) const
2143     {
2144         assert(0);
2145     }
2146 
2147     override @property size_t talign() nothrow pure const
2148     {
2149         assert(0);
2150     }
2151 
2152     version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2153     {
2154         assert(0);
2155     }
2156 }
2157 
2158 class TypeInfo_Const : TypeInfo
2159 {
2160     override string toString() const
2161     {
2162         return cast(string) ("const(" ~ base.toString() ~ ")");
2163     }
2164 
2165     //override bool opEquals(Object o) { return base.opEquals(o); }
2166     override bool opEquals(Object o)
2167     {
2168         if (this is o)
2169             return true;
2170 
2171         if (typeid(this) != typeid(o))
2172             return false;
2173 
2174         auto t = cast(TypeInfo_Const)o;
2175         return base.opEquals(t.base);
2176     }
2177 
2178     override size_t getHash(scope const void *p) const { return base.getHash(p); }
2179     override bool equals(in void *p1, in void *p2) const { return base.equals(p1, p2); }
2180     override int compare(in void *p1, in void *p2) const { return base.compare(p1, p2); }
2181     override @property size_t tsize() nothrow pure const { return base.tsize; }
2182     override void swap(void *p1, void *p2) const { return base.swap(p1, p2); }
2183 
2184     override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
2185     override @property uint flags() nothrow pure const { return base.flags; }
2186 
2187     override const(void)[] initializer() nothrow pure const
2188     {
2189         return base.initializer();
2190     }
2191 
2192     override @property size_t talign() nothrow pure const { return base.talign; }
2193 
2194     version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2195     {
2196         return base.argTypes(arg1, arg2);
2197     }
2198 
2199     TypeInfo base;
2200 }
2201 
2202 class TypeInfo_Invariant : TypeInfo_Const
2203 {
2204     override string toString() const
2205     {
2206         return cast(string) ("immutable(" ~ base.toString() ~ ")");
2207     }
2208 }
2209 
2210 class TypeInfo_Shared : TypeInfo_Const
2211 {
2212     override string toString() const
2213     {
2214         return cast(string) ("shared(" ~ base.toString() ~ ")");
2215     }
2216 }
2217 
2218 class TypeInfo_Inout : TypeInfo_Const
2219 {
2220     override string toString() const
2221     {
2222         return cast(string) ("inout(" ~ base.toString() ~ ")");
2223     }
2224 }
2225 
2226 // Contents of Moduleinfo._flags
2227 enum
2228 {
2229     MIctorstart  = 0x1,   // we've started constructing it
2230     MIctordone   = 0x2,   // finished construction
2231     MIstandalone = 0x4,   // module ctor does not depend on other module
2232                         // ctors being done first
2233     MItlsctor    = 8,
2234     MItlsdtor    = 0x10,
2235     MIctor       = 0x20,
2236     MIdtor       = 0x40,
2237     MIxgetMembers = 0x80,
2238     MIictor      = 0x100,
2239     MIunitTest   = 0x200,
2240     MIimportedModules = 0x400,
2241     MIlocalClasses = 0x800,
2242     MIname       = 0x1000,
2243 }
2244 
2245 /*****************************************
2246  * An instance of ModuleInfo is generated into the object file for each compiled module.
2247  *
2248  * It provides access to various aspects of the module.
2249  * It is not generated for betterC.
2250  */
2251 struct ModuleInfo
2252 {
2253     uint _flags; // MIxxxx
2254     uint _index; // index into _moduleinfo_array[]
2255 
2256     version (all)
2257     {
2258         deprecated("ModuleInfo cannot be copy-assigned because it is a variable-sized struct.")
2259         void opAssign(const scope ModuleInfo m) { _flags = m._flags; _index = m._index; }
2260     }
2261     else
2262     {
2263         @disable this();
2264     }
2265 
2266 const:
2267     private void* addrOf(int flag) return nothrow pure @nogc
2268     in
2269     {
2270         assert(flag >= MItlsctor && flag <= MIname);
2271         assert(!(flag & (flag - 1)) && !(flag & ~(flag - 1) << 1));
2272     }
2273     do
2274     {
2275         import core.stdc.string : strlen;
2276 
2277         void* p = cast(void*)&this + ModuleInfo.sizeof;
2278 
2279         if (flags & MItlsctor)
2280         {
2281             if (flag == MItlsctor) return p;
2282             p += typeof(tlsctor).sizeof;
2283         }
2284         if (flags & MItlsdtor)
2285         {
2286             if (flag == MItlsdtor) return p;
2287             p += typeof(tlsdtor).sizeof;
2288         }
2289         if (flags & MIctor)
2290         {
2291             if (flag == MIctor) return p;
2292             p += typeof(ctor).sizeof;
2293         }
2294         if (flags & MIdtor)
2295         {
2296             if (flag == MIdtor) return p;
2297             p += typeof(dtor).sizeof;
2298         }
2299         if (flags & MIxgetMembers)
2300         {
2301             if (flag == MIxgetMembers) return p;
2302             p += typeof(xgetMembers).sizeof;
2303         }
2304         if (flags & MIictor)
2305         {
2306             if (flag == MIictor) return p;
2307             p += typeof(ictor).sizeof;
2308         }
2309         if (flags & MIunitTest)
2310         {
2311             if (flag == MIunitTest) return p;
2312             p += typeof(unitTest).sizeof;
2313         }
2314         if (flags & MIimportedModules)
2315         {
2316             if (flag == MIimportedModules) return p;
2317             p += size_t.sizeof + *cast(size_t*)p * typeof(importedModules[0]).sizeof;
2318         }
2319         if (flags & MIlocalClasses)
2320         {
2321             if (flag == MIlocalClasses) return p;
2322             p += size_t.sizeof + *cast(size_t*)p * typeof(localClasses[0]).sizeof;
2323         }
2324         if (true || flags & MIname) // always available for now
2325         {
2326             if (flag == MIname) return p;
2327             p += strlen(cast(immutable char*)p);
2328         }
2329         assert(0);
2330     }
2331 
2332     @property uint index() nothrow pure @nogc { return _index; }
2333 
2334     @property uint flags() nothrow pure @nogc { return _flags; }
2335 
2336     /************************
2337      * Returns:
2338      *  module constructor for thread locals, `null` if there isn't one
2339      */
2340     @property void function() tlsctor() nothrow pure @nogc
2341     {
2342         return flags & MItlsctor ? *cast(typeof(return)*)addrOf(MItlsctor) : null;
2343     }
2344 
2345     /************************
2346      * Returns:
2347      *  module destructor for thread locals, `null` if there isn't one
2348      */
2349     @property void function() tlsdtor() nothrow pure @nogc
2350     {
2351         return flags & MItlsdtor ? *cast(typeof(return)*)addrOf(MItlsdtor) : null;
2352     }
2353 
2354     /*****************************
2355      * Returns:
2356      *  address of a module's `const(MemberInfo)[] getMembers(string)` function, `null` if there isn't one
2357      */
2358     @property void* xgetMembers() nothrow pure @nogc
2359     {
2360         return flags & MIxgetMembers ? *cast(typeof(return)*)addrOf(MIxgetMembers) : null;
2361     }
2362 
2363     /************************
2364      * Returns:
2365      *  module constructor, `null` if there isn't one
2366      */
2367     @property void function() ctor() nothrow pure @nogc
2368     {
2369         return flags & MIctor ? *cast(typeof(return)*)addrOf(MIctor) : null;
2370     }
2371 
2372     /************************
2373      * Returns:
2374      *  module destructor, `null` if there isn't one
2375      */
2376     @property void function() dtor() nothrow pure @nogc
2377     {
2378         return flags & MIdtor ? *cast(typeof(return)*)addrOf(MIdtor) : null;
2379     }
2380 
2381     /************************
2382      * Returns:
2383      *  module order independent constructor, `null` if there isn't one
2384      */
2385     @property void function() ictor() nothrow pure @nogc
2386     {
2387         return flags & MIictor ? *cast(typeof(return)*)addrOf(MIictor) : null;
2388     }
2389 
2390     /*************
2391      * Returns:
2392      *  address of function that runs the module's unittests, `null` if there isn't one
2393      */
2394     @property void function() unitTest() nothrow pure @nogc
2395     {
2396         return flags & MIunitTest ? *cast(typeof(return)*)addrOf(MIunitTest) : null;
2397     }
2398 
2399     /****************
2400      * Returns:
2401      *  array of pointers to the ModuleInfo's of modules imported by this one
2402      */
2403     @property immutable(ModuleInfo*)[] importedModules() return nothrow pure @nogc
2404     {
2405         if (flags & MIimportedModules)
2406         {
2407             auto p = cast(size_t*)addrOf(MIimportedModules);
2408             return (cast(immutable(ModuleInfo*)*)(p + 1))[0 .. *p];
2409         }
2410         return null;
2411     }
2412 
2413     /****************
2414      * Returns:
2415      *  array of TypeInfo_Class references for classes defined in this module
2416      */
2417     @property TypeInfo_Class[] localClasses() return nothrow pure @nogc
2418     {
2419         if (flags & MIlocalClasses)
2420         {
2421             auto p = cast(size_t*)addrOf(MIlocalClasses);
2422             return (cast(TypeInfo_Class*)(p + 1))[0 .. *p];
2423         }
2424         return null;
2425     }
2426 
2427     /********************
2428      * Returns:
2429      *  name of module, `null` if no name
2430      */
2431     @property string name() return nothrow pure @nogc
2432     {
2433         import core.stdc.string : strlen;
2434 
2435         auto p = cast(immutable char*) addrOf(MIname);
2436         return p[0 .. strlen(p)];
2437     }
2438 
2439     static int opApply(scope int delegate(ModuleInfo*) dg)
2440     {
2441         import core.internal.traits : externDFunc;
2442         alias moduleinfos_apply = externDFunc!("rt.minfo.moduleinfos_apply",
2443                                               int function(scope int delegate(immutable(ModuleInfo*))));
2444         // Bugzilla 13084 - enforcing immutable ModuleInfo would break client code
2445         return moduleinfos_apply(
2446             (immutable(ModuleInfo*)m) => dg(cast(ModuleInfo*)m));
2447     }
2448 }
2449 
2450 @system unittest
2451 {
2452     ModuleInfo* m1;
2453     foreach (m; ModuleInfo)
2454     {
2455         m1 = m;
2456     }
2457 }
2458 
2459 ///////////////////////////////////////////////////////////////////////////////
2460 // Throwable
2461 ///////////////////////////////////////////////////////////////////////////////
2462 
2463 
2464 /**
2465  * The base class of all thrown objects.
2466  *
2467  * All thrown objects must inherit from Throwable. Class $(D Exception), which
2468  * derives from this class, represents the category of thrown objects that are
2469  * safe to catch and handle. In principle, one should not catch Throwable
2470  * objects that are not derived from $(D Exception), as they represent
2471  * unrecoverable runtime errors. Certain runtime guarantees may fail to hold
2472  * when these errors are thrown, making it unsafe to continue execution after
2473  * catching them.
2474  */
2475 class Throwable : Object
2476 {
2477     interface TraceInfo
2478     {
2479         int opApply(scope int delegate(ref const(char[]))) const;
2480         int opApply(scope int delegate(ref size_t, ref const(char[]))) const;
2481         string toString() const;
2482     }
2483 
2484     alias TraceDeallocator = void function(TraceInfo) nothrow;
2485 
2486     string      msg;    /// A message describing the error.
2487 
2488     /**
2489      * The _file name of the D source code corresponding with
2490      * where the error was thrown from.
2491      */
2492     string      file;
2493     /**
2494      * The _line number of the D source code corresponding with
2495      * where the error was thrown from.
2496      */
2497     size_t      line;
2498 
2499     /**
2500      * The stack trace of where the error happened. This is an opaque object
2501      * that can either be converted to $(D string), or iterated over with $(D
2502      * foreach) to extract the items in the stack trace (as strings).
2503      */
2504     TraceInfo   info;
2505 
2506     /**
2507      * If set, this is used to deallocate the TraceInfo on destruction.
2508      */
2509     TraceDeallocator infoDeallocator;
2510 
2511 
2512     /**
2513      * A reference to the _next error in the list. This is used when a new
2514      * $(D Throwable) is thrown from inside a $(D catch) block. The originally
2515      * caught $(D Exception) will be chained to the new $(D Throwable) via this
2516      * field.
2517      */
2518     private Throwable   nextInChain;
2519 
2520     private uint _refcount;     // 0 : allocated by GC
2521                                 // 1 : allocated by _d_newThrowable()
2522                                 // 2.. : reference count + 1
2523 
2524     /**
2525      * Returns:
2526      * A reference to the _next error in the list. This is used when a new
2527      * $(D Throwable) is thrown from inside a $(D catch) block. The originally
2528      * caught $(D Exception) will be chained to the new $(D Throwable) via this
2529      * field.
2530      */
2531     @property inout(Throwable) next() @safe inout return scope pure nothrow @nogc { return nextInChain; }
2532 
2533     /**
2534      * Replace next in chain with `tail`.
2535      * Use `chainTogether` instead if at all possible.
2536      */
2537     @property void next(Throwable tail) @safe scope pure nothrow @nogc
2538     {
2539         if (tail && tail._refcount)
2540             ++tail._refcount;           // increment the replacement *first*
2541 
2542         auto n = nextInChain;
2543         nextInChain = null;             // sever the tail before deleting it
2544 
2545         if (n && n._refcount)
2546             _d_delThrowable(n);         // now delete the old tail
2547 
2548         nextInChain = tail;             // and set the new tail
2549     }
2550 
2551     /**
2552      * Returns:
2553      *  mutable reference to the reference count, which is
2554      *  0 - allocated by the GC, 1 - allocated by _d_newThrowable(),
2555      *  and >=2 which is the reference count + 1
2556      * Note:
2557      *  Marked as `@system` to discourage casual use of it.
2558      */
2559     @system @nogc final pure nothrow ref uint refcount() return { return _refcount; }
2560 
2561     /**
2562      * Loop over the chain of Throwables.
2563      */
2564     int opApply(scope int delegate(Throwable) dg)
2565     {
2566         int result = 0;
2567         for (Throwable t = this; t; t = t.nextInChain)
2568         {
2569             result = dg(t);
2570             if (result)
2571                 break;
2572         }
2573         return result;
2574     }
2575 
2576     /**
2577      * Append `e2` to chain of exceptions that starts with `e1`.
2578      * Params:
2579      *  e1 = start of chain (can be null)
2580      *  e2 = second part of chain (can be null)
2581      * Returns:
2582      *  Throwable that is at the start of the chain; null if both `e1` and `e2` are null
2583      */
2584     static @__future @system @nogc pure nothrow Throwable chainTogether(return scope Throwable e1, return scope Throwable e2)
2585     {
2586         if (!e1)
2587             return e2;
2588         if (!e2)
2589             return e1;
2590         if (e2.refcount())
2591             ++e2.refcount();
2592 
2593         for (auto e = e1; 1; e = e.nextInChain)
2594         {
2595             if (!e.nextInChain)
2596             {
2597                 e.nextInChain = e2;
2598                 break;
2599             }
2600         }
2601         return e1;
2602     }
2603 
2604     @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)
2605     {
2606         this.msg = msg;
2607         this.nextInChain = nextInChain;
2608         if (nextInChain && nextInChain._refcount)
2609             ++nextInChain._refcount;
2610         //this.info = _d_traceContext();
2611     }
2612 
2613     @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)
2614     {
2615         this(msg, nextInChain);
2616         this.file = file;
2617         this.line = line;
2618         //this.info = _d_traceContext();
2619     }
2620 
2621     @trusted nothrow ~this()
2622     {
2623         if (nextInChain && nextInChain._refcount)
2624             _d_delThrowable(nextInChain);
2625         // handle owned traceinfo
2626         if (infoDeallocator !is null)
2627         {
2628             infoDeallocator(info);
2629             info = null; // avoid any kind of dangling pointers if we can help
2630                          // it.
2631         }
2632     }
2633 
2634     /**
2635      * Overrides $(D Object.toString) and returns the error message.
2636      * Internally this forwards to the $(D toString) overload that
2637      * takes a $(D_PARAM sink) delegate.
2638      */
2639     override string toString()
2640     {
2641         string s;
2642         toString((in buf) { s ~= buf; });
2643         return s;
2644     }
2645 
2646     /**
2647      * The Throwable hierarchy uses a toString overload that takes a
2648      * $(D_PARAM _sink) delegate to avoid GC allocations, which cannot be
2649      * performed in certain error situations.  Override this $(D
2650      * toString) method to customize the error message.
2651      */
2652     void toString(scope void delegate(in char[]) sink) const
2653     {
2654         import core.internal.string : unsignedToTempString;
2655 
2656         char[20] tmpBuff = void;
2657 
2658         sink(typeid(this).name);
2659         sink("@"); sink(file);
2660         sink("("); sink(unsignedToTempString(line, tmpBuff)); sink(")");
2661 
2662         if (msg.length)
2663         {
2664             sink(": "); sink(msg);
2665         }
2666         if (info)
2667         {
2668             try
2669             {
2670                 sink("\n----------------");
2671                 foreach (t; info)
2672                 {
2673                     sink("\n"); sink(t);
2674                 }
2675             }
2676             catch (Throwable)
2677             {
2678                 // ignore more errors
2679             }
2680         }
2681     }
2682 
2683     /**
2684      * Get the message describing the error.
2685      *
2686      * This getter is an alternative way to access the Exception's message,
2687      * with the added advantage of being override-able in subclasses.
2688      * Subclasses are hence free to do their own memory managements without
2689      * being tied to the requirement of providing a `string` in a field.
2690      *
2691      * The default behavior is to return the `Throwable.msg` field.
2692      *
2693      * Returns:
2694      *  A message representing the cause of the `Throwable`
2695      */
2696     @__future const(char)[] message() const @safe nothrow
2697     {
2698         return this.msg;
2699     }
2700 }
2701 
2702 
2703 /**
2704  * The base class of all errors that are safe to catch and handle.
2705  *
2706  * In principle, only thrown objects derived from this class are safe to catch
2707  * inside a $(D catch) block. Thrown objects not derived from Exception
2708  * represent runtime errors that should not be caught, as certain runtime
2709  * guarantees may not hold, making it unsafe to continue program execution.
2710  */
2711 class Exception : Throwable
2712 {
2713 
2714     /**
2715      * Creates a new instance of Exception. The nextInChain parameter is used
2716      * internally and should always be $(D null) when passed by user code.
2717      * This constructor does not automatically throw the newly-created
2718      * Exception; the $(D throw) expression should be used for that purpose.
2719      */
2720     @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null)
2721     {
2722         super(msg, file, line, nextInChain);
2723     }
2724 
2725     @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
2726     {
2727         super(msg, file, line, nextInChain);
2728     }
2729 }
2730 
2731 ///
2732 @safe unittest
2733 {
2734     bool gotCaught;
2735     try
2736     {
2737         throw new Exception("msg");
2738     }
2739     catch (Exception e)
2740     {
2741         gotCaught = true;
2742         assert(e.msg == "msg");
2743     }
2744     assert(gotCaught);
2745 }
2746 
2747 @system unittest
2748 {
2749     {
2750         auto e = new Exception("msg");
2751         assert(e.file == __FILE__);
2752         assert(e.line == __LINE__ - 2);
2753         assert(e.nextInChain is null);
2754         assert(e.msg == "msg");
2755     }
2756 
2757     {
2758         auto e = new Exception("msg", new Exception("It's an Exception!"), "hello", 42);
2759         assert(e.file == "hello");
2760         assert(e.line == 42);
2761         assert(e.nextInChain !is null);
2762         assert(e.msg == "msg");
2763     }
2764 
2765     {
2766         auto e = new Exception("msg", "hello", 42, new Exception("It's an Exception!"));
2767         assert(e.file == "hello");
2768         assert(e.line == 42);
2769         assert(e.nextInChain !is null);
2770         assert(e.msg == "msg");
2771     }
2772 
2773     {
2774         auto e = new Exception("message");
2775         assert(e.message == "message");
2776     }
2777 }
2778 
2779 
2780 /**
2781  * The base class of all unrecoverable runtime errors.
2782  *
2783  * This represents the category of $(D Throwable) objects that are $(B not)
2784  * safe to catch and handle. In principle, one should not catch Error
2785  * objects, as they represent unrecoverable runtime errors.
2786  * Certain runtime guarantees may fail to hold when these errors are
2787  * thrown, making it unsafe to continue execution after catching them.
2788  */
2789 class Error : Throwable
2790 {
2791     /**
2792      * Creates a new instance of Error. The nextInChain parameter is used
2793      * internally and should always be $(D null) when passed by user code.
2794      * This constructor does not automatically throw the newly-created
2795      * Error; the $(D throw) statement should be used for that purpose.
2796      */
2797     @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)
2798     {
2799         super(msg, nextInChain);
2800         bypassedException = null;
2801     }
2802 
2803     @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)
2804     {
2805         super(msg, file, line, nextInChain);
2806         bypassedException = null;
2807     }
2808 
2809     /** The first $(D Exception) which was bypassed when this Error was thrown,
2810     or $(D null) if no $(D Exception)s were pending. */
2811     Throwable   bypassedException;
2812 }
2813 
2814 ///
2815 @system unittest
2816 {
2817     bool gotCaught;
2818     try
2819     {
2820         throw new Error("msg");
2821     }
2822     catch (Error e)
2823     {
2824         gotCaught = true;
2825         assert(e.msg == "msg");
2826     }
2827     assert(gotCaught);
2828 }
2829 
2830 @safe unittest
2831 {
2832     {
2833         auto e = new Error("msg");
2834         assert(e.file is null);
2835         assert(e.line == 0);
2836         assert(e.nextInChain is null);
2837         assert(e.msg == "msg");
2838         assert(e.bypassedException is null);
2839     }
2840 
2841     {
2842         auto e = new Error("msg", new Exception("It's an Exception!"));
2843         assert(e.file is null);
2844         assert(e.line == 0);
2845         assert(e.nextInChain !is null);
2846         assert(e.msg == "msg");
2847         assert(e.bypassedException is null);
2848     }
2849 
2850     {
2851         auto e = new Error("msg", "hello", 42, new Exception("It's an Exception!"));
2852         assert(e.file == "hello");
2853         assert(e.line == 42);
2854         assert(e.nextInChain !is null);
2855         assert(e.msg == "msg");
2856         assert(e.bypassedException is null);
2857     }
2858 }
2859 
2860 extern (C)
2861 {
2862     // from druntime/src/rt/aaA.d
2863 
2864     private struct AA { void* impl; }
2865     // size_t _aaLen(in AA aa) pure nothrow @nogc;
2866     private void* _aaGetY(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow;
2867     private void* _aaGetX(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow;
2868     // inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
2869     inout(void[]) _aaValues(inout AA aa, const size_t keysz, const size_t valsz, const TypeInfo tiValueArray) pure nothrow;
2870     inout(void[]) _aaKeys(inout AA aa, const size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
2871     void* _aaRehash(AA* paa, const scope TypeInfo keyti) pure nothrow;
2872     void _aaClear(AA aa) pure nothrow;
2873 
2874     // alias _dg_t = extern(D) int delegate(void*);
2875     // int _aaApply(AA aa, size_t keysize, _dg_t dg);
2876 
2877     // alias _dg2_t = extern(D) int delegate(void*, void*);
2878     // int _aaApply2(AA aa, size_t keysize, _dg2_t dg);
2879 
2880     private struct AARange { AA impl; size_t idx; }
2881     AARange _aaRange(AA aa) pure nothrow @nogc @safe;
2882     bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe;
2883     void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe;
2884     void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe;
2885     void _aaRangePopFront(ref AARange r) pure nothrow @nogc @safe;
2886 
2887     int _aaEqual(scope const TypeInfo tiRaw, scope const AA aa1, scope const AA aa2);
2888     hash_t _aaGetHash(scope const AA* aa, scope const TypeInfo tiRaw) nothrow;
2889 
2890     /*
2891         _d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code.
2892         This is a typesystem hole, however this is existing hole.
2893         Early compiler didn't check purity of toHash or postblit functions, if key is a UDT thus
2894         copiler allowed to create AA literal with keys, which have impure unsafe toHash methods.
2895     */
2896     void* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys, void[] values) pure;
2897 }
2898 
2899 void* aaLiteral(Key, Value)(Key[] keys, Value[] values) @trusted pure
2900 {
2901     return _d_assocarrayliteralTX(typeid(Value[Key]), *cast(void[]*)&keys, *cast(void[]*)&values);
2902 }
2903 
2904 alias AssociativeArray(Key, Value) = Value[Key];
2905 
2906 /***********************************
2907  * Removes all remaining keys and values from an associative array.
2908  * Params:
2909  *      aa =     The associative array.
2910  */
2911 void clear(Value, Key)(Value[Key] aa)
2912 {
2913     _aaClear(*cast(AA *) &aa);
2914 }
2915 
2916 /** ditto */
2917 void clear(Value, Key)(Value[Key]* aa)
2918 {
2919     _aaClear(*cast(AA *) aa);
2920 }
2921 
2922 ///
2923 @system unittest
2924 {
2925     auto aa = ["k1": 2];
2926     aa.clear;
2927     assert("k1" !in aa);
2928 }
2929 
2930 /***********************************
2931  * Reorganizes the associative array in place so that lookups are more
2932  * efficient.
2933  * Params:
2934  *      aa =     The associative array.
2935  * Returns:
2936  *      The rehashed associative array.
2937  */
2938 T rehash(T : Value[Key], Value, Key)(T aa)
2939 {
2940     _aaRehash(cast(AA*)&aa, typeid(Value[Key]));
2941     return aa;
2942 }
2943 
2944 /** ditto */
2945 T rehash(T : Value[Key], Value, Key)(T* aa)
2946 {
2947     _aaRehash(cast(AA*)aa, typeid(Value[Key]));
2948     return *aa;
2949 }
2950 
2951 /** ditto */
2952 T rehash(T : shared Value[Key], Value, Key)(T aa)
2953 {
2954     _aaRehash(cast(AA*)&aa, typeid(Value[Key]));
2955     return aa;
2956 }
2957 
2958 /** ditto */
2959 T rehash(T : shared Value[Key], Value, Key)(T* aa)
2960 {
2961     _aaRehash(cast(AA*)aa, typeid(Value[Key]));
2962     return *aa;
2963 }
2964 
2965 /***********************************
2966  * Creates a new associative array of the same size and copies the contents of
2967  * the associative array into it.
2968  * Params:
2969  *      aa =     The associative array.
2970  */
2971 V[K] dup(T : V[K], K, V)(T aa)
2972 {
2973     //pragma(msg, "K = ", K, ", V = ", V);
2974 
2975     // Bug10720 - check whether V is copyable
2976     static assert(is(typeof({ V v = aa[K.init]; })),
2977         "cannot call " ~ T.stringof ~ ".dup because " ~ V.stringof ~ " is not copyable");
2978 
2979     V[K] result;
2980 
2981     //foreach (k, ref v; aa)
2982     //    result[k] = v;  // Bug13701 - won't work if V is not mutable
2983 
2984     ref V duplicateElem(ref K k, ref const V v) @trusted pure nothrow
2985     {
2986         import core.stdc.string : memcpy;
2987 
2988         void* pv = _aaGetY(cast(AA*)&result, typeid(V[K]), V.sizeof, &k);
2989         memcpy(pv, &v, V.sizeof);
2990         return *cast(V*)pv;
2991     }
2992 
2993     foreach (k, ref v; aa)
2994     {
2995         static if (!__traits(hasPostblit, V))
2996             duplicateElem(k, v);
2997         else static if (__traits(isStaticArray, V))
2998             _doPostblit(duplicateElem(k, v)[]);
2999         else static if (!is(typeof(v.__xpostblit())) && is(immutable V == immutable UV, UV))
3000             (() @trusted => *cast(UV*) &duplicateElem(k, v))().__xpostblit();
3001         else
3002             duplicateElem(k, v).__xpostblit();
3003     }
3004 
3005     return result;
3006 }
3007 
3008 /** ditto */
3009 V[K] dup(T : V[K], K, V)(T* aa)
3010 {
3011     return (*aa).dup;
3012 }
3013 
3014 ///
3015 @safe unittest
3016 {
3017     auto aa = ["k1": 2];
3018     auto a2 = aa.dup;
3019     aa["k2"] = 3;
3020     assert("k2" !in a2);
3021 }
3022 
3023 // this should never be made public.
3024 private AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe
3025 {
3026     // ensure we are dealing with a genuine AA.
3027     static if (is(const(V[K]) == const(T)))
3028         alias realAA = aa;
3029     else
3030         const(V[K]) realAA = aa;
3031     return _aaRange(() @trusted { return *cast(AA*)&realAA; } ());
3032 }
3033 
3034 /***********************************
3035  * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3036  * which will iterate over the keys of the associative array. The keys are
3037  * returned by reference.
3038  *
3039  * If structural changes are made to the array (removing or adding keys), all
3040  * ranges previously obtained through this function are invalidated. The
3041  * following example program will dereference a null pointer:
3042  *
3043  *---
3044  * import std.stdio : writeln;
3045  *
3046  * auto dict = ["k1": 1, "k2": 2];
3047  * auto keyRange = dict.byKey;
3048  * dict.clear;
3049  * writeln(keyRange.front);    // Segmentation fault
3050  *---
3051  *
3052  * Params:
3053  *      aa =     The associative array.
3054  * Returns:
3055  *      A forward range referencing the keys of the associative array.
3056  */
3057 auto byKey(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3058 {
3059     import core.internal.traits : substInout;
3060 
3061     static struct Result
3062     {
3063         AARange r;
3064 
3065     pure nothrow @nogc:
3066         @property bool empty()  @safe { return _aaRangeEmpty(r); }
3067         @property ref front() @trusted
3068         {
3069             return *cast(substInout!K*) _aaRangeFrontKey(r);
3070         }
3071         void popFront() @safe { _aaRangePopFront(r); }
3072         @property Result save() { return this; }
3073     }
3074 
3075     return Result(_aaToRange(aa));
3076 }
3077 
3078 /** ditto */
3079 auto byKey(T : V[K], K, V)(T* aa) pure nothrow @nogc
3080 {
3081     return (*aa).byKey();
3082 }
3083 
3084 ///
3085 @safe unittest
3086 {
3087     auto dict = [1: "v1", 2: "v2"];
3088     int sum;
3089     foreach (v; dict.byKey)
3090         sum += v;
3091 
3092     assert(sum == 3);
3093 }
3094 
3095 /***********************************
3096  * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3097  * which will iterate over the values of the associative array. The values are
3098  * returned by reference.
3099  *
3100  * If structural changes are made to the array (removing or adding keys), all
3101  * ranges previously obtained through this function are invalidated. The
3102  * following example program will dereference a null pointer:
3103  *
3104  *---
3105  * import std.stdio : writeln;
3106  *
3107  * auto dict = ["k1": 1, "k2": 2];
3108  * auto valueRange = dict.byValue;
3109  * dict.clear;
3110  * writeln(valueRange.front);    // Segmentation fault
3111  *---
3112  *
3113  * Params:
3114  *      aa =     The associative array.
3115  * Returns:
3116  *      A forward range referencing the values of the associative array.
3117  */
3118 auto byValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3119 {
3120     import core.internal.traits : substInout;
3121 
3122     static struct Result
3123     {
3124         AARange r;
3125 
3126     pure nothrow @nogc:
3127         @property bool empty() @safe { return _aaRangeEmpty(r); }
3128         @property ref front() @trusted
3129         {
3130             return *cast(substInout!V*) _aaRangeFrontValue(r);
3131         }
3132         void popFront() @safe { _aaRangePopFront(r); }
3133         @property Result save() { return this; }
3134     }
3135 
3136     return Result(_aaToRange(aa));
3137 }
3138 
3139 /** ditto */
3140 auto byValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
3141 {
3142     return (*aa).byValue();
3143 }
3144 
3145 ///
3146 @safe unittest
3147 {
3148     auto dict = ["k1": 1, "k2": 2];
3149     int sum;
3150     foreach (v; dict.byValue)
3151         sum += v;
3152 
3153     assert(sum == 3);
3154 }
3155 
3156 /***********************************
3157  * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3158  * which will iterate over the key-value pairs of the associative array. The
3159  * returned pairs are represented by an opaque type with `.key` and `.value`
3160  * properties for accessing references to the key and value of the pair,
3161  * respectively.
3162  *
3163  * If structural changes are made to the array (removing or adding keys), all
3164  * ranges previously obtained through this function are invalidated. The
3165  * following example program will dereference a null pointer:
3166  *
3167  *---
3168  * import std.stdio : writeln;
3169  *
3170  * auto dict = ["k1": 1, "k2": 2];
3171  * auto kvRange = dict.byKeyValue;
3172  * dict.clear;
3173  * writeln(kvRange.front.key, ": ", kvRange.front.value);    // Segmentation fault
3174  *---
3175  *
3176  * Note that this is a low-level interface to iterating over the associative
3177  * array and is not compatible withth the
3178  * $(LINK2 $(ROOT_DIR)phobos/std_typecons.html#.Tuple,`Tuple`) type in Phobos.
3179  * For compatibility with `Tuple`, use
3180  * $(LINK2 $(ROOT_DIR)phobos/std_array.html#.byPair,std.array.byPair) instead.
3181  *
3182  * Params:
3183  *      aa =     The associative array.
3184  * Returns:
3185  *      A forward range referencing the pairs of the associative array.
3186  */
3187 auto byKeyValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3188 {
3189     import core.internal.traits : substInout;
3190 
3191     static struct Result
3192     {
3193         AARange r;
3194 
3195     pure nothrow @nogc:
3196         @property bool empty() @safe { return _aaRangeEmpty(r); }
3197         @property auto front()
3198         {
3199             static struct Pair
3200             {
3201                 // We save the pointers here so that the Pair we return
3202                 // won't mutate when Result.popFront is called afterwards.
3203                 private void* keyp;
3204                 private void* valp;
3205 
3206                 @property ref key() inout @trusted
3207                 {
3208                     return *cast(substInout!K*) keyp;
3209                 }
3210                 @property ref value() inout @trusted
3211                 {
3212                     return *cast(substInout!V*) valp;
3213                 }
3214             }
3215             return Pair(_aaRangeFrontKey(r),
3216                         _aaRangeFrontValue(r));
3217         }
3218         void popFront() @safe { return _aaRangePopFront(r); }
3219         @property Result save() { return this; }
3220     }
3221 
3222     return Result(_aaToRange(aa));
3223 }
3224 
3225 /** ditto */
3226 auto byKeyValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
3227 {
3228     return (*aa).byKeyValue();
3229 }
3230 
3231 ///
3232 @safe unittest
3233 {
3234     auto dict = ["k1": 1, "k2": 2];
3235     int sum;
3236     foreach (e; dict.byKeyValue)
3237     {
3238         assert(e.key[1] == e.value + '0');
3239         sum += e.value;
3240     }
3241 
3242     assert(sum == 3);
3243 }
3244 
3245 /***********************************
3246  * Returns a newly allocated dynamic array containing a copy of the keys from
3247  * the associative array.
3248  * Params:
3249  *      aa =     The associative array.
3250  * Returns:
3251  *      A dynamic array containing a copy of the keys.
3252  */
3253 Key[] keys(T : Value[Key], Value, Key)(T aa) @property
3254 {
3255     // ensure we are dealing with a genuine AA.
3256     static if (is(const(Value[Key]) == const(T)))
3257         alias realAA = aa;
3258     else
3259         const(Value[Key]) realAA = aa;
3260     auto res = () @trusted {
3261         auto a = cast(void[])_aaKeys(*cast(inout(AA)*)&realAA, Key.sizeof, typeid(Key[]));
3262         return *cast(Key[]*)&a;
3263     }();
3264     static if (__traits(hasPostblit, Key))
3265         _doPostblit(res);
3266     return res;
3267 }
3268 
3269 /** ditto */
3270 Key[] keys(T : Value[Key], Value, Key)(T *aa) @property
3271 {
3272     return (*aa).keys;
3273 }
3274 
3275 ///
3276 @safe unittest
3277 {
3278     auto aa = [1: "v1", 2: "v2"];
3279     int sum;
3280     foreach (k; aa.keys)
3281         sum += k;
3282 
3283     assert(sum == 3);
3284 }
3285 
3286 @safe unittest
3287 {
3288     static struct S
3289     {
3290         string str;
3291         void[][string] dict;
3292         alias dict this;
3293     }
3294 
3295     auto s = S("a");
3296     assert(s.keys.length == 0);
3297 }
3298 
3299 @safe unittest
3300 {
3301     @safe static struct Key
3302     {
3303          string str;
3304          this(this) @safe {}
3305     }
3306     string[Key] aa;
3307     static assert(__traits(compiles, {
3308                 void test() @safe {
3309                     const _ = aa.keys;
3310                 }
3311             }));
3312 }
3313 
3314 @safe unittest
3315 {
3316     static struct Key
3317     {
3318         string str;
3319         this(this) @system {}
3320     }
3321     string[Key] aa;
3322     static assert(!__traits(compiles, {
3323                 void test() @safe {
3324                     const _ = aa.keys;
3325                 }
3326             }));
3327 }
3328 
3329 /***********************************
3330  * Returns a newly allocated dynamic array containing a copy of the values from
3331  * the associative array.
3332  * Params:
3333  *      aa =     The associative array.
3334  * Returns:
3335  *      A dynamic array containing a copy of the values.
3336  */
3337 Value[] values(T : Value[Key], Value, Key)(T aa) @property
3338 {
3339     // ensure we are dealing with a genuine AA.
3340     static if (is(const(Value[Key]) == const(T)))
3341         alias realAA = aa;
3342     else
3343         const(Value[Key]) realAA = aa;
3344     auto res = () @trusted {
3345         auto a = cast(void[])_aaValues(*cast(inout(AA)*)&realAA, Key.sizeof, Value.sizeof, typeid(Value[]));
3346         return *cast(Value[]*)&a;
3347     }();
3348     static if (__traits(hasPostblit, Value))
3349         _doPostblit(res);
3350     return res;
3351 }
3352 
3353 /** ditto */
3354 Value[] values(T : Value[Key], Value, Key)(T *aa) @property
3355 {
3356     return (*aa).values;
3357 }
3358 
3359 ///
3360 @safe unittest
3361 {
3362     auto aa = ["k1": 1, "k2": 2];
3363     int sum;
3364     foreach (e; aa.values)
3365         sum += e;
3366 
3367     assert(sum == 3);
3368 }
3369 
3370 @safe unittest
3371 {
3372     static struct S
3373     {
3374         string str;
3375         void[][string] dict;
3376         alias dict this;
3377     }
3378 
3379     auto s = S("a");
3380     assert(s.values.length == 0);
3381 }
3382 
3383 @safe unittest
3384 {
3385     @safe static struct Value
3386     {
3387         string str;
3388         this(this) @safe {}
3389     }
3390     Value[string] aa;
3391     static assert(__traits(compiles, {
3392                 void test() @safe {
3393                     const _ = aa.values;
3394                 }
3395             }));
3396 }
3397 
3398 @safe unittest
3399 {
3400     static struct Value
3401     {
3402         string str;
3403         this(this) @system {}
3404     }
3405     Value[string] aa;
3406     static assert(!__traits(compiles, {
3407                 void test() @safe {
3408                     const _ = aa.values;
3409                 }
3410             }));
3411 }
3412 
3413 /***********************************
3414  * Looks up key; if it exists returns corresponding value else evaluates and
3415  * returns defaultValue.
3416  * Params:
3417  *      aa =     The associative array.
3418  *      key =    The key.
3419  *      defaultValue = The default value.
3420  * Returns:
3421  *      The value.
3422  */
3423 inout(V) get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)
3424 {
3425     auto p = key in aa;
3426     return p ? *p : defaultValue;
3427 }
3428 
3429 /** ditto */
3430 inout(V) get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)
3431 {
3432     return (*aa).get(key, defaultValue);
3433 }
3434 
3435 ///
3436 @safe unittest
3437 {
3438     auto aa = ["k1": 1];
3439     assert(aa.get("k1", 0) == 1);
3440     assert(aa.get("k2", 0) == 0);
3441 }
3442 
3443 /***********************************
3444  * Looks up key; if it exists returns corresponding value else evaluates
3445  * value, adds it to the associative array and returns it.
3446  * Params:
3447  *      aa =     The associative array.
3448  *      key =    The key.
3449  *      value =  The required value.
3450  * Returns:
3451  *      The value.
3452  */
3453 ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init)
3454 {
3455     bool found;
3456     // if key is @safe-ly copyable, `require` can infer @safe
3457     static if (isSafeCopyable!K)
3458     {
3459         auto p = () @trusted
3460         {
3461             return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3462         } ();
3463     }
3464     else
3465     {
3466         auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3467     }
3468     if (found)
3469         return *p;
3470     else
3471     {
3472         *p = value; // Not `return (*p = value)` since if `=` is overloaded
3473         return *p;  // this might not return a ref to the left-hand side.
3474     }
3475 }
3476 
3477 ///
3478 @safe unittest
3479 {
3480     auto aa = ["k1": 1];
3481     assert(aa.require("k1", 0) == 1);
3482     assert(aa.require("k2", 0) == 0);
3483     assert(aa["k2"] == 0);
3484 }
3485 
3486 // Tests whether T can be @safe-ly copied. Use a union to exclude destructor from the test.
3487 private enum bool isSafeCopyable(T) = is(typeof(() @safe { union U { T x; } T *x; auto u = U(*x); }));
3488 
3489 /***********************************
3490  * Calls `create` if `key` doesn't exist in the associative array,
3491  * otherwise calls `update`.
3492  * `create` returns a corresponding value for `key`.
3493  * `update` accepts a key parameter. If it returns a value, the value is
3494  * set for `key`.
3495  * Params:
3496  *      aa =     The associative array.
3497  *      key =    The key.
3498  *      create = The callable to create a value for `key`.
3499  *               Must return V.
3500  *      update = The callable to call if `key` exists.
3501  *               Takes a K argument, returns a V or void.
3502  */
3503 void update(K, V, C, U)(ref V[K] aa, K key, scope C create, scope U update)
3504 if (is(typeof(create()) : V) && (is(typeof(update(aa[K.init])) : V) || is(typeof(update(aa[K.init])) == void)))
3505 {
3506     bool found;
3507     // if key is @safe-ly copyable, `update` may infer @safe
3508     static if (isSafeCopyable!K)
3509     {
3510         auto p = () @trusted
3511         {
3512             return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3513         } ();
3514     }
3515     else
3516     {
3517         auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3518     }
3519     if (!found)
3520         *p = create();
3521     else
3522     {
3523         static if (is(typeof(update(*p)) == void))
3524             update(*p);
3525         else
3526             *p = update(*p);
3527     }
3528 }
3529 
3530 ///
3531 @safe unittest
3532 {
3533     int[string] aa;
3534 
3535     // create
3536     aa.update("key",
3537         () => 1,
3538         (int) {} // not executed
3539         );
3540     assert(aa["key"] == 1);
3541 
3542     // update value by ref
3543     aa.update("key",
3544         () => 0, // not executed
3545         (ref int v) {
3546             v += 1;
3547         });
3548     assert(aa["key"] == 2);
3549 
3550     // update from return value
3551     aa.update("key",
3552         () => 0, // not executed
3553         (int v) => v * 2
3554         );
3555     assert(aa["key"] == 4);
3556 
3557     // 'update' without changing value
3558     aa.update("key",
3559         () => 0, // not executed
3560         (int) {
3561             // do something else
3562         });
3563     assert(aa["key"] == 4);
3564 }
3565 
3566 @safe unittest
3567 {
3568     static struct S
3569     {
3570         int x;
3571     @nogc nothrow pure:
3572         this(this) @system {}
3573 
3574     @safe const:
3575         // stubs
3576         bool opEquals(S rhs) { assert(0); }
3577         size_t toHash() { assert(0); }
3578     }
3579 
3580     int[string] aai;
3581     static assert(is(typeof(() @safe { aai.require("a", 1234); })));
3582     static assert(is(typeof(() @safe { aai.update("a", { return 1234; }, (ref int x) { x++; return x; }); })));
3583 
3584     S[string] aas;
3585     static assert(is(typeof(() { aas.require("a", S(1234)); })));
3586     static assert(is(typeof(() { aas.update("a", { return S(1234); }, (ref S s) { s.x++; return s; }); })));
3587     static assert(!is(typeof(() @safe { aas.update("a", { return S(1234); }, (ref S s) { s.x++; return s; }); })));
3588 
3589     int[S] aais;
3590     static assert(is(typeof(() { aais.require(S(1234), 1234); })));
3591     static assert(is(typeof(() { aais.update(S(1234), { return 1234; }, (ref int x) { x++; return x; }); })));
3592     static assert(!is(typeof(() @safe { aais.require(S(1234), 1234); })));
3593     static assert(!is(typeof(() @safe { aais.update(S(1234), { return 1234; }, (ref int x) { x++; return x; }); })));
3594 }
3595 
3596 @safe unittest
3597 {
3598     struct S0
3599     {
3600         int opCall(ref int v)
3601         {
3602             return v + 1;
3603         }
3604     }
3605 
3606     struct S1
3607     {
3608         int opCall()()
3609         {
3610             return -2;
3611         }
3612 
3613         T opCall(T)(ref T v)
3614         {
3615             return v + 1;
3616         }
3617     }
3618 
3619     int[string] a = ["2" : 1];
3620     a.update("2", () => -1, S0.init);
3621     assert(a["2"] == 2);
3622     a.update("0", () => -1, S0.init);
3623     assert(a["0"] == -1);
3624     a.update("2", S1.init, S1.init);
3625     assert(a["2"] == 3);
3626     a.update("1", S1.init, S1.init);
3627     assert(a["1"] == -2);
3628 }
3629 
3630 @system unittest
3631 {
3632     int[string] aa;
3633 
3634     foreach (n; 0 .. 2)
3635         aa.update("k1", {
3636             return 7;
3637         }, (ref int v) {
3638             return v + 3;
3639         });
3640     assert(aa["k1"] == 10);
3641 }
3642 
3643 version (CoreDdoc)
3644 {
3645     // This lets DDoc produce better documentation.
3646 
3647     /**
3648     Calculates the hash value of `arg` with an optional `seed` initial value.
3649     The result might not be equal to `typeid(T).getHash(&arg)`.
3650 
3651     Params:
3652         arg = argument to calculate the hash value of
3653         seed = optional `seed` value (may be used for hash chaining)
3654 
3655     Return: calculated hash value of `arg`
3656     */
3657     size_t hashOf(T)(auto ref T arg, size_t seed)
3658     {
3659         static import core.internal.hash;
3660         return core.internal.hash.hashOf(arg, seed);
3661     }
3662     /// ditto
3663     size_t hashOf(T)(auto ref T arg)
3664     {
3665         static import core.internal.hash;
3666         return core.internal.hash.hashOf(arg);
3667     }
3668 
3669     @safe unittest
3670     {
3671         auto h1 = "my.string".hashOf;
3672         assert(h1 == "my.string".hashOf);
3673     }
3674 }
3675 else
3676 {
3677     public import core.internal.hash : hashOf;
3678 }
3679 
3680 ///
3681 @system unittest
3682 {
3683     class MyObject
3684     {
3685         size_t myMegaHash() const @safe pure nothrow
3686         {
3687             return 42;
3688         }
3689     }
3690     struct Test
3691     {
3692         int a;
3693         string b;
3694         MyObject c;
3695         size_t toHash() const pure nothrow
3696         {
3697             size_t hash = a.hashOf();
3698             hash = b.hashOf(hash);
3699             size_t h1 = c.myMegaHash();
3700             hash = h1.hashOf(hash); //Mix two hash values
3701             return hash;
3702         }
3703     }
3704 }
3705 
3706 bool _xopEquals(in void*, in void*)
3707 {
3708     throw new Error("TypeInfo.equals is not implemented");
3709 }
3710 
3711 bool _xopCmp(in void*, in void*)
3712 {
3713     throw new Error("TypeInfo.compare is not implemented");
3714 }
3715 
3716 /******************************************
3717  * Create RTInfo for type T
3718  */
3719 
3720 template RTInfoImpl(size_t[] pointerBitmap)
3721 {
3722     immutable size_t[pointerBitmap.length] RTInfoImpl = pointerBitmap[];
3723 }
3724 
3725 template NoPointersBitmapPayload(size_t N)
3726 {
3727     enum size_t[N] NoPointersBitmapPayload = 0;
3728 }
3729 
3730 template RTInfo(T)
3731 {
3732     enum pointerBitmap = __traits(getPointerBitmap, T);
3733     static if (pointerBitmap[1 .. $] == NoPointersBitmapPayload!(pointerBitmap.length - 1))
3734         enum RTInfo = rtinfoNoPointers;
3735     else
3736         enum RTInfo = RTInfoImpl!(pointerBitmap).ptr;
3737 }
3738 
3739 /**
3740 * shortcuts for the precise GC, also generated by the compiler
3741 * used instead of the actual pointer bitmap
3742 */
3743 enum immutable(void)* rtinfoNoPointers  = null;
3744 enum immutable(void)* rtinfoHasPointers = cast(void*)1;
3745 
3746 // Helper functions
3747 
3748 private inout(TypeInfo) getElement(return scope inout TypeInfo value) @trusted pure nothrow
3749 {
3750     TypeInfo element = cast() value;
3751     for (;;)
3752     {
3753         if (auto qualified = cast(TypeInfo_Const) element)
3754             element = qualified.base;
3755         else if (auto redefined = cast(TypeInfo_Enum) element)
3756             element = redefined.base;
3757         else if (auto staticArray = cast(TypeInfo_StaticArray) element)
3758             element = staticArray.value;
3759         else if (auto vector = cast(TypeInfo_Vector) element)
3760             element = vector.base;
3761         else
3762             break;
3763     }
3764     return cast(inout) element;
3765 }
3766 
3767 private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr, const size_t count) @trusted nothrow
3768 {
3769     if (!count)
3770         return 0;
3771 
3772     const size_t elementSize = element.tsize;
3773     if (!elementSize)
3774         return 0;
3775 
3776     static bool hasCustomToHash(const scope TypeInfo value) @trusted pure nothrow
3777     {
3778         const element = getElement(value);
3779 
3780         if (const struct_ = cast(const TypeInfo_Struct) element)
3781             return !!struct_.xtoHash;
3782 
3783         return cast(const TypeInfo_Array) element
3784             || cast(const TypeInfo_AssociativeArray) element
3785             || cast(const ClassInfo) element
3786             || cast(const TypeInfo_Interface) element;
3787     }
3788 
3789     if (!hasCustomToHash(element))
3790         return hashOf(ptr[0 .. elementSize * count]);
3791 
3792     size_t hash = 0;
3793     foreach (size_t i; 0 .. count)
3794         hash = hashOf(element.getHash(ptr + i * elementSize), hash);
3795     return hash;
3796 }
3797 
3798 /// Provide the .dup array property.
3799 @property auto dup(T)(T[] a)
3800     if (!is(const(T) : T))
3801 {
3802     import core.internal.traits : Unconst;
3803     import core.internal.array.duplication : _dup;
3804     static assert(is(T : Unconst!T), "Cannot implicitly convert type "~T.stringof~
3805                   " to "~Unconst!T.stringof~" in dup.");
3806 
3807     return _dup!(T, Unconst!T)(a);
3808 }
3809 
3810 ///
3811 @safe unittest
3812 {
3813     auto arr = [1, 2];
3814     auto arr2 = arr.dup;
3815     arr[0] = 0;
3816     assert(arr == [0, 2]);
3817     assert(arr2 == [1, 2]);
3818 }
3819 
3820 /// ditto
3821 // const overload to support implicit conversion to immutable (unique result, see DIP29)
3822 @property T[] dup(T)(const(T)[] a)
3823     if (is(const(T) : T))
3824 {
3825     import core.internal.array.duplication : _dup;
3826     return _dup!(const(T), T)(a);
3827 }
3828 
3829 
3830 /// Provide the .idup array property.
3831 @property immutable(T)[] idup(T)(T[] a)
3832 {
3833     import core.internal.array.duplication : _dup;
3834     static assert(is(T : immutable(T)), "Cannot implicitly convert type "~T.stringof~
3835                   " to immutable in idup.");
3836     return _dup!(T, immutable(T))(a);
3837 }
3838 
3839 /// ditto
3840 @property immutable(T)[] idup(T:void)(const(T)[] a)
3841 {
3842     return a.dup;
3843 }
3844 
3845 ///
3846 @safe unittest
3847 {
3848     char[] arr = ['a', 'b', 'c'];
3849     string s = arr.idup;
3850     arr[0] = '.';
3851     assert(s == "abc");
3852 }
3853 
3854 // HACK:  This is a lie.  `_d_arraysetcapacity` is neither `nothrow` nor `pure`, but this lie is
3855 // necessary for now to prevent breaking code.
3856 private extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* arrptr) pure nothrow;
3857 
3858 /**
3859 (Property) Gets the current _capacity of a slice. The _capacity is the size
3860 that the slice can grow to before the underlying array must be
3861 reallocated or extended.
3862 
3863 If an append must reallocate a slice with no possibility of extension, then
3864 `0` is returned. This happens when the slice references a static array, or
3865 if another slice references elements past the end of the current slice.
3866 
3867 Note: The _capacity of a slice may be impacted by operations on other slices.
3868 */
3869 @property size_t capacity(T)(T[] arr) pure nothrow @trusted
3870 {
3871     return _d_arraysetcapacity(typeid(T[]), 0, cast(void[]*)&arr);
3872 }
3873 
3874 ///
3875 @safe unittest
3876 {
3877     //Static array slice: no capacity
3878     int[4] sarray = [1, 2, 3, 4];
3879     int[]  slice  = sarray[];
3880     assert(sarray.capacity == 0);
3881     //Appending to slice will reallocate to a new array
3882     slice ~= 5;
3883     assert(slice.capacity >= 5);
3884 
3885     //Dynamic array slices
3886     int[] a = [1, 2, 3, 4];
3887     int[] b = a[1 .. $];
3888     int[] c = a[1 .. $ - 1];
3889     debug(SENTINEL) {} else // non-zero capacity very much depends on the array and GC implementation
3890     {
3891         assert(a.capacity != 0);
3892         assert(a.capacity == b.capacity + 1); //both a and b share the same tail
3893     }
3894     assert(c.capacity == 0);              //an append to c must relocate c.
3895 }
3896 
3897 /**
3898 Reserves capacity for a slice. The capacity is the size
3899 that the slice can grow to before the underlying array must be
3900 reallocated or extended.
3901 
3902 Returns: The new capacity of the array (which may be larger than
3903 the requested capacity).
3904 */
3905 size_t reserve(T)(ref T[] arr, size_t newcapacity) pure nothrow @trusted
3906 {
3907     if (__ctfe)
3908         return newcapacity;
3909     else
3910         return _d_arraysetcapacity(typeid(T[]), newcapacity, cast(void[]*)&arr);
3911 }
3912 
3913 ///
3914 @safe unittest
3915 {
3916     //Static array slice: no capacity. Reserve relocates.
3917     int[4] sarray = [1, 2, 3, 4];
3918     int[]  slice  = sarray[];
3919     auto u = slice.reserve(8);
3920     assert(u >= 8);
3921     assert(&sarray[0] !is &slice[0]);
3922     assert(slice.capacity == u);
3923 
3924     //Dynamic array slices
3925     int[] a = [1, 2, 3, 4];
3926     a.reserve(8); //prepare a for appending 4 more items
3927     auto p = &a[0];
3928     u = a.capacity;
3929     a ~= [5, 6, 7, 8];
3930     assert(p == &a[0]);      //a should not have been reallocated
3931     assert(u == a.capacity); //a should not have been extended
3932 }
3933 
3934 // https://issues.dlang.org/show_bug.cgi?id=12330, reserve() at CTFE time
3935 @safe unittest
3936 {
3937     int[] foo() {
3938         int[] result;
3939         auto a = result.reserve = 5;
3940         assert(a == 5);
3941         return result;
3942     }
3943     enum r = foo();
3944 }
3945 
3946 // Issue 6646: should be possible to use array.reserve from SafeD.
3947 @safe unittest
3948 {
3949     int[] a;
3950     a.reserve(10);
3951 }
3952 
3953 // HACK:  This is a lie.  `_d_arrayshrinkfit` is not `nothrow`, but this lie is necessary
3954 // for now to prevent breaking code.
3955 private extern (C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow;
3956 
3957 /**
3958 Assume that it is safe to append to this array. Appends made to this array
3959 after calling this function may append in place, even if the array was a
3960 slice of a larger array to begin with.
3961 
3962 Use this only when it is certain there are no elements in use beyond the
3963 array in the memory block.  If there are, those elements will be
3964 overwritten by appending to this array.
3965 
3966 Warning: Calling this function, and then using references to data located after the
3967 given array results in undefined behavior.
3968 
3969 Returns:
3970   The input is returned.
3971 */
3972 auto ref inout(T[]) assumeSafeAppend(T)(auto ref inout(T[]) arr) nothrow @system
3973 {
3974     _d_arrayshrinkfit(typeid(T[]), *(cast(void[]*)&arr));
3975     return arr;
3976 }
3977 
3978 ///
3979 @system unittest
3980 {
3981     int[] a = [1, 2, 3, 4];
3982 
3983     // Without assumeSafeAppend. Appending relocates.
3984     int[] b = a [0 .. 3];
3985     b ~= 5;
3986     assert(a.ptr != b.ptr);
3987 
3988     debug(SENTINEL) {} else
3989     {
3990         // With assumeSafeAppend. Appending overwrites.
3991         int[] c = a [0 .. 3];
3992         c.assumeSafeAppend() ~= 5;
3993         assert(a.ptr == c.ptr);
3994     }
3995 }
3996 
3997 @system unittest
3998 {
3999     int[] arr;
4000     auto newcap = arr.reserve(2000);
4001     assert(newcap >= 2000);
4002     assert(newcap == arr.capacity);
4003     auto ptr = arr.ptr;
4004     foreach (i; 0..2000)
4005         arr ~= i;
4006     assert(ptr == arr.ptr);
4007     arr = arr[0..1];
4008     arr.assumeSafeAppend();
4009     arr ~= 5;
4010     assert(ptr == arr.ptr);
4011 }
4012 
4013 @system unittest
4014 {
4015     int[] arr = [1, 2, 3];
4016     void foo(ref int[] i)
4017     {
4018         i ~= 5;
4019     }
4020     arr = arr[0 .. 2];
4021     foo(assumeSafeAppend(arr)); //pass by ref
4022     assert(arr[]==[1, 2, 5]);
4023     arr = arr[0 .. 1].assumeSafeAppend(); //pass by value
4024 }
4025 
4026 // https://issues.dlang.org/show_bug.cgi?id=10574
4027 @system unittest
4028 {
4029     int[] a;
4030     immutable(int[]) b;
4031     auto a2 = &assumeSafeAppend(a);
4032     auto b2 = &assumeSafeAppend(b);
4033     auto a3 = assumeSafeAppend(a[]);
4034     auto b3 = assumeSafeAppend(b[]);
4035     assert(is(typeof(*a2) == int[]));
4036     assert(is(typeof(*b2) == immutable(int[])));
4037     assert(is(typeof(a3) == int[]));
4038     assert(is(typeof(b3) == immutable(int[])));
4039 }
4040 
4041 private void _doPostblit(T)(T[] arr)
4042 {
4043     // infer static postblit type, run postblit if any
4044     static if (__traits(hasPostblit, T))
4045     {
4046         static if (__traits(isStaticArray, T) && is(T : E[], E))
4047             _doPostblit(cast(E[]) arr);
4048         else static if (!is(typeof(arr[0].__xpostblit())) && is(immutable T == immutable U, U))
4049             foreach (ref elem; (() @trusted => cast(U[]) arr)())
4050                 elem.__xpostblit();
4051         else
4052             foreach (ref elem; arr)
4053                 elem.__xpostblit();
4054     }
4055 }
4056 
4057 /**
4058 Destroys the given object and optionally resets to initial state. It's used to
4059 _destroy an object, calling its destructor or finalizer so it no longer
4060 references any other objects. It does $(I not) initiate a GC cycle or free
4061 any GC memory.
4062 If `initialize` is supplied `false`, the object is considered invalid after
4063 destruction, and should not be referenced.
4064 */
4065 void destroy(bool initialize = true, T)(ref T obj) if (is(T == struct))
4066 {
4067     import core.internal.destruction : destructRecurse;
4068 
4069     destructRecurse(obj);
4070 
4071     static if (initialize)
4072     {
4073         import core.internal.lifetime : emplaceInitializer;
4074         emplaceInitializer(obj); // emplace T.init
4075     }
4076 }
4077 
4078 @safe unittest
4079 {
4080     struct A { string s = "A";  }
4081     A a = {s: "B"};
4082     assert(a.s == "B");
4083     a.destroy;
4084     assert(a.s == "A");
4085 }
4086 
4087 nothrow @safe @nogc unittest
4088 {
4089     {
4090         struct A { string s = "A";  }
4091         A a;
4092         a.s = "asd";
4093         destroy!false(a);
4094         assert(a.s == "asd");
4095         destroy(a);
4096         assert(a.s == "A");
4097     }
4098     {
4099         static int destroyed = 0;
4100         struct C
4101         {
4102             string s = "C";
4103             ~this() nothrow @safe @nogc
4104             {
4105                 destroyed ++;
4106             }
4107         }
4108 
4109         struct B
4110         {
4111             C c;
4112             string s = "B";
4113             ~this() nothrow @safe @nogc
4114             {
4115                 destroyed ++;
4116             }
4117         }
4118         B a;
4119         a.s = "asd";
4120         a.c.s = "jkl";
4121         destroy!false(a);
4122         assert(destroyed == 2);
4123         assert(a.s == "asd");
4124         assert(a.c.s == "jkl" );
4125         destroy(a);
4126         assert(destroyed == 4);
4127         assert(a.s == "B");
4128         assert(a.c.s == "C" );
4129     }
4130 }
4131 
4132 private extern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true) nothrow;
4133 
4134 /// ditto
4135 void destroy(bool initialize = true, T)(T obj) if (is(T == class))
4136 {
4137     static if (__traits(getLinkage, T) == "C++")
4138     {
4139         static if (__traits(hasMember, T, "__xdtor"))
4140             obj.__xdtor();
4141 
4142         static if (initialize)
4143         {
4144             const initializer = __traits(initSymbol, T);
4145             (cast(void*)obj)[0 .. initializer.length] = initializer[];
4146         }
4147     }
4148     else
4149     {
4150         // Bypass overloaded opCast
4151         auto ptr = (() @trusted => *cast(void**) &obj)();
4152         rt_finalize2(ptr, true, initialize);
4153     }
4154 }
4155 
4156 /// ditto
4157 void destroy(bool initialize = true, T)(T obj) if (is(T == interface))
4158 {
4159     static assert(__traits(getLinkage, T) == "D", "Invalid call to destroy() on extern(" ~ __traits(getLinkage, T) ~ ") interface");
4160 
4161     destroy!initialize(cast(Object)obj);
4162 }
4163 
4164 /// Reference type demonstration
4165 @system unittest
4166 {
4167     class C
4168     {
4169         struct Agg
4170         {
4171             static int dtorCount;
4172 
4173             int x = 10;
4174             ~this() { dtorCount++; }
4175         }
4176 
4177         static int dtorCount;
4178 
4179         string s = "S";
4180         Agg a;
4181         ~this() { dtorCount++; }
4182     }
4183 
4184     C c = new C();
4185     assert(c.dtorCount == 0);   // destructor not yet called
4186     assert(c.s == "S");         // initial state `c.s` is `"S"`
4187     assert(c.a.dtorCount == 0); // destructor not yet called
4188     assert(c.a.x == 10);        // initial state `c.a.x` is `10`
4189     c.s = "T";
4190     c.a.x = 30;
4191     assert(c.s == "T");         // `c.s` is `"T"`
4192     destroy(c);
4193     assert(c.dtorCount == 1);   // `c`'s destructor was called
4194     assert(c.s == "S");         // `c.s` is back to its inital state, `"S"`
4195     assert(c.a.dtorCount == 1); // `c.a`'s destructor was called
4196     assert(c.a.x == 10);        // `c.a.x` is back to its inital state, `10`
4197 
4198     // check C++ classes work too!
4199     extern (C++) class CPP
4200     {
4201         struct Agg
4202         {
4203             __gshared int dtorCount;
4204 
4205             int x = 10;
4206             ~this() { dtorCount++; }
4207         }
4208 
4209         __gshared int dtorCount;
4210 
4211         string s = "S";
4212         Agg a;
4213         ~this() { dtorCount++; }
4214     }
4215 
4216     CPP cpp = new CPP();
4217     assert(cpp.dtorCount == 0);   // destructor not yet called
4218     assert(cpp.s == "S");         // initial state `cpp.s` is `"S"`
4219     assert(cpp.a.dtorCount == 0); // destructor not yet called
4220     assert(cpp.a.x == 10);        // initial state `cpp.a.x` is `10`
4221     cpp.s = "T";
4222     cpp.a.x = 30;
4223     assert(cpp.s == "T");         // `cpp.s` is `"T"`
4224     destroy!false(cpp);           // destroy without initialization
4225     assert(cpp.dtorCount == 1);   // `cpp`'s destructor was called
4226     assert(cpp.s == "T");         // `cpp.s` is not initialized
4227     assert(cpp.a.dtorCount == 1); // `cpp.a`'s destructor was called
4228     assert(cpp.a.x == 30);        // `cpp.a.x` is not initialized
4229     destroy(cpp);
4230     assert(cpp.dtorCount == 2);   // `cpp`'s destructor was called again
4231     assert(cpp.s == "S");         // `cpp.s` is back to its inital state, `"S"`
4232     assert(cpp.a.dtorCount == 2); // `cpp.a`'s destructor was called again
4233     assert(cpp.a.x == 10);        // `cpp.a.x` is back to its inital state, `10`
4234 }
4235 
4236 /// Value type demonstration
4237 @safe unittest
4238 {
4239     int i;
4240     assert(i == 0);           // `i`'s initial state is `0`
4241     i = 1;
4242     assert(i == 1);           // `i` changed to `1`
4243     destroy!false(i);
4244     assert(i == 1);           // `i` was not initialized
4245     destroy(i);
4246     assert(i == 0);           // `i` is back to its initial state `0`
4247 }
4248 
4249 @system unittest
4250 {
4251     extern(C++)
4252     static class C
4253     {
4254         void* ptr;
4255         this() {}
4256     }
4257 
4258     destroy!false(new C());
4259     destroy!true(new C());
4260 }
4261 
4262 @system unittest
4263 {
4264     interface I { }
4265     {
4266         class A: I { string s = "A"; this() {} }
4267         auto a = new A, b = new A;
4268         a.s = b.s = "asd";
4269         destroy(a);
4270         assert(a.s == "A");
4271 
4272         I i = b;
4273         destroy(i);
4274         assert(b.s == "A");
4275     }
4276     {
4277         static bool destroyed = false;
4278         class B: I
4279         {
4280             string s = "B";
4281             this() {}
4282             ~this()
4283             {
4284                 destroyed = true;
4285             }
4286         }
4287         auto a = new B, b = new B;
4288         a.s = b.s = "asd";
4289         destroy(a);
4290         assert(destroyed);
4291         assert(a.s == "B");
4292 
4293         destroyed = false;
4294         I i = b;
4295         destroy(i);
4296         assert(destroyed);
4297         assert(b.s == "B");
4298     }
4299     // this test is invalid now that the default ctor is not run after clearing
4300     version (none)
4301     {
4302         class C
4303         {
4304             string s;
4305             this()
4306             {
4307                 s = "C";
4308             }
4309         }
4310         auto a = new C;
4311         a.s = "asd";
4312         destroy(a);
4313         assert(a.s == "C");
4314     }
4315 }
4316 
4317 nothrow @safe @nogc unittest
4318 {
4319     {
4320         struct A { string s = "A";  }
4321         A a;
4322         a.s = "asd";
4323         destroy!false(a);
4324         assert(a.s == "asd");
4325         destroy(a);
4326         assert(a.s == "A");
4327     }
4328     {
4329         static int destroyed = 0;
4330         struct C
4331         {
4332             string s = "C";
4333             ~this() nothrow @safe @nogc
4334             {
4335                 destroyed ++;
4336             }
4337         }
4338 
4339         struct B
4340         {
4341             C c;
4342             string s = "B";
4343             ~this() nothrow @safe @nogc
4344             {
4345                 destroyed ++;
4346             }
4347         }
4348         B a;
4349         a.s = "asd";
4350         a.c.s = "jkl";
4351         destroy!false(a);
4352         assert(destroyed == 2);
4353         assert(a.s == "asd");
4354         assert(a.c.s == "jkl" );
4355         destroy(a);
4356         assert(destroyed == 4);
4357         assert(a.s == "B");
4358         assert(a.c.s == "C" );
4359     }
4360 }
4361 
4362 nothrow unittest
4363 {
4364     // Bugzilla 20049: Test to ensure proper behavior of `nothrow` destructors
4365     class C
4366     {
4367         static int dtorCount = 0;
4368         this() nothrow {}
4369         ~this() nothrow { dtorCount++; }
4370     }
4371 
4372     auto c = new C;
4373     destroy(c);
4374     assert(C.dtorCount == 1);
4375 }
4376 
4377 // https://issues.dlang.org/show_bug.cgi?id=22832
4378 nothrow unittest
4379 {
4380     static struct A {}
4381     static class B
4382     {
4383         A opCast(T : A)() { return A(); }
4384     }
4385 
4386     destroy(B.init);
4387 }
4388 
4389 // make sure destroy!false skips re-initialization
4390 unittest
4391 {
4392     static struct S { int x; }
4393     static class C { int x; }
4394     static extern(C++) class Cpp { int x; }
4395 
4396     static void test(T)(T inst)
4397     {
4398         inst.x = 123;
4399         destroy!false(inst);
4400         assert(inst.x == 123, T.stringof);
4401     }
4402 
4403     test(S());
4404     test(new C());
4405     test(new Cpp());
4406 }
4407 
4408 /// ditto
4409 void destroy(bool initialize = true, T)(ref T obj)
4410 if (__traits(isStaticArray, T))
4411 {
4412     foreach_reverse (ref e; obj[])
4413         destroy!initialize(e);
4414 }
4415 
4416 @safe unittest
4417 {
4418     int[2] a;
4419     a[0] = 1;
4420     a[1] = 2;
4421     destroy!false(a);
4422     assert(a == [ 1, 2 ]);
4423     destroy(a);
4424     assert(a == [ 0, 0 ]);
4425 }
4426 
4427 @safe unittest
4428 {
4429     static struct vec2f {
4430         float[2] values;
4431         alias values this;
4432     }
4433 
4434     vec2f v;
4435     destroy!(true, vec2f)(v);
4436 }
4437 
4438 @system unittest
4439 {
4440     // Bugzilla 15009
4441     static string op;
4442     static struct S
4443     {
4444         int x;
4445         this(int x) { op ~= "C" ~ cast(char)('0'+x); this.x = x; }
4446         this(this)  { op ~= "P" ~ cast(char)('0'+x); }
4447         ~this()     { op ~= "D" ~ cast(char)('0'+x); }
4448     }
4449 
4450     {
4451         S[2] a1 = [S(1), S(2)];
4452         op = "";
4453     }
4454     assert(op == "D2D1");   // built-in scope destruction
4455     {
4456         S[2] a1 = [S(1), S(2)];
4457         op = "";
4458         destroy(a1);
4459         assert(op == "D2D1");   // consistent with built-in behavior
4460     }
4461 
4462     {
4463         S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];
4464         op = "";
4465     }
4466     assert(op == "D4D3D2D1");
4467     {
4468         S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];
4469         op = "";
4470         destroy(a2);
4471         assert(op == "D4D3D2D1", op);
4472     }
4473 }
4474 
4475 /// ditto
4476 void destroy(bool initialize = true, T)(ref T obj)
4477     if (!is(T == struct) && !is(T == interface) && !is(T == class) && !__traits(isStaticArray, T))
4478 {
4479     static if (initialize)
4480         obj = T.init;
4481 }
4482 
4483 @safe unittest
4484 {
4485     {
4486         int a = 42;
4487         destroy!false(a);
4488         assert(a == 42);
4489         destroy(a);
4490         assert(a == 0);
4491     }
4492     {
4493         float a = 42;
4494         destroy!false(a);
4495         assert(a == 42);
4496         destroy(a);
4497         assert(a != a); // isnan
4498     }
4499 }
4500 
4501 @safe unittest
4502 {
4503     // Bugzilla 14746
4504     static struct HasDtor
4505     {
4506         ~this() { assert(0); }
4507     }
4508     static struct Owner
4509     {
4510         HasDtor* ptr;
4511         alias ptr this;
4512     }
4513 
4514     Owner o;
4515     assert(o.ptr is null);
4516     destroy(o);     // must not reach in HasDtor.__dtor()
4517 }
4518 
4519 /* ************************************************************************
4520                            COMPILER SUPPORT
4521 The compiler lowers certain expressions to instantiations of the following
4522 templates.  They must be implicitly imported, which is why they are here
4523 in this file. They must also be `public` as they must be visible from the
4524 scope in which they are instantiated.  They are explicitly undocumented as
4525 they are only intended to be instantiated by the compiler, not the user.
4526 **************************************************************************/
4527 
4528 public import core.internal.entrypoint : _d_cmain;
4529 
4530 public import core.internal.array.appending : _d_arrayappendT;
4531 version (D_ProfileGC)
4532 {
4533     public import core.internal.array.appending : _d_arrayappendTTrace;
4534     public import core.internal.array.concatenation : _d_arraycatnTXTrace;
4535 }
4536 public import core.internal.array.appending : _d_arrayappendcTXImpl;
4537 public import core.internal.array.comparison : __cmp;
4538 public import core.internal.array.equality : __equals;
4539 public import core.internal.array.casting: __ArrayCast;
4540 public import core.internal.array.concatenation : _d_arraycatnTX;
4541 public import core.internal.array.construction : _d_arrayctor;
4542 public import core.internal.array.construction : _d_arraysetctor;
4543 public import core.internal.array.arrayassign : _d_arrayassign_l;
4544 public import core.internal.array.arrayassign : _d_arrayassign_r;
4545 public import core.internal.array.arrayassign : _d_arraysetassign;
4546 public import core.internal.array.capacity: _d_arraysetlengthTImpl;
4547 
4548 public import core.internal.dassert: _d_assert_fail;
4549 
4550 public import core.internal.destruction: __ArrayDtor;
4551 
4552 public import core.internal.moving: __move_post_blt;
4553 
4554 public import core.internal.postblit: __ArrayPostblit;
4555 
4556 public import core.internal.switch_: __switch;
4557 public import core.internal.switch_: __switch_error;
4558 
4559 public import core.lifetime : _d_delstructImpl;
4560 public import core.lifetime : _d_newThrowable;
4561 public import core.lifetime : _d_newclassT;
4562 public import core.lifetime : _d_newclassTTrace;
4563 
4564 public @trusted @nogc nothrow pure extern (C) void _d_delThrowable(scope Throwable);
4565 
4566 // Compare class and interface objects for ordering.
4567 int __cmp(C1, C2)(C1 lhs, C2 rhs)
4568 if ((is(C1 : const(Object)) || (is(C1 == interface) && (__traits(getLinkage, C1) == "D"))) &&
4569     (is(C2 : const(Object)) || (is(C2 == interface) && (__traits(getLinkage, C2) == "D"))))
4570 {
4571     static if (is(C1 == typeof(null)) && is(C2 == typeof(null)))
4572     {
4573         return 0;
4574     }
4575     else static if (is(C1 == typeof(null)))
4576     {
4577         // Regard null references as always being "less than"
4578         return -1;
4579     }
4580     else static if (is(C2 == typeof(null)))
4581     {
4582         return 1;
4583     }
4584     else
4585     {
4586         if (lhs is rhs)
4587             return 0;
4588         if (lhs is null)
4589             return -1;
4590         if (rhs is null)
4591             return 1;
4592         return lhs.opCmp(rhs);
4593     }
4594 }
4595 
4596 // objects
4597 @safe unittest
4598 {
4599     class C
4600     {
4601         int i;
4602         this(int i) { this.i = i; }
4603 
4604         override int opCmp(Object c) const @safe
4605         {
4606             return i - (cast(C)c).i;
4607         }
4608     }
4609 
4610     auto c1 = new C(1);
4611     auto c2 = new C(2);
4612     assert(__cmp(c1, null) > 0);
4613     assert(__cmp(null, c1) < 0);
4614     assert(__cmp(c1, c1) == 0);
4615     assert(__cmp(c1, c2) < 0);
4616     assert(__cmp(c2, c1) > 0);
4617 
4618     assert(__cmp([c1, c1][], [c2, c2][]) < 0);
4619     assert(__cmp([c2, c2], [c1, c1]) > 0);
4620 }
4621 
4622 // structs
4623 @safe unittest
4624 {
4625     struct C
4626     {
4627         ubyte i;
4628         this(ubyte i) { this.i = i; }
4629     }
4630 
4631     auto c1 = C(1);
4632     auto c2 = C(2);
4633 
4634     assert(__cmp([c1, c1][], [c2, c2][]) < 0);
4635     assert(__cmp([c2, c2], [c1, c1]) > 0);
4636     assert(__cmp([c2, c2], [c2, c1]) > 0);
4637 }
4638 
4639 @safe unittest
4640 {
4641     auto a = "hello"c;
4642 
4643     assert(a >  "hel");
4644     assert(a >= "hel");
4645     assert(a <  "helloo");
4646     assert(a <= "helloo");
4647     assert(a >  "betty");
4648     assert(a >= "betty");
4649     assert(a == "hello");
4650     assert(a <= "hello");
4651     assert(a >= "hello");
4652     assert(a <  "я");
4653 }
4654 
4655 // Used in Exception Handling LSDA tables to 'wrap' C++ type info
4656 // so it can be distinguished from D TypeInfo
4657 class __cpp_type_info_ptr
4658 {
4659     void* ptr;          // opaque pointer to C++ RTTI type info
4660 }
4661 
4662 // Compiler hook into the runtime implementation of array (vector) operations.
4663 template _arrayOp(Args...)
4664 {
4665     import core.internal.array.operations;
4666     alias _arrayOp = arrayOp!Args;
4667 }
4668 
4669 public import core.builtins : __ctfeWrite;
4670 
4671 /**
4672 
4673 Provides an "inline import", i.e. an `import` that is only available for a
4674 limited lookup. For example:
4675 
4676 ---
4677 void fun(imported!"std.stdio".File input)
4678 {
4679     ... use File from std.stdio normally ...
4680 }
4681 ---
4682 
4683 There is no need to import `std.stdio` at top level, so `fun` carries its own
4684 dependencies. The same approach can be used for template constraints:
4685 
4686 ---
4687 void fun(T)(imported!"std.stdio".File input, T value)
4688 if (imported!"std.traits".isIntegral!T)
4689 {
4690     ...
4691 }
4692 ---
4693 
4694 An inline import may be used in conjunction with the `with` statement as well.
4695 Inside the scope controlled by `with`, all symbols in the imported module are
4696 made available:
4697 
4698 ---
4699 void fun()
4700 {
4701     with (imported!"std.datetime")
4702     with (imported!"std.stdio")
4703     {
4704         Clock.currTime.writeln;
4705     }
4706 }
4707 ---
4708 
4709 The advantages of inline imports over top-level uses of the `import` declaration
4710 are the following:
4711 
4712 $(UL
4713 $(LI The `imported` template specifies dependencies at declaration level, not at
4714 module level. This allows reasoning about the dependency cost of declarations in
4715 separation instead of aggregated at module level.)
4716 $(LI Declarations using `imported` are easier to move around because they don't
4717 require top-level context, making for simpler and quicker refactorings.)
4718 $(LI Declarations using `imported` scale better with templates. This is because
4719 templates that are not instantiated do not have their parameters and constraints
4720 instantiated, so additional modules are not imported without necessity. This
4721 makes the cost of unused templates negligible. Dependencies are pulled on a need
4722 basis depending on the declarations used by client code.)
4723 )
4724 
4725 The use of `imported` also has drawbacks:
4726 
4727 $(UL
4728 $(LI If most declarations in a module need the same imports, then factoring them
4729 at top level, outside the declarations, is simpler than repeating them.)
4730 $(LI Traditional dependency-tracking tools such as make and other build systems
4731 assume file-level dependencies and need special tooling (such as rdmd) in order
4732 to work efficiently.)
4733 $(LI Dependencies at the top of a module are easier to inspect quickly than
4734 dependencies spread throughout the module.)
4735 )
4736 
4737 See_Also: The $(HTTP forum.dlang.org/post/tzqzmqhankrkbrfsrmbo@forum.dlang.org,
4738 forum discussion) that led to the creation of the `imported` facility. Credit is
4739 due to Daniel Nielsen and Dominikus Dittes Scherkl.
4740 
4741 */
4742 template imported(string moduleName)
4743 {
4744     mixin("import imported = " ~ moduleName ~ ";");
4745 }