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