gimple-low: Remove .ASAN_MARK calls on TREE_STATIC variables [PR113531]
[official-gcc.git] / libphobos / libdruntime / object.d
blob5589c0a884ffde41b477d2a84d66a65b5aa45424
1 /**
2 * $(SCRIPT inhibitQuickIndex = 1;)
3 * $(DIVC quickindex,
4 * $(BOOKTABLE,
5 * $(TR $(TH Category) $(TH Symbols))
6 * $(TR $(TD Arrays) $(TD
7 * $(MYREF assumeSafeAppend)
8 * $(MYREF capacity)
9 * $(A #.dup.2, $(TT dup))
10 * $(MYREF idup)
11 * $(MYREF reserve)
12 * ))
13 * $(TR $(TD Associative arrays) $(TD
14 * $(MYREF byKey)
15 * $(MYREF byKeyValue)
16 * $(MYREF byValue)
17 * $(MYREF clear)
18 * $(MYREF dup)
19 * $(MYREF get)
20 * $(MYREF keys)
21 * $(MYREF rehash)
22 * $(MYREF require)
23 * $(MYREF update)
24 * $(MYREF values)
25 * ))
26 * $(TR $(TD General) $(TD
27 * $(MYREF destroy)
28 * $(MYREF hashOf)
29 * $(MYREF imported)
30 * $(MYREF noreturn)
31 * ))
32 * $(TR $(TD Classes) $(TD
33 * $(MYREF Error)
34 * $(MYREF Exception)
35 * $(MYREF Object)
36 * $(MYREF opEquals)
37 * $(MYREF Throwable)
38 * ))
39 * $(TR $(TD Type info) $(TD
40 * $(MYREF Interface)
41 * $(MYREF ModuleInfo)
42 * $(MYREF OffsetTypeInfo)
43 * $(MYREF RTInfoImpl)
44 * $(MYREF rtinfoNoPointers)
45 * $(MYREF TypeInfo)
46 * $(MYREF TypeInfo_Class)
47 * ))
48 * ))
50 * Forms the symbols available to all D programs. Includes Object, which is
51 * the root of the class object hierarchy. This module is implicitly
52 * imported.
54 * Copyright: Copyright Digital Mars 2000 - 2011.
55 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
56 * Authors: Walter Bright, Sean Kelly
57 * Source: $(DRUNTIMESRC object.d)
60 module object;
62 alias size_t = typeof(int.sizeof);
63 alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0);
65 alias sizediff_t = ptrdiff_t; // For backwards compatibility only.
66 /**
67 * Bottom type.
68 * See $(DDSUBLINK spec/type, noreturn).
70 alias noreturn = typeof(*null);
72 alias hash_t = size_t; // For backwards compatibility only.
73 alias equals_t = bool; // For backwards compatibility only.
75 alias string = immutable(char)[];
76 alias wstring = immutable(wchar)[];
77 alias dstring = immutable(dchar)[];
79 version (D_ObjectiveC)
81 deprecated("explicitly import `selector` instead using: `import core.attribute : selector;`")
82 public import core.attribute : selector;
84 version (Posix) public import core.attribute : gnuAbiTag;
86 // Some ABIs use a complex varargs implementation requiring TypeInfo.argTypes().
87 version (GNU)
89 // No TypeInfo-based core.vararg.va_arg().
91 else version (X86_64)
93 version (DigitalMars) version = WithArgTypes;
94 else version (Windows) { /* no need for Win64 ABI */ }
95 else version = WithArgTypes;
97 else version (AArch64)
99 // Apple uses a trivial varargs implementation
100 version (OSX) {}
101 else version (iOS) {}
102 else version (TVOS) {}
103 else version (WatchOS) {}
104 else version = WithArgTypes;
108 * All D class objects inherit from Object.
110 class Object
113 * Convert Object to a human readable string.
115 string toString()
117 return typeid(this).name;
120 @system unittest
122 enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
123 enum fqn_unittest = "object.Object." ~ unittest_sym_name; // object.__unittest_LX_CY
125 class C {}
127 Object obj = new Object;
128 C c = new C;
130 assert(obj.toString() == "object.Object");
131 assert(c.toString() == fqn_unittest ~ ".C");
135 * Compute hash function for Object.
137 size_t toHash() @trusted nothrow
139 // BUG: this prevents a compacting GC from working, needs to be fixed
140 size_t addr = cast(size_t) cast(void*) this;
141 // The bottom log2((void*).alignof) bits of the address will always
142 // be 0. Moreover it is likely that each Object is allocated with a
143 // separate call to malloc. The alignment of malloc differs from
144 // platform to platform, but rather than having special cases for
145 // each platform it is safe to use a shift of 4. To minimize
146 // collisions in the low bits it is more important for the shift to
147 // not be too small than for the shift to not be too big.
148 return addr ^ (addr >>> 4);
152 * Compare with another Object obj.
153 * Returns:
154 * $(TABLE
155 * $(TR $(TD this < obj) $(TD < 0))
156 * $(TR $(TD this == obj) $(TD 0))
157 * $(TR $(TD this > obj) $(TD > 0))
160 int opCmp(Object o)
162 // BUG: this prevents a compacting GC from working, needs to be fixed
163 //return cast(int)cast(void*)this - cast(int)cast(void*)o;
165 throw new Exception("need opCmp for class " ~ typeid(this).name);
166 //return this !is o;
169 @system unittest
171 Object obj = new Object;
173 bool gotCaught;
176 obj.opCmp(new Object);
178 catch (Exception e)
180 gotCaught = true;
181 assert(e.msg == "need opCmp for class object.Object");
183 assert(gotCaught);
187 * Test whether $(D this) is equal to $(D o).
188 * The default implementation only compares by identity (using the $(D is) operator).
189 * Generally, overrides and overloads for $(D opEquals) should attempt to compare objects by their contents.
190 * A class will most likely want to add an overload that takes your specific type as the argument
191 * and does the content comparison. Then you can override this and forward it to your specific
192 * typed overload with a cast. Remember to check for `null` on the typed overload.
194 * Examples:
195 * ---
196 * class Child {
197 * int contents;
198 * // the typed overload first. It can use all the attribute you want
199 * bool opEquals(const Child c) const @safe pure nothrow @nogc
201 * if (c is null)
202 * return false;
203 * return this.contents == c.contents;
206 * // and now the generic override forwards with a cast
207 * override bool opEquals(Object o)
209 * return this.opEquals(cast(Child) o);
212 * ---
214 bool opEquals(Object o)
216 return this is o;
219 interface Monitor
221 void lock();
222 void unlock();
226 * Create instance of class specified by the fully qualified name
227 * classname.
228 * The class must either have no constructors or have
229 * a default constructor.
230 * Returns:
231 * null if failed
232 * Example:
233 * ---
234 * module foo.bar;
236 * class C
238 * this() { x = 10; }
239 * int x;
242 * void main()
244 * auto c = cast(C)Object.factory("foo.bar.C");
245 * assert(c !is null && c.x == 10);
247 * ---
249 static Object factory(string classname)
251 auto ci = TypeInfo_Class.find(classname);
252 if (ci)
254 return ci.create();
256 return null;
259 @system unittest
261 Object valid_obj = Object.factory("object.Object");
262 Object invalid_obj = Object.factory("object.__this_class_doesnt_exist__");
264 assert(valid_obj !is null);
265 assert(invalid_obj is null);
270 Implementation for class opEquals override. Calls the class-defined methods after a null check.
271 Please note this is not nogc right now, even if your implementation is, because of
272 the typeinfo name string compare. This is because of dmd's dll implementation. However,
273 it can infer to @safe if your class' opEquals is.
275 bool opEquals(LHS, RHS)(LHS lhs, RHS rhs)
276 if ((is(LHS : const Object) || is(LHS : const shared Object)) &&
277 (is(RHS : const Object) || is(RHS : const shared Object)))
279 static if (__traits(compiles, lhs.opEquals(rhs)) && __traits(compiles, rhs.opEquals(lhs)))
281 // If aliased to the same object or both null => equal
282 if (lhs is rhs) return true;
284 // If either is null => non-equal
285 if (lhs is null || rhs is null) return false;
287 if (!lhs.opEquals(rhs)) return false;
289 // If same exact type => one call to method opEquals
290 if (typeid(lhs) is typeid(rhs) ||
291 !__ctfe && typeid(lhs).opEquals(typeid(rhs)))
292 /* CTFE doesn't like typeid much. 'is' works, but opEquals doesn't:
293 https://issues.dlang.org/show_bug.cgi?id=7147
294 But CTFE also guarantees that equal TypeInfos are
295 always identical. So, no opEquals needed during CTFE. */
297 return true;
300 // General case => symmetric calls to method opEquals
301 return rhs.opEquals(lhs);
303 else
305 // this is a compatibility hack for the old const cast behavior
306 // if none of the new overloads compile, we'll go back plain Object,
307 // including casting away const. It does this through the pointer
308 // to bypass any opCast that may be present on the original class.
309 return .opEquals!(Object, Object)(*cast(Object*) &lhs, *cast(Object*) &rhs);
314 /// If aliased to the same object or both null => equal
315 @system unittest // this one is not @safe because it goes through the Object base method
317 class F { int flag; this(int flag) { this.flag = flag; } }
319 F f;
320 assert(f == f); // both null
321 f = new F(1);
322 assert(f == f); // both aliased to the same object
325 /// If either is null => non-equal
326 @system unittest
328 class F { int flag; this(int flag) { this.flag = flag; } }
329 F f;
330 assert(!(new F(0) == f));
331 assert(!(f == new F(0)));
334 /// If same exact type => one call to method opEquals
335 /// This test passes `@safe` because it defines a new opEquals with `@safe`
336 @safe unittest
338 class F
340 int flag;
342 this(int flag)
344 this.flag = flag;
347 bool opEquals(const F o) const @safe nothrow pure
349 return flag == o.flag;
353 F f;
354 assert(new F(0) == new F(0));
355 assert(!(new F(0) == new F(1)));
358 /// General case => symmetric calls to method opEquals
359 @safe unittest
361 int fEquals, gEquals;
363 class Base
365 int flag;
366 this(int flag)
368 this.flag = flag;
372 class F : Base
374 this(int flag) { super(flag); }
376 bool opEquals(const Base o) @safe
378 fEquals++;
379 return flag == o.flag;
383 class G : Base
385 this(int flag) { super(flag); }
387 bool opEquals(const Base o) @safe
389 gEquals++;
390 return flag == o.flag;
394 assert(new F(1) == new G(1));
395 assert(fEquals == 1);
396 assert(gEquals == 1);
400 This test shows an example for a comprehensive inheritance equality chain too.
402 unittest
404 static class Base
406 int member;
408 this(int member) pure @safe nothrow @nogc
410 this.member = member;
413 override bool opEquals(Object rhs) const
415 return this.opEquals(cast(Base) rhs);
418 bool opEquals(const Base rhs) const @nogc pure nothrow @safe
420 if (rhs is null)
421 return false;
422 return this.member == rhs.member;
426 // works through the direct class with attributes enabled, except for pure and nogc in the current TypeInfo implementation
427 bool testThroughBase() nothrow @safe
429 Base b1 = new Base(0);
430 Base b2 = new Base(0);
431 assert(b1 == b2);
432 Base b3 = new Base(1);
433 assert(b1 != b3);
434 return true;
437 static assert(testThroughBase());
439 // also works through the base class interface thanks to the override, but no more attributes
440 bool testThroughObject()
442 Object o1 = new Base(0);
443 Object o2 = new Base(0);
444 assert(o1 == o2);
445 Object o3 = new Base(1);
446 assert(o1 != o3);
447 return true;
450 static assert(testThroughObject());
452 // Each time you make a child, you want to override all old opEquals
453 // and add a new overload for the new child.
454 static class Child : Base
456 int member2;
458 this(int member, int member2) pure @safe nothrow @nogc
460 super(member);
461 this.member2 = member2;
464 // override the whole chain so it works consistently though any base
465 override bool opEquals(Object rhs) const
467 return this.opEquals(cast(Child) rhs);
469 override bool opEquals(const Base rhs) const
471 return this.opEquals(cast(const Child) rhs);
473 // and then add the new overload, if necessary, to handle new members
474 bool opEquals(const Child rhs) const @nogc pure nothrow @safe
476 if (rhs is null)
477 return false;
478 // can call back to the devirtualized base test with implicit conversion
479 // then compare the new member too. or we could have just compared the base
480 // member directly here as well.
481 return Base.opEquals(rhs) && this.member2 == rhs.member2;
484 // a mixin template, of course, could automate this.
487 bool testThroughChild()
489 Child a = new Child(0, 0);
490 Child b = new Child(0, 1);
491 assert(a != b);
493 Base ba = a;
494 Base bb = b;
495 assert(ba != bb);
497 Object oa = a;
498 Object ob = b;
499 assert(oa != ob);
501 return true;
504 static assert(testThroughChild());
507 // To cover const Object opEquals
508 @system unittest
510 const Object obj1 = new Object;
511 const Object obj2 = new Object;
513 assert(obj1 == obj1);
514 assert(obj1 != obj2);
517 // https://issues.dlang.org/show_bug.cgi?id=23291
518 @system unittest
520 static shared class C { bool opEquals(const(shared(C)) rhs) const shared { return true;}}
521 const(C) c = new C();
522 const(C)[] a = [c];
523 const(C)[] b = [c];
524 assert(a[0] == b[0]);
527 private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow;
529 void setSameMutex(shared Object ownee, shared Object owner)
531 import core.atomic : atomicLoad;
532 _d_setSameMutex(atomicLoad(ownee), atomicLoad(owner));
535 @system unittest
537 shared Object obj1 = new Object;
538 synchronized class C
540 void bar() {}
542 shared C obj2 = new shared(C);
543 obj2.bar();
545 assert(obj1.__monitor != obj2.__monitor);
546 assert(obj1.__monitor is null);
548 setSameMutex(obj1, obj2);
549 assert(obj1.__monitor == obj2.__monitor);
550 assert(obj1.__monitor !is null);
554 * Information about an interface.
555 * When an object is accessed via an interface, an Interface* appears as the
556 * first entry in its vtbl.
558 struct Interface
560 /// Class info returned by `typeid` for this interface (not for containing class)
561 TypeInfo_Class classinfo;
562 void*[] vtbl;
563 size_t offset; /// offset to Interface 'this' from Object 'this'
567 * Array of pairs giving the offset and type information for each
568 * member in an aggregate.
570 struct OffsetTypeInfo
572 size_t offset; /// Offset of member from start of object
573 TypeInfo ti; /// TypeInfo for this member
577 * Runtime type information about a type.
578 * Can be retrieved for any type using a
579 * $(GLINK2 expression,TypeidExpression, TypeidExpression).
581 class TypeInfo
583 override string toString() const @safe nothrow
585 return typeid(this).name;
588 override size_t toHash() @trusted const nothrow
590 return hashOf(this.toString());
593 override int opCmp(Object rhs)
595 if (this is rhs)
596 return 0;
597 auto ti = cast(TypeInfo) rhs;
598 if (ti is null)
599 return 1;
600 return __cmp(this.toString(), ti.toString());
603 @system unittest
605 assert(typeid(void) <= typeid(void));
606 assert(typeid(void).opCmp(null));
607 assert(!typeid(void).opCmp(typeid(void)));
610 override bool opEquals(Object o)
612 return opEquals(cast(TypeInfo) o);
615 bool opEquals(const TypeInfo ti) @safe nothrow const
617 /* TypeInfo instances are singletons, but duplicates can exist
618 * across DLL's. Therefore, comparing for a name match is
619 * sufficient.
621 if (this is ti)
622 return true;
623 return ti && this.toString() == ti.toString();
626 @system unittest
628 auto anotherObj = new Object();
630 assert(typeid(void).opEquals(typeid(void)));
631 assert(typeid(void) != anotherObj); // calling .opEquals here directly is a type mismatch
635 * Computes a hash of the instance of a type.
636 * Params:
637 * p = pointer to start of instance of the type
638 * Returns:
639 * the hash
640 * Bugs:
641 * fix https://issues.dlang.org/show_bug.cgi?id=12516 e.g. by changing this to a truly safe interface.
643 size_t getHash(scope const void* p) @trusted nothrow const
645 // by default, do not assume anything about the type
646 return 0;
649 /// Compares two instances for equality.
650 bool equals(in void* p1, in void* p2) const { return p1 == p2; }
652 /// Compares two instances for &lt;, ==, or &gt;.
653 int compare(in void* p1, in void* p2) const { return _xopCmp(p1, p2); }
655 /// Returns size of the type.
656 @property size_t tsize() nothrow pure const @safe @nogc { return 0; }
658 /// Swaps two instances of the type.
659 void swap(void* p1, void* p2) const
661 size_t remaining = tsize;
662 // If the type might contain pointers perform the swap in pointer-sized
663 // chunks in case a garbage collection pass interrupts this function.
664 if ((cast(size_t) p1 | cast(size_t) p2) % (void*).alignof == 0)
666 while (remaining >= (void*).sizeof)
668 void* tmp = *cast(void**) p1;
669 *cast(void**) p1 = *cast(void**) p2;
670 *cast(void**) p2 = tmp;
671 p1 += (void*).sizeof;
672 p2 += (void*).sizeof;
673 remaining -= (void*).sizeof;
676 for (size_t i = 0; i < remaining; i++)
678 byte t = (cast(byte *)p1)[i];
679 (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
680 (cast(byte*)p2)[i] = t;
684 @system unittest
686 class _TypeInfo_Dummy : TypeInfo
688 override const(void)[] initializer() const { return []; }
689 @property override size_t tsize() nothrow pure const @safe @nogc { return tsize_val; }
691 size_t tsize_val;
693 auto dummy = new _TypeInfo_Dummy();
694 cast(void)dummy.initializer(); // For coverage completeness
696 int a = 2, b = -2;
697 dummy.swap(&a, &b);
698 // does nothing because tsize is 0
699 assert(a == 2);
700 assert(b == -2);
702 dummy.tsize_val = int.sizeof;
703 dummy.swap(&a, &b);
704 assert(a == -2);
705 assert(b == 2);
707 void* ptr_a = null, ptr_b = cast(void*)1;
708 dummy.tsize_val = (void*).sizeof;
709 dummy.swap(&ptr_a, &ptr_b);
710 assert(ptr_a is cast(void*)1);
711 assert(ptr_b is null);
714 /** Get TypeInfo for 'next' type, as defined by what kind of type this is,
715 null if none. */
716 @property inout(TypeInfo) next() nothrow pure inout @nogc { return null; }
719 * Return default initializer. If the type should be initialized to all
720 * zeros, an array with a null ptr and a length equal to the type size will
721 * be returned. For static arrays, this returns the default initializer for
722 * a single element of the array, use `tsize` to get the correct size.
724 abstract const(void)[] initializer() nothrow pure const @safe @nogc;
726 /** Get flags for type: 1 means GC should scan for pointers,
727 2 means arg of this type is passed in SIMD register(s) if available */
728 @property uint flags() nothrow pure const @safe @nogc { return 0; }
730 /// Get type information on the contents of the type; null if not available
731 const(OffsetTypeInfo)[] offTi() const { return null; }
732 /// Run the destructor on the object and all its sub-objects
733 void destroy(void* p) const {}
734 /// Run the postblit on the object and all its sub-objects
735 void postblit(void* p) const {}
738 /// Return alignment of type
739 @property size_t talign() nothrow pure const @safe @nogc { return tsize; }
741 /** Return internal info on arguments fitting into 8byte.
742 * See X86-64 ABI 3.2.3
744 version (WithArgTypes) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow
746 arg1 = this;
747 return 0;
750 /** Return info used by the garbage collector to do precise collection.
752 @property immutable(void)* rtInfo() nothrow pure const @trusted @nogc { return rtinfoHasPointers; } // better safe than sorry
755 @system unittest
757 class _TypeInfo_Dummy : TypeInfo
759 override const(void)[] initializer() const { return []; }
761 auto dummy = new _TypeInfo_Dummy();
762 cast(void)dummy.initializer(); // For coverage completeness
764 assert(dummy.rtInfo() is rtinfoHasPointers);
765 assert(typeid(void).rtInfo() is rtinfoNoPointers);
767 assert(dummy.tsize() == 0);
769 bool gotCaught;
772 dummy.compare(null, null);
773 } catch (Error e)
775 gotCaught = true;
776 assert(e.msg == "TypeInfo.compare is not implemented");
778 assert(gotCaught);
780 assert(dummy.equals(null, null));
781 assert(!dummy.equals(cast(void*)1, null));
784 @system unittest
786 assert(typeid(void).next() is null);
787 assert(typeid(void).offTi() is null);
788 assert(typeid(void).tsize() == 1);
790 version (WithArgTypes)
792 TypeInfo ti1;
793 TypeInfo ti2;
794 assert(typeid(void).argTypes(ti1, ti2) == 0);
795 assert(typeid(void) is ti1);
797 assert(ti1 !is null);
798 assert(ti2 is null);
802 @system unittest
804 class _ZypeInfo_Dummy : TypeInfo
806 override const(void)[] initializer() const { return []; }
808 auto dummy2 = new _ZypeInfo_Dummy();
809 cast(void)dummy2.initializer(); // For coverage completeness
811 assert(typeid(void) > dummy2);
812 assert(dummy2 < typeid(void));
815 @safe unittest
817 enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
818 enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
820 class _TypeInfo_Dummy : TypeInfo
822 override const(void)[] initializer() const { return []; }
825 auto dummy = new _TypeInfo_Dummy();
826 cast(void)dummy.initializer(); // For coverage completeness
828 assert(dummy.toString() == fqn_unittest ~ "._TypeInfo_Dummy");
829 assert(dummy.toHash() == hashOf(dummy.toString()));
830 assert(dummy.getHash(null) == 0);
833 class TypeInfo_Enum : TypeInfo
835 override string toString() const pure { return name; }
837 override bool opEquals(Object o)
839 if (this is o)
840 return true;
841 auto c = cast(const TypeInfo_Enum)o;
842 return c && this.name == c.name &&
843 this.base == c.base;
846 @system unittest
848 enum E { A, B, C }
849 enum EE { A, B, C }
851 assert(typeid(E).opEquals(typeid(E)));
852 assert(!typeid(E).opEquals(typeid(EE)));
855 override size_t getHash(scope const void* p) const { return base.getHash(p); }
857 @system unittest
859 enum E { A, B, C }
860 E e1 = E.A;
861 E e2 = E.B;
863 assert(typeid(E).getHash(&e1) == hashOf(E.A));
864 assert(typeid(E).getHash(&e2) == hashOf(E.B));
866 enum ES : string { A = "foo", B = "bar" }
867 ES es1 = ES.A;
868 ES es2 = ES.B;
870 assert(typeid(ES).getHash(&es1) == hashOf("foo"));
871 assert(typeid(ES).getHash(&es2) == hashOf("bar"));
874 override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
876 @system unittest
878 enum E { A, B, C }
880 E e1 = E.A;
881 E e2 = E.B;
883 assert(typeid(E).equals(&e1, &e1));
884 assert(!typeid(E).equals(&e1, &e2));
887 override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
889 @system unittest
891 enum E { A, B, C }
893 E e1 = E.A;
894 E e2 = E.B;
896 assert(typeid(E).compare(&e1, &e1) == 0);
897 assert(typeid(E).compare(&e1, &e2) < 0);
898 assert(typeid(E).compare(&e2, &e1) > 0);
901 override @property size_t tsize() nothrow pure const { return base.tsize; }
903 @safe unittest
905 enum E { A, B, C }
906 enum ES : string { A = "a", B = "b", C = "c"}
908 assert(typeid(E).tsize == E.sizeof);
909 assert(typeid(ES).tsize == ES.sizeof);
910 assert(typeid(E).tsize != ES.sizeof);
913 override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
915 @system unittest
917 enum E { A, B, C }
919 E e1 = E.A;
920 E e2 = E.B;
922 typeid(E).swap(&e1, &e2);
923 assert(e1 == E.B);
924 assert(e2 == E.A);
927 override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
929 @system unittest
931 enum E { A, B, C }
933 assert(typeid(E).next is null);
936 override @property uint flags() nothrow pure const { return base.flags; }
938 @safe unittest
940 enum E { A, B, C }
942 assert(typeid(E).flags == 0);
945 override const(OffsetTypeInfo)[] offTi() const { return base.offTi; }
947 @system unittest
949 enum E { A, B, C }
951 assert(typeid(E).offTi is null);
954 override void destroy(void* p) const { return base.destroy(p); }
955 override void postblit(void* p) const { return base.postblit(p); }
957 override const(void)[] initializer() const
959 return m_init.length ? m_init : base.initializer();
962 override @property size_t talign() nothrow pure const { return base.talign; }
964 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
966 return base.argTypes(arg1, arg2);
969 override @property immutable(void)* rtInfo() const { return base.rtInfo; }
971 TypeInfo base;
972 string name;
973 void[] m_init;
976 @safe unittest
978 enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
979 enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
981 enum E { A, B, C }
982 enum EE { A, B, C }
984 assert(typeid(E).toString() == fqn_unittest ~ ".E");
988 @safe unittest // https://issues.dlang.org/show_bug.cgi?id=12233
990 static assert(is(typeof(TypeInfo.init) == TypeInfo));
991 assert(TypeInfo.init is null);
995 // Please make sure to keep this in sync with TypeInfo_P (src/rt/typeinfo/ti_ptr.d)
996 class TypeInfo_Pointer : TypeInfo
998 override string toString() const { return m_next.toString() ~ "*"; }
1000 override bool opEquals(Object o)
1002 if (this is o)
1003 return true;
1004 auto c = cast(const TypeInfo_Pointer)o;
1005 return c && this.m_next == c.m_next;
1008 override size_t getHash(scope const void* p) @trusted const
1010 size_t addr = cast(size_t) *cast(const void**)p;
1011 return addr ^ (addr >> 4);
1014 override bool equals(in void* p1, in void* p2) const
1016 return *cast(void**)p1 == *cast(void**)p2;
1019 override int compare(in void* p1, in void* p2) const
1021 const v1 = *cast(void**) p1, v2 = *cast(void**) p2;
1022 return (v1 > v2) - (v1 < v2);
1025 override @property size_t tsize() nothrow pure const
1027 return (void*).sizeof;
1030 override const(void)[] initializer() const @trusted
1032 return (cast(void *)null)[0 .. (void*).sizeof];
1035 override void swap(void* p1, void* p2) const
1037 void* tmp = *cast(void**)p1;
1038 *cast(void**)p1 = *cast(void**)p2;
1039 *cast(void**)p2 = tmp;
1042 override @property inout(TypeInfo) next() nothrow pure inout { return m_next; }
1043 override @property uint flags() nothrow pure const { return 1; }
1045 TypeInfo m_next;
1048 class TypeInfo_Array : TypeInfo
1050 override string toString() const { return value.toString() ~ "[]"; }
1052 override bool opEquals(Object o)
1054 if (this is o)
1055 return true;
1056 auto c = cast(const TypeInfo_Array)o;
1057 return c && this.value == c.value;
1060 override size_t getHash(scope const void* p) @trusted const
1062 void[] a = *cast(void[]*)p;
1063 return getArrayHash(value, a.ptr, a.length);
1066 override bool equals(in void* p1, in void* p2) const
1068 void[] a1 = *cast(void[]*)p1;
1069 void[] a2 = *cast(void[]*)p2;
1070 if (a1.length != a2.length)
1071 return false;
1072 size_t sz = value.tsize;
1073 for (size_t i = 0; i < a1.length; i++)
1075 if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))
1076 return false;
1078 return true;
1081 override int compare(in void* p1, in void* p2) const
1083 void[] a1 = *cast(void[]*)p1;
1084 void[] a2 = *cast(void[]*)p2;
1085 size_t sz = value.tsize;
1086 size_t len = a1.length;
1088 if (a2.length < len)
1089 len = a2.length;
1090 for (size_t u = 0; u < len; u++)
1092 immutable int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
1093 if (result)
1094 return result;
1096 return (a1.length > a2.length) - (a1.length < a2.length);
1099 override @property size_t tsize() nothrow pure const
1101 return (void[]).sizeof;
1104 override const(void)[] initializer() const @trusted
1106 return (cast(void *)null)[0 .. (void[]).sizeof];
1109 override void swap(void* p1, void* p2) const
1111 void[] tmp = *cast(void[]*)p1;
1112 *cast(void[]*)p1 = *cast(void[]*)p2;
1113 *cast(void[]*)p2 = tmp;
1116 TypeInfo value;
1118 override @property inout(TypeInfo) next() nothrow pure inout
1120 return value;
1123 override @property uint flags() nothrow pure const { return 1; }
1125 override @property size_t talign() nothrow pure const
1127 return (void[]).alignof;
1130 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1132 arg1 = typeid(size_t);
1133 arg2 = typeid(void*);
1134 return 0;
1137 override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(void[]); }
1140 class TypeInfo_StaticArray : TypeInfo
1142 override string toString() const
1144 import core.internal.string : unsignedToTempString;
1146 char[20] tmpBuff = void;
1147 const lenString = unsignedToTempString(len, tmpBuff);
1149 return (() @trusted => cast(string) (value.toString() ~ "[" ~ lenString ~ "]"))();
1152 override bool opEquals(Object o)
1154 if (this is o)
1155 return true;
1156 auto c = cast(const TypeInfo_StaticArray)o;
1157 return c && this.len == c.len &&
1158 this.value == c.value;
1161 override size_t getHash(scope const void* p) @trusted const
1163 return getArrayHash(value, p, len);
1166 override bool equals(in void* p1, in void* p2) const
1168 size_t sz = value.tsize;
1170 for (size_t u = 0; u < len; u++)
1172 if (!value.equals(p1 + u * sz, p2 + u * sz))
1173 return false;
1175 return true;
1178 override int compare(in void* p1, in void* p2) const
1180 size_t sz = value.tsize;
1182 for (size_t u = 0; u < len; u++)
1184 immutable int result = value.compare(p1 + u * sz, p2 + u * sz);
1185 if (result)
1186 return result;
1188 return 0;
1191 override @property size_t tsize() nothrow pure const
1193 return len * value.tsize;
1196 override void swap(void* p1, void* p2) const
1198 import core.stdc.string : memcpy;
1200 size_t remaining = value.tsize * len;
1201 void[size_t.sizeof * 4] buffer = void;
1202 while (remaining > buffer.length)
1204 memcpy(buffer.ptr, p1, buffer.length);
1205 memcpy(p1, p2, buffer.length);
1206 memcpy(p2, buffer.ptr, buffer.length);
1207 p1 += buffer.length;
1208 p2 += buffer.length;
1209 remaining -= buffer.length;
1211 memcpy(buffer.ptr, p1, remaining);
1212 memcpy(p1, p2, remaining);
1213 memcpy(p2, buffer.ptr, remaining);
1216 override const(void)[] initializer() nothrow pure const
1218 return value.initializer();
1221 override @property inout(TypeInfo) next() nothrow pure inout { return value; }
1222 override @property uint flags() nothrow pure const { return value.flags; }
1224 override void destroy(void* p) const
1226 immutable sz = value.tsize;
1227 p += sz * len;
1228 foreach (i; 0 .. len)
1230 p -= sz;
1231 value.destroy(p);
1235 override void postblit(void* p) const
1237 immutable sz = value.tsize;
1238 foreach (i; 0 .. len)
1240 value.postblit(p);
1241 p += sz;
1245 TypeInfo value;
1246 size_t len;
1248 override @property size_t talign() nothrow pure const
1250 return value.talign;
1253 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1255 arg1 = typeid(void*);
1256 return 0;
1259 // just return the rtInfo of the element, we have no generic type T to run RTInfo!T on
1260 override @property immutable(void)* rtInfo() nothrow pure const @safe { return value.rtInfo(); }
1263 // https://issues.dlang.org/show_bug.cgi?id=21315
1264 @system unittest
1266 int[16] a, b;
1267 foreach (int i; 0 .. 16)
1269 a[i] = i;
1270 b[i] = ~i;
1272 typeid(int[16]).swap(&a, &b);
1273 foreach (int i; 0 .. 16)
1275 assert(a[i] == ~i);
1276 assert(b[i] == i);
1280 class TypeInfo_AssociativeArray : TypeInfo
1282 override string toString() const
1284 return value.toString() ~ "[" ~ key.toString() ~ "]";
1287 override bool opEquals(Object o)
1289 if (this is o)
1290 return true;
1291 auto c = cast(const TypeInfo_AssociativeArray)o;
1292 return c && this.key == c.key &&
1293 this.value == c.value;
1296 override bool equals(in void* p1, in void* p2) @trusted const
1298 return !!_aaEqual(this, *cast(const AA*) p1, *cast(const AA*) p2);
1301 override hash_t getHash(scope const void* p) nothrow @trusted const
1303 return _aaGetHash(cast(AA*)p, this);
1306 // BUG: need to add the rest of the functions
1308 override @property size_t tsize() nothrow pure const
1310 return (char[int]).sizeof;
1313 override const(void)[] initializer() const @trusted
1315 return (cast(void *)null)[0 .. (char[int]).sizeof];
1318 override @property inout(TypeInfo) next() nothrow pure inout { return value; }
1319 override @property uint flags() nothrow pure const { return 1; }
1321 TypeInfo value;
1322 TypeInfo key;
1324 override @property size_t talign() nothrow pure const
1326 return (char[int]).alignof;
1329 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1331 arg1 = typeid(void*);
1332 return 0;
1336 class TypeInfo_Vector : TypeInfo
1338 override string toString() const { return "__vector(" ~ base.toString() ~ ")"; }
1340 override bool opEquals(Object o)
1342 if (this is o)
1343 return true;
1344 auto c = cast(const TypeInfo_Vector)o;
1345 return c && this.base == c.base;
1348 override size_t getHash(scope const void* p) const { return base.getHash(p); }
1349 override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
1350 override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
1351 override @property size_t tsize() nothrow pure const { return base.tsize; }
1352 override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
1354 override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
1355 override @property uint flags() nothrow pure const { return 2; /* passed in SIMD register */ }
1357 override const(void)[] initializer() nothrow pure const
1359 return base.initializer();
1362 override @property size_t talign() nothrow pure const { return 16; }
1364 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1366 return base.argTypes(arg1, arg2);
1369 TypeInfo base;
1372 class TypeInfo_Function : TypeInfo
1374 override string toString() const pure @trusted
1376 import core.demangle : demangleType;
1378 alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;
1379 SafeDemangleFunctionType demangle = cast(SafeDemangleFunctionType) &demangleType;
1381 return cast(string) demangle(deco);
1384 override bool opEquals(Object o)
1386 if (this is o)
1387 return true;
1388 auto c = cast(const TypeInfo_Function)o;
1389 return c && this.deco == c.deco;
1392 // BUG: need to add the rest of the functions
1394 override @property size_t tsize() nothrow pure const
1396 return 0; // no size for functions
1399 override const(void)[] initializer() const @safe
1401 return null;
1404 override @property immutable(void)* rtInfo() nothrow pure const @safe { return rtinfoNoPointers; }
1406 TypeInfo next;
1409 * Mangled function type string
1411 string deco;
1414 @safe unittest
1416 abstract class C
1418 void func();
1419 void func(int a);
1420 int func(int a, int b);
1423 alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
1424 assert(typeid(functionTypes[0]).toString() == "void function()");
1425 assert(typeid(functionTypes[1]).toString() == "void function(int)");
1426 assert(typeid(functionTypes[2]).toString() == "int function(int, int)");
1429 @system unittest
1431 abstract class C
1433 void func();
1434 void func(int a);
1437 alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
1439 Object obj = typeid(functionTypes[0]);
1440 assert(obj.opEquals(typeid(functionTypes[0])));
1441 assert(typeid(functionTypes[0]) == typeid(functionTypes[0]));
1442 assert(typeid(functionTypes[0]) != typeid(functionTypes[1]));
1444 assert(typeid(functionTypes[0]).tsize() == 0);
1445 assert(typeid(functionTypes[0]).initializer() is null);
1446 assert(typeid(functionTypes[0]).rtInfo() is null);
1449 class TypeInfo_Delegate : TypeInfo
1451 override string toString() const pure @trusted
1453 import core.demangle : demangleType;
1455 alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;
1456 SafeDemangleFunctionType demangle = cast(SafeDemangleFunctionType) &demangleType;
1458 return cast(string) demangle(deco);
1461 @safe unittest
1463 double sqr(double x) { return x * x; }
1464 sqr(double.init); // for coverage completeness
1466 auto delegate_str = "double delegate(double) pure nothrow @nogc @safe";
1468 assert(typeid(typeof(&sqr)).toString() == delegate_str);
1469 assert(delegate_str.hashOf() == typeid(typeof(&sqr)).hashOf());
1470 assert(typeid(typeof(&sqr)).toHash() == typeid(typeof(&sqr)).hashOf());
1472 int g;
1474 alias delegate_type = typeof((int a, int b) => a + b + g);
1475 delegate_str = "int delegate(int, int) pure nothrow @nogc @safe";
1477 assert(typeid(delegate_type).toString() == delegate_str);
1478 assert(delegate_str.hashOf() == typeid(delegate_type).hashOf());
1479 assert(typeid(delegate_type).toHash() == typeid(delegate_type).hashOf());
1482 override bool opEquals(Object o)
1484 if (this is o)
1485 return true;
1486 auto c = cast(const TypeInfo_Delegate)o;
1487 return c && this.deco == c.deco;
1490 @system unittest
1492 double sqr(double x) { return x * x; }
1493 int dbl(int x) { return x + x; }
1494 sqr(double.init); // for coverage completeness
1495 dbl(int.init); // for coverage completeness
1497 Object obj = typeid(typeof(&sqr));
1498 assert(obj.opEquals(typeid(typeof(&sqr))));
1499 assert(typeid(typeof(&sqr)) == typeid(typeof(&sqr)));
1500 assert(typeid(typeof(&dbl)) != typeid(typeof(&sqr)));
1503 override size_t getHash(scope const void* p) @trusted const
1505 return hashOf(*cast(const void delegate() *)p);
1508 override bool equals(in void* p1, in void* p2) const
1510 auto dg1 = *cast(void delegate()*)p1;
1511 auto dg2 = *cast(void delegate()*)p2;
1512 return dg1 == dg2;
1515 override int compare(in void* p1, in void* p2) const
1517 auto dg1 = *cast(void delegate()*)p1;
1518 auto dg2 = *cast(void delegate()*)p2;
1520 if (dg1 < dg2)
1521 return -1;
1522 else if (dg1 > dg2)
1523 return 1;
1524 else
1525 return 0;
1528 override @property size_t tsize() nothrow pure const
1530 alias dg = int delegate();
1531 return dg.sizeof;
1534 override const(void)[] initializer() const @trusted
1536 return (cast(void *)null)[0 .. (int delegate()).sizeof];
1539 override @property uint flags() nothrow pure const { return 1; }
1541 TypeInfo next;
1542 string deco;
1544 override @property size_t talign() nothrow pure const
1546 alias dg = int delegate();
1547 return dg.alignof;
1550 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1552 arg1 = typeid(void*);
1553 arg2 = typeid(void*);
1554 return 0;
1557 override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(int delegate()); }
1560 private extern (C) Object _d_newclass(const TypeInfo_Class ci);
1561 private extern (C) int _d_isbaseof(scope TypeInfo_Class child,
1562 scope const TypeInfo_Class parent) @nogc nothrow pure @safe; // rt.cast_
1565 * Runtime type information about a class.
1566 * Can be retrieved from an object instance by using the
1567 * $(DDSUBLINK spec/expression,typeid_expressions,typeid expression).
1569 class TypeInfo_Class : TypeInfo
1571 override string toString() const pure { return name; }
1573 override bool opEquals(const TypeInfo o) const
1575 if (this is o)
1576 return true;
1577 auto c = cast(const TypeInfo_Class)o;
1578 return c && this.name == c.name;
1581 override size_t getHash(scope const void* p) @trusted const
1583 auto o = *cast(Object*)p;
1584 return o ? o.toHash() : 0;
1587 override bool equals(in void* p1, in void* p2) const
1589 Object o1 = *cast(Object*)p1;
1590 Object o2 = *cast(Object*)p2;
1592 return (o1 is o2) || (o1 && o1.opEquals(o2));
1595 override int compare(in void* p1, in void* p2) const
1597 Object o1 = *cast(Object*)p1;
1598 Object o2 = *cast(Object*)p2;
1599 int c = 0;
1601 // Regard null references as always being "less than"
1602 if (o1 !is o2)
1604 if (o1)
1606 if (!o2)
1607 c = 1;
1608 else
1609 c = o1.opCmp(o2);
1611 else
1612 c = -1;
1614 return c;
1617 override @property size_t tsize() nothrow pure const
1619 return Object.sizeof;
1622 override const(void)[] initializer() nothrow pure const @safe
1624 return m_init;
1627 override @property uint flags() nothrow pure const { return 1; }
1629 override @property const(OffsetTypeInfo)[] offTi() nothrow pure const
1631 return m_offTi;
1634 final @property auto info() @safe @nogc nothrow pure const return { return this; }
1635 final @property auto typeinfo() @safe @nogc nothrow pure const return { return this; }
1637 byte[] m_init; /** class static initializer
1638 * (init.length gives size in bytes of class)
1640 string name; /// class name
1641 void*[] vtbl; /// virtual function pointer table
1642 Interface[] interfaces; /// interfaces this class implements
1643 TypeInfo_Class base; /// base class
1644 void* destructor;
1645 void function(Object) classInvariant;
1646 enum ClassFlags : uint
1648 isCOMclass = 0x1,
1649 noPointers = 0x2,
1650 hasOffTi = 0x4,
1651 hasCtor = 0x8,
1652 hasGetMembers = 0x10,
1653 hasTypeInfo = 0x20,
1654 isAbstract = 0x40,
1655 isCPPclass = 0x80,
1656 hasDtor = 0x100,
1658 ClassFlags m_flags;
1659 void* deallocator;
1660 OffsetTypeInfo[] m_offTi;
1661 void function(Object) defaultConstructor; // default Constructor
1663 immutable(void)* m_RTInfo; // data for precise GC
1664 override @property immutable(void)* rtInfo() const { return m_RTInfo; }
1667 * Search all modules for TypeInfo_Class corresponding to classname.
1668 * Returns: null if not found
1670 static const(TypeInfo_Class) find(const scope char[] classname)
1672 foreach (m; ModuleInfo)
1674 if (m)
1676 //writefln("module %s, %d", m.name, m.localClasses.length);
1677 foreach (c; m.localClasses)
1679 if (c is null)
1680 continue;
1681 //writefln("\tclass %s", c.name);
1682 if (c.name == classname)
1683 return c;
1687 return null;
1691 * Create instance of Object represented by 'this'.
1693 Object create() const
1695 if (m_flags & 8 && !defaultConstructor)
1696 return null;
1697 if (m_flags & 64) // abstract
1698 return null;
1699 Object o = _d_newclass(this);
1700 if (m_flags & 8 && defaultConstructor)
1702 defaultConstructor(o);
1704 return o;
1708 * Returns true if the class described by `child` derives from or is
1709 * the class described by this `TypeInfo_Class`. Always returns false
1710 * if the argument is null.
1712 * Params:
1713 * child = TypeInfo for some class
1714 * Returns:
1715 * true if the class described by `child` derives from or is the
1716 * class described by this `TypeInfo_Class`.
1718 final bool isBaseOf(scope const TypeInfo_Class child) const @nogc nothrow pure @trusted
1720 if (m_init.length)
1722 // If this TypeInfo_Class represents an actual class we only need
1723 // to check the child and its direct ancestors.
1724 for (auto ti = cast() child; ti !is null; ti = ti.base)
1725 if (ti is this)
1726 return true;
1727 return false;
1729 else
1731 // If this TypeInfo_Class is the .info field of a TypeInfo_Interface
1732 // we also need to recursively check the child's interfaces.
1733 return child !is null && _d_isbaseof(cast() child, this);
1738 alias ClassInfo = TypeInfo_Class;
1740 @safe unittest
1742 // Bugzilla 14401
1743 static class X
1745 int a;
1748 assert(typeid(X).initializer is typeid(X).m_init);
1749 assert(typeid(X).initializer.length == typeid(const(X)).initializer.length);
1750 assert(typeid(X).initializer.length == typeid(shared(X)).initializer.length);
1751 assert(typeid(X).initializer.length == typeid(immutable(X)).initializer.length);
1754 class TypeInfo_Interface : TypeInfo
1756 override string toString() const pure { return info.name; }
1758 override bool opEquals(Object o)
1760 if (this is o)
1761 return true;
1762 auto c = cast(const TypeInfo_Interface)o;
1763 return c && this.info.name == typeid(c).name;
1766 override size_t getHash(scope const void* p) @trusted const
1768 if (!*cast(void**)p)
1770 return 0;
1772 Interface* pi = **cast(Interface ***)*cast(void**)p;
1773 Object o = cast(Object)(*cast(void**)p - pi.offset);
1774 assert(o);
1775 return o.toHash();
1778 override bool equals(in void* p1, in void* p2) const
1780 Interface* pi = **cast(Interface ***)*cast(void**)p1;
1781 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
1782 pi = **cast(Interface ***)*cast(void**)p2;
1783 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
1785 return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
1788 override int compare(in void* p1, in void* p2) const
1790 Interface* pi = **cast(Interface ***)*cast(void**)p1;
1791 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
1792 pi = **cast(Interface ***)*cast(void**)p2;
1793 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
1794 int c = 0;
1796 // Regard null references as always being "less than"
1797 if (o1 != o2)
1799 if (o1)
1801 if (!o2)
1802 c = 1;
1803 else
1804 c = o1.opCmp(o2);
1806 else
1807 c = -1;
1809 return c;
1812 override @property size_t tsize() nothrow pure const
1814 return Object.sizeof;
1817 override const(void)[] initializer() const @trusted
1819 return (cast(void *)null)[0 .. Object.sizeof];
1822 override @property uint flags() nothrow pure const { return 1; }
1824 TypeInfo_Class info;
1827 * Returns true if the class described by `child` derives from the
1828 * interface described by this `TypeInfo_Interface`. Always returns
1829 * false if the argument is null.
1831 * Params:
1832 * child = TypeInfo for some class
1833 * Returns:
1834 * true if the class described by `child` derives from the
1835 * interface described by this `TypeInfo_Interface`.
1837 final bool isBaseOf(scope const TypeInfo_Class child) const @nogc nothrow pure @trusted
1839 return child !is null && _d_isbaseof(cast() child, this.info);
1843 * Returns true if the interface described by `child` derives from
1844 * or is the interface described by this `TypeInfo_Interface`.
1845 * Always returns false if the argument is null.
1847 * Params:
1848 * child = TypeInfo for some interface
1849 * Returns:
1850 * true if the interface described by `child` derives from or is
1851 * the interface described by this `TypeInfo_Interface`.
1853 final bool isBaseOf(scope const TypeInfo_Interface child) const @nogc nothrow pure @trusted
1855 return child !is null && _d_isbaseof(cast() child.info, this.info);
1859 @safe unittest
1861 enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
1862 enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
1864 interface I {}
1866 assert(fqn_unittest ~ ".I" == typeid(I).info.name);
1867 assert((fqn_unittest ~ ".I").hashOf() == typeid(I).hashOf());
1868 assert(typeid(I).toHash() == typeid(I).hashOf());
1871 class TypeInfo_Struct : TypeInfo
1873 override string toString() const { return name; }
1875 override size_t toHash() const
1877 return hashOf(this.mangledName);
1880 override bool opEquals(Object o)
1882 if (this is o)
1883 return true;
1884 auto s = cast(const TypeInfo_Struct)o;
1885 return s && this.mangledName == s.mangledName;
1888 override size_t getHash(scope const void* p) @trusted pure nothrow const
1890 assert(p);
1891 if (xtoHash)
1893 return (*xtoHash)(p);
1895 else
1897 return hashOf(p[0 .. initializer().length]);
1901 override bool equals(in void* p1, in void* p2) @trusted pure nothrow const
1903 import core.stdc.string : memcmp;
1905 if (!p1 || !p2)
1906 return false;
1907 else if (xopEquals)
1909 const dg = _memberFunc(p1, xopEquals);
1910 return dg.xopEquals(p2);
1912 else if (p1 == p2)
1913 return true;
1914 else
1915 // BUG: relies on the GC not moving objects
1916 return memcmp(p1, p2, initializer().length) == 0;
1919 override int compare(in void* p1, in void* p2) @trusted pure nothrow const
1921 import core.stdc.string : memcmp;
1923 // Regard null references as always being "less than"
1924 if (p1 != p2)
1926 if (p1)
1928 if (!p2)
1929 return true;
1930 else if (xopCmp)
1932 const dg = _memberFunc(p1, xopCmp);
1933 return dg.xopCmp(p2);
1935 else
1936 // BUG: relies on the GC not moving objects
1937 return memcmp(p1, p2, initializer().length);
1939 else
1940 return -1;
1942 return 0;
1945 override @property size_t tsize() nothrow pure const
1947 return initializer().length;
1950 override const(void)[] initializer() nothrow pure const @safe
1952 return m_init;
1955 override @property uint flags() nothrow pure const { return m_flags; }
1957 override @property size_t talign() nothrow pure const { return m_align; }
1959 final override void destroy(void* p) const
1961 if (xdtor)
1963 if (m_flags & StructFlags.isDynamicType)
1964 (*xdtorti)(p, this);
1965 else
1966 (*xdtor)(p);
1970 override void postblit(void* p) const
1972 if (xpostblit)
1973 (*xpostblit)(p);
1976 string mangledName;
1978 final @property string name() nothrow const @trusted
1980 import core.demangle : demangleType;
1982 if (mangledName is null) // e.g., opaque structs
1983 return null;
1985 const key = cast(const void*) this; // faster lookup than TypeInfo_Struct, at the cost of potential duplicates per binary
1986 static string[typeof(key)] demangledNamesCache; // per thread
1988 // not nothrow:
1989 //return demangledNamesCache.require(key, cast(string) demangleType(mangledName));
1991 if (auto pDemangled = key in demangledNamesCache)
1992 return *pDemangled;
1994 const demangled = cast(string) demangleType(mangledName);
1995 demangledNamesCache[key] = demangled;
1996 return demangled;
1999 void[] m_init; // initializer; m_init.ptr == null if 0 initialize
2001 @safe pure nothrow
2003 size_t function(in void*) xtoHash;
2004 bool function(in void*, in void*) xopEquals;
2005 int function(in void*, in void*) xopCmp;
2006 string function(in void*) xtoString;
2008 enum StructFlags : uint
2010 hasPointers = 0x1,
2011 isDynamicType = 0x2, // built at runtime, needs type info in xdtor
2013 StructFlags m_flags;
2015 union
2017 void function(void*) xdtor;
2018 void function(void*, const TypeInfo_Struct ti) xdtorti;
2020 void function(void*) xpostblit;
2022 uint m_align;
2024 override @property immutable(void)* rtInfo() nothrow pure const @safe { return m_RTInfo; }
2026 version (WithArgTypes)
2028 override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2030 arg1 = m_arg1;
2031 arg2 = m_arg2;
2032 return 0;
2034 TypeInfo m_arg1;
2035 TypeInfo m_arg2;
2037 immutable(void)* m_RTInfo; // data for precise GC
2039 // The xopEquals and xopCmp members are function pointers to member
2040 // functions, which is not guaranteed to share the same ABI, as it is not
2041 // known whether the `this` parameter is the first or second argument.
2042 // This wrapper is to convert it to a delegate which will always pass the
2043 // `this` parameter in the correct way.
2044 private struct _memberFunc
2046 union
2048 struct // delegate
2050 const void* ptr;
2051 const void* funcptr;
2053 @safe pure nothrow
2055 bool delegate(in void*) xopEquals;
2056 int delegate(in void*) xopCmp;
2062 @system unittest
2064 struct S
2066 bool opEquals(ref const S rhs) const
2068 return false;
2071 S s;
2072 assert(!typeid(S).equals(&s, &s));
2075 class TypeInfo_Tuple : TypeInfo
2077 TypeInfo[] elements;
2079 override string toString() const
2081 string s = "(";
2082 foreach (i, element; elements)
2084 if (i)
2085 s ~= ',';
2086 s ~= element.toString();
2088 s ~= ")";
2089 return s;
2092 override bool opEquals(Object o)
2094 if (this is o)
2095 return true;
2097 auto t = cast(const TypeInfo_Tuple)o;
2098 if (t && elements.length == t.elements.length)
2100 for (size_t i = 0; i < elements.length; i++)
2102 if (elements[i] != t.elements[i])
2103 return false;
2105 return true;
2107 return false;
2110 override size_t getHash(scope const void* p) const
2112 assert(0);
2115 override bool equals(in void* p1, in void* p2) const
2117 assert(0);
2120 override int compare(in void* p1, in void* p2) const
2122 assert(0);
2125 override @property size_t tsize() nothrow pure const
2127 assert(0);
2130 override const(void)[] initializer() const @trusted
2132 assert(0);
2135 override void swap(void* p1, void* p2) const
2137 assert(0);
2140 override void destroy(void* p) const
2142 assert(0);
2145 override void postblit(void* p) const
2147 assert(0);
2150 override @property size_t talign() nothrow pure const
2152 assert(0);
2155 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2157 assert(0);
2161 class TypeInfo_Const : TypeInfo
2163 override string toString() const
2165 return cast(string) ("const(" ~ base.toString() ~ ")");
2168 //override bool opEquals(Object o) { return base.opEquals(o); }
2169 override bool opEquals(Object o)
2171 if (this is o)
2172 return true;
2174 if (typeid(this) != typeid(o))
2175 return false;
2177 auto t = cast(TypeInfo_Const)o;
2178 return base.opEquals(t.base);
2181 override size_t getHash(scope const void *p) const { return base.getHash(p); }
2182 override bool equals(in void *p1, in void *p2) const { return base.equals(p1, p2); }
2183 override int compare(in void *p1, in void *p2) const { return base.compare(p1, p2); }
2184 override @property size_t tsize() nothrow pure const { return base.tsize; }
2185 override void swap(void *p1, void *p2) const { return base.swap(p1, p2); }
2187 override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
2188 override @property uint flags() nothrow pure const { return base.flags; }
2190 override const(void)[] initializer() nothrow pure const
2192 return base.initializer();
2195 override @property size_t talign() nothrow pure const { return base.talign; }
2197 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2199 return base.argTypes(arg1, arg2);
2202 TypeInfo base;
2205 class TypeInfo_Invariant : TypeInfo_Const
2207 override string toString() const
2209 return cast(string) ("immutable(" ~ base.toString() ~ ")");
2213 class TypeInfo_Shared : TypeInfo_Const
2215 override string toString() const
2217 return cast(string) ("shared(" ~ base.toString() ~ ")");
2221 class TypeInfo_Inout : TypeInfo_Const
2223 override string toString() const
2225 return cast(string) ("inout(" ~ base.toString() ~ ")");
2229 // Contents of Moduleinfo._flags
2230 enum
2232 MIctorstart = 0x1, // we've started constructing it
2233 MIctordone = 0x2, // finished construction
2234 MIstandalone = 0x4, // module ctor does not depend on other module
2235 // ctors being done first
2236 MItlsctor = 8,
2237 MItlsdtor = 0x10,
2238 MIctor = 0x20,
2239 MIdtor = 0x40,
2240 MIxgetMembers = 0x80,
2241 MIictor = 0x100,
2242 MIunitTest = 0x200,
2243 MIimportedModules = 0x400,
2244 MIlocalClasses = 0x800,
2245 MIname = 0x1000,
2248 /*****************************************
2249 * An instance of ModuleInfo is generated into the object file for each compiled module.
2251 * It provides access to various aspects of the module.
2252 * It is not generated for betterC.
2254 struct ModuleInfo
2256 uint _flags; // MIxxxx
2257 uint _index; // index into _moduleinfo_array[]
2259 version (all)
2261 deprecated("ModuleInfo cannot be copy-assigned because it is a variable-sized struct.")
2262 void opAssign(const scope ModuleInfo m) { _flags = m._flags; _index = m._index; }
2264 else
2266 @disable this();
2269 const:
2270 private void* addrOf(int flag) return nothrow pure @nogc
2273 assert(flag >= MItlsctor && flag <= MIname);
2274 assert(!(flag & (flag - 1)) && !(flag & ~(flag - 1) << 1));
2278 import core.stdc.string : strlen;
2280 void* p = cast(void*)&this + ModuleInfo.sizeof;
2282 if (flags & MItlsctor)
2284 if (flag == MItlsctor) return p;
2285 p += typeof(tlsctor).sizeof;
2287 if (flags & MItlsdtor)
2289 if (flag == MItlsdtor) return p;
2290 p += typeof(tlsdtor).sizeof;
2292 if (flags & MIctor)
2294 if (flag == MIctor) return p;
2295 p += typeof(ctor).sizeof;
2297 if (flags & MIdtor)
2299 if (flag == MIdtor) return p;
2300 p += typeof(dtor).sizeof;
2302 if (flags & MIxgetMembers)
2304 if (flag == MIxgetMembers) return p;
2305 p += typeof(xgetMembers).sizeof;
2307 if (flags & MIictor)
2309 if (flag == MIictor) return p;
2310 p += typeof(ictor).sizeof;
2312 if (flags & MIunitTest)
2314 if (flag == MIunitTest) return p;
2315 p += typeof(unitTest).sizeof;
2317 if (flags & MIimportedModules)
2319 if (flag == MIimportedModules) return p;
2320 p += size_t.sizeof + *cast(size_t*)p * typeof(importedModules[0]).sizeof;
2322 if (flags & MIlocalClasses)
2324 if (flag == MIlocalClasses) return p;
2325 p += size_t.sizeof + *cast(size_t*)p * typeof(localClasses[0]).sizeof;
2327 if (true || flags & MIname) // always available for now
2329 if (flag == MIname) return p;
2330 p += strlen(cast(immutable char*)p);
2332 assert(0);
2335 @property uint index() nothrow pure @nogc { return _index; }
2337 @property uint flags() nothrow pure @nogc { return _flags; }
2339 /************************
2340 * Returns:
2341 * module constructor for thread locals, `null` if there isn't one
2343 @property void function() tlsctor() nothrow pure @nogc
2345 return flags & MItlsctor ? *cast(typeof(return)*)addrOf(MItlsctor) : null;
2348 /************************
2349 * Returns:
2350 * module destructor for thread locals, `null` if there isn't one
2352 @property void function() tlsdtor() nothrow pure @nogc
2354 return flags & MItlsdtor ? *cast(typeof(return)*)addrOf(MItlsdtor) : null;
2357 /*****************************
2358 * Returns:
2359 * address of a module's `const(MemberInfo)[] getMembers(string)` function, `null` if there isn't one
2361 @property void* xgetMembers() nothrow pure @nogc
2363 return flags & MIxgetMembers ? *cast(typeof(return)*)addrOf(MIxgetMembers) : null;
2366 /************************
2367 * Returns:
2368 * module constructor, `null` if there isn't one
2370 @property void function() ctor() nothrow pure @nogc
2372 return flags & MIctor ? *cast(typeof(return)*)addrOf(MIctor) : null;
2375 /************************
2376 * Returns:
2377 * module destructor, `null` if there isn't one
2379 @property void function() dtor() nothrow pure @nogc
2381 return flags & MIdtor ? *cast(typeof(return)*)addrOf(MIdtor) : null;
2384 /************************
2385 * Returns:
2386 * module order independent constructor, `null` if there isn't one
2388 @property void function() ictor() nothrow pure @nogc
2390 return flags & MIictor ? *cast(typeof(return)*)addrOf(MIictor) : null;
2393 /*************
2394 * Returns:
2395 * address of function that runs the module's unittests, `null` if there isn't one
2397 @property void function() unitTest() nothrow pure @nogc
2399 return flags & MIunitTest ? *cast(typeof(return)*)addrOf(MIunitTest) : null;
2402 /****************
2403 * Returns:
2404 * array of pointers to the ModuleInfo's of modules imported by this one
2406 @property immutable(ModuleInfo*)[] importedModules() return nothrow pure @nogc
2408 if (flags & MIimportedModules)
2410 auto p = cast(size_t*)addrOf(MIimportedModules);
2411 return (cast(immutable(ModuleInfo*)*)(p + 1))[0 .. *p];
2413 return null;
2416 /****************
2417 * Returns:
2418 * array of TypeInfo_Class references for classes defined in this module
2420 @property TypeInfo_Class[] localClasses() return nothrow pure @nogc
2422 if (flags & MIlocalClasses)
2424 auto p = cast(size_t*)addrOf(MIlocalClasses);
2425 return (cast(TypeInfo_Class*)(p + 1))[0 .. *p];
2427 return null;
2430 /********************
2431 * Returns:
2432 * name of module, `null` if no name
2434 @property string name() return nothrow pure @nogc
2436 import core.stdc.string : strlen;
2438 auto p = cast(immutable char*) addrOf(MIname);
2439 return p[0 .. strlen(p)];
2442 static int opApply(scope int delegate(ModuleInfo*) dg)
2444 import core.internal.traits : externDFunc;
2445 alias moduleinfos_apply = externDFunc!("rt.minfo.moduleinfos_apply",
2446 int function(scope int delegate(immutable(ModuleInfo*))));
2447 // Bugzilla 13084 - enforcing immutable ModuleInfo would break client code
2448 return moduleinfos_apply(
2449 (immutable(ModuleInfo*)m) => dg(cast(ModuleInfo*)m));
2453 @system unittest
2455 ModuleInfo* m1;
2456 foreach (m; ModuleInfo)
2458 m1 = m;
2462 ///////////////////////////////////////////////////////////////////////////////
2463 // Throwable
2464 ///////////////////////////////////////////////////////////////////////////////
2468 * The base class of all thrown objects.
2470 * All thrown objects must inherit from Throwable. Class $(D Exception), which
2471 * derives from this class, represents the category of thrown objects that are
2472 * safe to catch and handle. In principle, one should not catch Throwable
2473 * objects that are not derived from $(D Exception), as they represent
2474 * unrecoverable runtime errors. Certain runtime guarantees may fail to hold
2475 * when these errors are thrown, making it unsafe to continue execution after
2476 * catching them.
2478 class Throwable : Object
2480 interface TraceInfo
2482 int opApply(scope int delegate(ref const(char[]))) const;
2483 int opApply(scope int delegate(ref size_t, ref const(char[]))) const;
2484 string toString() const;
2487 alias TraceDeallocator = void function(TraceInfo) nothrow;
2489 string msg; /// A message describing the error.
2492 * The _file name of the D source code corresponding with
2493 * where the error was thrown from.
2495 string file;
2497 * The _line number of the D source code corresponding with
2498 * where the error was thrown from.
2500 size_t line;
2503 * The stack trace of where the error happened. This is an opaque object
2504 * that can either be converted to $(D string), or iterated over with $(D
2505 * foreach) to extract the items in the stack trace (as strings).
2507 TraceInfo info;
2510 * If set, this is used to deallocate the TraceInfo on destruction.
2512 TraceDeallocator infoDeallocator;
2516 * A reference to the _next error in the list. This is used when a new
2517 * $(D Throwable) is thrown from inside a $(D catch) block. The originally
2518 * caught $(D Exception) will be chained to the new $(D Throwable) via this
2519 * field.
2521 private Throwable nextInChain;
2523 private uint _refcount; // 0 : allocated by GC
2524 // 1 : allocated by _d_newThrowable()
2525 // 2.. : reference count + 1
2528 * Returns:
2529 * A reference to the _next error in the list. This is used when a new
2530 * $(D Throwable) is thrown from inside a $(D catch) block. The originally
2531 * caught $(D Exception) will be chained to the new $(D Throwable) via this
2532 * field.
2534 @property inout(Throwable) next() @safe inout return scope pure nothrow @nogc { return nextInChain; }
2537 * Replace next in chain with `tail`.
2538 * Use `chainTogether` instead if at all possible.
2540 @property void next(Throwable tail) @safe scope pure nothrow @nogc
2542 if (tail && tail._refcount)
2543 ++tail._refcount; // increment the replacement *first*
2545 auto n = nextInChain;
2546 nextInChain = null; // sever the tail before deleting it
2548 if (n && n._refcount)
2549 _d_delThrowable(n); // now delete the old tail
2551 nextInChain = tail; // and set the new tail
2555 * Returns:
2556 * mutable reference to the reference count, which is
2557 * 0 - allocated by the GC, 1 - allocated by _d_newThrowable(),
2558 * and >=2 which is the reference count + 1
2559 * Note:
2560 * Marked as `@system` to discourage casual use of it.
2562 @system @nogc final pure nothrow ref uint refcount() return { return _refcount; }
2565 * Loop over the chain of Throwables.
2567 int opApply(scope int delegate(Throwable) dg)
2569 int result = 0;
2570 for (Throwable t = this; t; t = t.nextInChain)
2572 result = dg(t);
2573 if (result)
2574 break;
2576 return result;
2580 * Append `e2` to chain of exceptions that starts with `e1`.
2581 * Params:
2582 * e1 = start of chain (can be null)
2583 * e2 = second part of chain (can be null)
2584 * Returns:
2585 * Throwable that is at the start of the chain; null if both `e1` and `e2` are null
2587 static @__future @system @nogc pure nothrow Throwable chainTogether(return scope Throwable e1, return scope Throwable e2)
2589 if (!e1)
2590 return e2;
2591 if (!e2)
2592 return e1;
2593 if (e2.refcount())
2594 ++e2.refcount();
2596 for (auto e = e1; 1; e = e.nextInChain)
2598 if (!e.nextInChain)
2600 e.nextInChain = e2;
2601 break;
2604 return e1;
2607 @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)
2609 this.msg = msg;
2610 this.nextInChain = nextInChain;
2611 if (nextInChain && nextInChain._refcount)
2612 ++nextInChain._refcount;
2613 //this.info = _d_traceContext();
2616 @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)
2618 this(msg, nextInChain);
2619 this.file = file;
2620 this.line = line;
2621 //this.info = _d_traceContext();
2624 @trusted nothrow ~this()
2626 if (nextInChain && nextInChain._refcount)
2627 _d_delThrowable(nextInChain);
2628 // handle owned traceinfo
2629 if (infoDeallocator !is null)
2631 infoDeallocator(info);
2632 info = null; // avoid any kind of dangling pointers if we can help
2633 // it.
2638 * Overrides $(D Object.toString) and returns the error message.
2639 * Internally this forwards to the $(D toString) overload that
2640 * takes a $(D_PARAM sink) delegate.
2642 override string toString()
2644 string s;
2645 toString((in buf) { s ~= buf; });
2646 return s;
2650 * The Throwable hierarchy uses a toString overload that takes a
2651 * $(D_PARAM _sink) delegate to avoid GC allocations, which cannot be
2652 * performed in certain error situations. Override this $(D
2653 * toString) method to customize the error message.
2655 void toString(scope void delegate(in char[]) sink) const
2657 import core.internal.string : unsignedToTempString;
2659 char[20] tmpBuff = void;
2661 sink(typeid(this).name);
2662 sink("@"); sink(file);
2663 sink("("); sink(unsignedToTempString(line, tmpBuff)); sink(")");
2665 if (msg.length)
2667 sink(": "); sink(msg);
2669 if (info)
2673 sink("\n----------------");
2674 foreach (t; info)
2676 sink("\n"); sink(t);
2679 catch (Throwable)
2681 // ignore more errors
2687 * Get the message describing the error.
2689 * This getter is an alternative way to access the Exception's message,
2690 * with the added advantage of being override-able in subclasses.
2691 * Subclasses are hence free to do their own memory managements without
2692 * being tied to the requirement of providing a `string` in a field.
2694 * The default behavior is to return the `Throwable.msg` field.
2696 * Returns:
2697 * A message representing the cause of the `Throwable`
2699 @__future const(char)[] message() const @safe nothrow
2701 return this.msg;
2707 * The base class of all errors that are safe to catch and handle.
2709 * In principle, only thrown objects derived from this class are safe to catch
2710 * inside a $(D catch) block. Thrown objects not derived from Exception
2711 * represent runtime errors that should not be caught, as certain runtime
2712 * guarantees may not hold, making it unsafe to continue program execution.
2714 class Exception : Throwable
2718 * Creates a new instance of Exception. The nextInChain parameter is used
2719 * internally and should always be $(D null) when passed by user code.
2720 * This constructor does not automatically throw the newly-created
2721 * Exception; the $(D throw) expression should be used for that purpose.
2723 @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null)
2725 super(msg, file, line, nextInChain);
2728 @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
2730 super(msg, file, line, nextInChain);
2735 @safe unittest
2737 bool gotCaught;
2740 throw new Exception("msg");
2742 catch (Exception e)
2744 gotCaught = true;
2745 assert(e.msg == "msg");
2747 assert(gotCaught);
2750 @system unittest
2753 auto e = new Exception("msg");
2754 assert(e.file == __FILE__);
2755 assert(e.line == __LINE__ - 2);
2756 assert(e.nextInChain is null);
2757 assert(e.msg == "msg");
2761 auto e = new Exception("msg", new Exception("It's an Exception!"), "hello", 42);
2762 assert(e.file == "hello");
2763 assert(e.line == 42);
2764 assert(e.nextInChain !is null);
2765 assert(e.msg == "msg");
2769 auto e = new Exception("msg", "hello", 42, new Exception("It's an Exception!"));
2770 assert(e.file == "hello");
2771 assert(e.line == 42);
2772 assert(e.nextInChain !is null);
2773 assert(e.msg == "msg");
2777 auto e = new Exception("message");
2778 assert(e.message == "message");
2784 * The base class of all unrecoverable runtime errors.
2786 * This represents the category of $(D Throwable) objects that are $(B not)
2787 * safe to catch and handle. In principle, one should not catch Error
2788 * objects, as they represent unrecoverable runtime errors.
2789 * Certain runtime guarantees may fail to hold when these errors are
2790 * thrown, making it unsafe to continue execution after catching them.
2792 class Error : Throwable
2795 * Creates a new instance of Error. The nextInChain parameter is used
2796 * internally and should always be $(D null) when passed by user code.
2797 * This constructor does not automatically throw the newly-created
2798 * Error; the $(D throw) statement should be used for that purpose.
2800 @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)
2802 super(msg, nextInChain);
2803 bypassedException = null;
2806 @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)
2808 super(msg, file, line, nextInChain);
2809 bypassedException = null;
2812 /** The first $(D Exception) which was bypassed when this Error was thrown,
2813 or $(D null) if no $(D Exception)s were pending. */
2814 Throwable bypassedException;
2818 @system unittest
2820 bool gotCaught;
2823 throw new Error("msg");
2825 catch (Error e)
2827 gotCaught = true;
2828 assert(e.msg == "msg");
2830 assert(gotCaught);
2833 @safe unittest
2836 auto e = new Error("msg");
2837 assert(e.file is null);
2838 assert(e.line == 0);
2839 assert(e.nextInChain is null);
2840 assert(e.msg == "msg");
2841 assert(e.bypassedException is null);
2845 auto e = new Error("msg", new Exception("It's an Exception!"));
2846 assert(e.file is null);
2847 assert(e.line == 0);
2848 assert(e.nextInChain !is null);
2849 assert(e.msg == "msg");
2850 assert(e.bypassedException is null);
2854 auto e = new Error("msg", "hello", 42, new Exception("It's an Exception!"));
2855 assert(e.file == "hello");
2856 assert(e.line == 42);
2857 assert(e.nextInChain !is null);
2858 assert(e.msg == "msg");
2859 assert(e.bypassedException is null);
2863 extern (C)
2865 // from druntime/src/rt/aaA.d
2867 private struct AA { void* impl; }
2868 // size_t _aaLen(in AA aa) pure nothrow @nogc;
2869 private void* _aaGetY(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow;
2870 private void* _aaGetX(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow;
2871 // inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
2872 inout(void[]) _aaValues(inout AA aa, const size_t keysz, const size_t valsz, const TypeInfo tiValueArray) pure nothrow;
2873 inout(void[]) _aaKeys(inout AA aa, const size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
2874 void* _aaRehash(AA* paa, const scope TypeInfo keyti) pure nothrow;
2875 void _aaClear(AA aa) pure nothrow;
2877 // alias _dg_t = extern(D) int delegate(void*);
2878 // int _aaApply(AA aa, size_t keysize, _dg_t dg);
2880 // alias _dg2_t = extern(D) int delegate(void*, void*);
2881 // int _aaApply2(AA aa, size_t keysize, _dg2_t dg);
2883 private struct AARange { AA impl; size_t idx; }
2884 AARange _aaRange(AA aa) pure nothrow @nogc @safe;
2885 bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe;
2886 void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe;
2887 void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe;
2888 void _aaRangePopFront(ref AARange r) pure nothrow @nogc @safe;
2890 int _aaEqual(scope const TypeInfo tiRaw, scope const AA aa1, scope const AA aa2);
2891 hash_t _aaGetHash(scope const AA* aa, scope const TypeInfo tiRaw) nothrow;
2894 _d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code.
2895 This is a typesystem hole, however this is existing hole.
2896 Early compiler didn't check purity of toHash or postblit functions, if key is a UDT thus
2897 copiler allowed to create AA literal with keys, which have impure unsafe toHash methods.
2899 void* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys, void[] values) pure;
2902 void* aaLiteral(Key, Value)(Key[] keys, Value[] values) @trusted pure
2904 return _d_assocarrayliteralTX(typeid(Value[Key]), *cast(void[]*)&keys, *cast(void[]*)&values);
2907 // Lower an Associative Array to a newaa struct for static initialization.
2908 auto _aaAsStruct(K, V)(V[K] aa) @safe
2910 import core.internal.newaa : makeAA;
2911 assert(__ctfe);
2912 return makeAA!(K, V)(aa);
2915 alias AssociativeArray(Key, Value) = Value[Key];
2917 /***********************************
2918 * Removes all remaining keys and values from an associative array.
2919 * Params:
2920 * aa = The associative array.
2922 void clear(Value, Key)(Value[Key] aa) @trusted
2924 _aaClear(*cast(AA *) &aa);
2927 /** ditto */
2928 void clear(Value, Key)(Value[Key]* aa) @trusted
2930 _aaClear(*cast(AA *) aa);
2934 @safe unittest
2936 auto aa = ["k1": 2];
2937 aa.clear;
2938 assert("k1" !in aa);
2941 // Issue 20559
2942 @system unittest
2944 static class Foo
2946 int[string] aa;
2947 alias aa this;
2950 auto v = new Foo();
2951 v["Hello World"] = 42;
2952 v.clear;
2953 assert("Hello World" !in v);
2955 // Test for T*
2956 static assert(!__traits(compiles, (&v).clear));
2957 static assert( __traits(compiles, (*(&v)).clear));
2960 /***********************************
2961 * Reorganizes the associative array in place so that lookups are more
2962 * efficient.
2963 * Params:
2964 * aa = The associative array.
2965 * Returns:
2966 * The rehashed associative array.
2968 T rehash(T : Value[Key], Value, Key)(T aa)
2970 _aaRehash(cast(AA*)&aa, typeid(Value[Key]));
2971 return aa;
2974 /** ditto */
2975 T rehash(T : Value[Key], Value, Key)(T* aa)
2977 _aaRehash(cast(AA*)aa, typeid(Value[Key]));
2978 return *aa;
2981 /** ditto */
2982 T rehash(T : shared Value[Key], Value, Key)(T aa)
2984 _aaRehash(cast(AA*)&aa, typeid(Value[Key]));
2985 return aa;
2988 /** ditto */
2989 T rehash(T : shared Value[Key], Value, Key)(T* aa)
2991 _aaRehash(cast(AA*)aa, typeid(Value[Key]));
2992 return *aa;
2995 /***********************************
2996 * Creates a new associative array of the same size and copies the contents of
2997 * the associative array into it.
2998 * Params:
2999 * aa = The associative array.
3001 V[K] dup(T : V[K], K, V)(T aa)
3003 //pragma(msg, "K = ", K, ", V = ", V);
3005 // Bug10720 - check whether V is copyable
3006 static assert(is(typeof({ V v = aa[K.init]; })),
3007 "cannot call " ~ T.stringof ~ ".dup because " ~ V.stringof ~ " is not copyable");
3009 V[K] result;
3011 //foreach (k, ref v; aa)
3012 // result[k] = v; // Bug13701 - won't work if V is not mutable
3014 ref V duplicateElem(ref K k, ref const V v) @trusted pure nothrow
3016 import core.stdc.string : memcpy;
3018 void* pv = _aaGetY(cast(AA*)&result, typeid(V[K]), V.sizeof, &k);
3019 memcpy(pv, &v, V.sizeof);
3020 return *cast(V*)pv;
3023 foreach (k, ref v; aa)
3025 static if (!__traits(hasPostblit, V))
3026 duplicateElem(k, v);
3027 else static if (__traits(isStaticArray, V))
3028 _doPostblit(duplicateElem(k, v)[]);
3029 else static if (!is(typeof(v.__xpostblit())) && is(immutable V == immutable UV, UV))
3030 (() @trusted => *cast(UV*) &duplicateElem(k, v))().__xpostblit();
3031 else
3032 duplicateElem(k, v).__xpostblit();
3035 return result;
3038 /** ditto */
3039 V[K] dup(T : V[K], K, V)(T* aa)
3041 return (*aa).dup;
3045 @safe unittest
3047 auto aa = ["k1": 2];
3048 auto a2 = aa.dup;
3049 aa["k2"] = 3;
3050 assert("k2" !in a2);
3053 // this should never be made public.
3054 private AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe
3056 // ensure we are dealing with a genuine AA.
3057 static if (is(const(V[K]) == const(T)))
3058 alias realAA = aa;
3059 else
3060 const(V[K]) realAA = aa;
3061 return _aaRange(() @trusted { return *cast(AA*)&realAA; } ());
3064 /***********************************
3065 * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3066 * which will iterate over the keys of the associative array. The keys are
3067 * returned by reference.
3069 * If structural changes are made to the array (removing or adding keys), all
3070 * ranges previously obtained through this function are invalidated. The
3071 * following example program will dereference a null pointer:
3073 *---
3074 * import std.stdio : writeln;
3076 * auto dict = ["k1": 1, "k2": 2];
3077 * auto keyRange = dict.byKey;
3078 * dict.clear;
3079 * writeln(keyRange.front); // Segmentation fault
3080 *---
3082 * Params:
3083 * aa = The associative array.
3084 * Returns:
3085 * A forward range referencing the keys of the associative array.
3087 auto byKey(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3089 import core.internal.traits : substInout;
3091 static struct Result
3093 AARange r;
3095 pure nothrow @nogc:
3096 @property bool empty() @safe { return _aaRangeEmpty(r); }
3097 @property ref front() @trusted
3099 return *cast(substInout!K*) _aaRangeFrontKey(r);
3101 void popFront() @safe { _aaRangePopFront(r); }
3102 @property Result save() { return this; }
3105 return Result(_aaToRange(aa));
3108 /** ditto */
3109 auto byKey(T : V[K], K, V)(T* aa) pure nothrow @nogc
3111 return (*aa).byKey();
3115 @safe unittest
3117 auto dict = [1: "v1", 2: "v2"];
3118 int sum;
3119 foreach (v; dict.byKey)
3120 sum += v;
3122 assert(sum == 3);
3125 /***********************************
3126 * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3127 * which will iterate over the values of the associative array. The values are
3128 * returned by reference.
3130 * If structural changes are made to the array (removing or adding keys), all
3131 * ranges previously obtained through this function are invalidated. The
3132 * following example program will dereference a null pointer:
3134 *---
3135 * import std.stdio : writeln;
3137 * auto dict = ["k1": 1, "k2": 2];
3138 * auto valueRange = dict.byValue;
3139 * dict.clear;
3140 * writeln(valueRange.front); // Segmentation fault
3141 *---
3143 * Params:
3144 * aa = The associative array.
3145 * Returns:
3146 * A forward range referencing the values of the associative array.
3148 auto byValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3150 import core.internal.traits : substInout;
3152 static struct Result
3154 AARange r;
3156 pure nothrow @nogc:
3157 @property bool empty() @safe { return _aaRangeEmpty(r); }
3158 @property ref front() @trusted
3160 return *cast(substInout!V*) _aaRangeFrontValue(r);
3162 void popFront() @safe { _aaRangePopFront(r); }
3163 @property Result save() { return this; }
3166 return Result(_aaToRange(aa));
3169 /** ditto */
3170 auto byValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
3172 return (*aa).byValue();
3176 @safe unittest
3178 auto dict = ["k1": 1, "k2": 2];
3179 int sum;
3180 foreach (v; dict.byValue)
3181 sum += v;
3183 assert(sum == 3);
3186 /***********************************
3187 * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3188 * which will iterate over the key-value pairs of the associative array. The
3189 * returned pairs are represented by an opaque type with `.key` and `.value`
3190 * properties for accessing references to the key and value of the pair,
3191 * respectively.
3193 * If structural changes are made to the array (removing or adding keys), all
3194 * ranges previously obtained through this function are invalidated. The
3195 * following example program will dereference a null pointer:
3197 *---
3198 * import std.stdio : writeln;
3200 * auto dict = ["k1": 1, "k2": 2];
3201 * auto kvRange = dict.byKeyValue;
3202 * dict.clear;
3203 * writeln(kvRange.front.key, ": ", kvRange.front.value); // Segmentation fault
3204 *---
3206 * Note that this is a low-level interface to iterating over the associative
3207 * array and is not compatible withth the
3208 * $(LINK2 $(ROOT_DIR)phobos/std_typecons.html#.Tuple,`Tuple`) type in Phobos.
3209 * For compatibility with `Tuple`, use
3210 * $(LINK2 $(ROOT_DIR)phobos/std_array.html#.byPair,std.array.byPair) instead.
3212 * Params:
3213 * aa = The associative array.
3214 * Returns:
3215 * A forward range referencing the pairs of the associative array.
3217 auto byKeyValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3219 import core.internal.traits : substInout;
3221 static struct Result
3223 AARange r;
3225 pure nothrow @nogc:
3226 @property bool empty() @safe { return _aaRangeEmpty(r); }
3227 @property auto front()
3229 static struct Pair
3231 // We save the pointers here so that the Pair we return
3232 // won't mutate when Result.popFront is called afterwards.
3233 private void* keyp;
3234 private void* valp;
3236 @property ref key() inout @trusted
3238 return *cast(substInout!K*) keyp;
3240 @property ref value() inout @trusted
3242 return *cast(substInout!V*) valp;
3245 return Pair(_aaRangeFrontKey(r),
3246 _aaRangeFrontValue(r));
3248 void popFront() @safe { return _aaRangePopFront(r); }
3249 @property Result save() { return this; }
3252 return Result(_aaToRange(aa));
3255 /** ditto */
3256 auto byKeyValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
3258 return (*aa).byKeyValue();
3262 @safe unittest
3264 auto dict = ["k1": 1, "k2": 2];
3265 int sum;
3266 foreach (e; dict.byKeyValue)
3268 assert(e.key[1] == e.value + '0');
3269 sum += e.value;
3272 assert(sum == 3);
3275 /***********************************
3276 * Returns a newly allocated dynamic array containing a copy of the keys from
3277 * the associative array.
3278 * Params:
3279 * aa = The associative array.
3280 * Returns:
3281 * A dynamic array containing a copy of the keys.
3283 Key[] keys(T : Value[Key], Value, Key)(T aa) @property
3285 // ensure we are dealing with a genuine AA.
3286 static if (is(const(Value[Key]) == const(T)))
3287 alias realAA = aa;
3288 else
3289 const(Value[Key]) realAA = aa;
3290 auto res = () @trusted {
3291 auto a = cast(void[])_aaKeys(*cast(inout(AA)*)&realAA, Key.sizeof, typeid(Key[]));
3292 return *cast(Key[]*)&a;
3293 }();
3294 static if (__traits(hasPostblit, Key))
3295 _doPostblit(res);
3296 return res;
3299 /** ditto */
3300 Key[] keys(T : Value[Key], Value, Key)(T *aa) @property
3302 return (*aa).keys;
3306 @safe unittest
3308 auto aa = [1: "v1", 2: "v2"];
3309 int sum;
3310 foreach (k; aa.keys)
3311 sum += k;
3313 assert(sum == 3);
3316 @safe unittest
3318 static struct S
3320 string str;
3321 void[][string] dict;
3322 alias dict this;
3325 auto s = S("a");
3326 assert(s.keys.length == 0);
3329 @safe unittest
3331 @safe static struct Key
3333 string str;
3334 this(this) @safe {}
3336 string[Key] aa;
3337 static assert(__traits(compiles, {
3338 void test() @safe {
3339 const _ = aa.keys;
3341 }));
3344 @safe unittest
3346 static struct Key
3348 string str;
3349 this(this) @system {}
3351 string[Key] aa;
3352 static assert(!__traits(compiles, {
3353 void test() @safe {
3354 const _ = aa.keys;
3356 }));
3359 /***********************************
3360 * Returns a newly allocated dynamic array containing a copy of the values from
3361 * the associative array.
3362 * Params:
3363 * aa = The associative array.
3364 * Returns:
3365 * A dynamic array containing a copy of the values.
3367 Value[] values(T : Value[Key], Value, Key)(T aa) @property
3369 // ensure we are dealing with a genuine AA.
3370 static if (is(const(Value[Key]) == const(T)))
3371 alias realAA = aa;
3372 else
3373 const(Value[Key]) realAA = aa;
3374 auto res = () @trusted {
3375 auto a = cast(void[])_aaValues(*cast(inout(AA)*)&realAA, Key.sizeof, Value.sizeof, typeid(Value[]));
3376 return *cast(Value[]*)&a;
3377 }();
3378 static if (__traits(hasPostblit, Value))
3379 _doPostblit(res);
3380 return res;
3383 /** ditto */
3384 Value[] values(T : Value[Key], Value, Key)(T *aa) @property
3386 return (*aa).values;
3390 @safe unittest
3392 auto aa = ["k1": 1, "k2": 2];
3393 int sum;
3394 foreach (e; aa.values)
3395 sum += e;
3397 assert(sum == 3);
3400 @safe unittest
3402 static struct S
3404 string str;
3405 void[][string] dict;
3406 alias dict this;
3409 auto s = S("a");
3410 assert(s.values.length == 0);
3413 @safe unittest
3415 @safe static struct Value
3417 string str;
3418 this(this) @safe {}
3420 Value[string] aa;
3421 static assert(__traits(compiles, {
3422 void test() @safe {
3423 const _ = aa.values;
3425 }));
3428 @safe unittest
3430 static struct Value
3432 string str;
3433 this(this) @system {}
3435 Value[string] aa;
3436 static assert(!__traits(compiles, {
3437 void test() @safe {
3438 const _ = aa.values;
3440 }));
3443 /***********************************
3444 * Looks up key; if it exists returns corresponding value else evaluates and
3445 * returns defaultValue.
3446 * Params:
3447 * aa = The associative array.
3448 * key = The key.
3449 * defaultValue = The default value.
3450 * Returns:
3451 * The value.
3453 inout(V) get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)
3455 auto p = key in aa;
3456 return p ? *p : defaultValue;
3459 /** ditto */
3460 inout(V) get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)
3462 return (*aa).get(key, defaultValue);
3466 @safe unittest
3468 auto aa = ["k1": 1];
3469 assert(aa.get("k1", 0) == 1);
3470 assert(aa.get("k2", 0) == 0);
3473 /***********************************
3474 * Looks up key; if it exists returns corresponding value else evaluates
3475 * value, adds it to the associative array and returns it.
3476 * Params:
3477 * aa = The associative array.
3478 * key = The key.
3479 * value = The required value.
3480 * Returns:
3481 * The value.
3483 ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init)
3485 bool found;
3486 // if key is @safe-ly copyable, `require` can infer @safe
3487 static if (isSafeCopyable!K)
3489 auto p = () @trusted
3491 return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3492 } ();
3494 else
3496 auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3498 if (found)
3499 return *p;
3500 else
3502 *p = value; // Not `return (*p = value)` since if `=` is overloaded
3503 return *p; // this might not return a ref to the left-hand side.
3508 @safe unittest
3510 auto aa = ["k1": 1];
3511 assert(aa.require("k1", 0) == 1);
3512 assert(aa.require("k2", 0) == 0);
3513 assert(aa["k2"] == 0);
3516 // Tests whether T can be @safe-ly copied. Use a union to exclude destructor from the test.
3517 private enum bool isSafeCopyable(T) = is(typeof(() @safe { union U { T x; } T *x; auto u = U(*x); }));
3519 /***********************************
3520 * Calls `create` if `key` doesn't exist in the associative array,
3521 * otherwise calls `update`.
3522 * `create` returns a corresponding value for `key`.
3523 * `update` accepts a key parameter. If it returns a value, the value is
3524 * set for `key`.
3525 * Params:
3526 * aa = The associative array.
3527 * key = The key.
3528 * create = The callable to create a value for `key`.
3529 * Must return V.
3530 * update = The callable to call if `key` exists.
3531 * Takes a K argument, returns a V or void.
3533 void update(K, V, C, U)(ref V[K] aa, K key, scope C create, scope U update)
3534 if (is(typeof(create()) : V) && (is(typeof(update(aa[K.init])) : V) || is(typeof(update(aa[K.init])) == void)))
3536 bool found;
3537 // if key is @safe-ly copyable, `update` may infer @safe
3538 static if (isSafeCopyable!K)
3540 auto p = () @trusted
3542 return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3543 } ();
3545 else
3547 auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3549 if (!found)
3550 *p = create();
3551 else
3553 static if (is(typeof(update(*p)) == void))
3554 update(*p);
3555 else
3556 *p = update(*p);
3561 @safe unittest
3563 int[string] aa;
3565 // create
3566 aa.update("key",
3567 () => 1,
3568 (int) {} // not executed
3570 assert(aa["key"] == 1);
3572 // update value by ref
3573 aa.update("key",
3574 () => 0, // not executed
3575 (ref int v) {
3576 v += 1;
3578 assert(aa["key"] == 2);
3580 // update from return value
3581 aa.update("key",
3582 () => 0, // not executed
3583 (int v) => v * 2
3585 assert(aa["key"] == 4);
3587 // 'update' without changing value
3588 aa.update("key",
3589 () => 0, // not executed
3590 (int) {
3591 // do something else
3593 assert(aa["key"] == 4);
3596 @safe unittest
3598 static struct S
3600 int x;
3601 @nogc nothrow pure:
3602 this(this) @system {}
3604 @safe const:
3605 // stubs
3606 bool opEquals(S rhs) { assert(0); }
3607 size_t toHash() { assert(0); }
3610 int[string] aai;
3611 static assert(is(typeof(() @safe { aai.require("a", 1234); })));
3612 static assert(is(typeof(() @safe { aai.update("a", { return 1234; }, (ref int x) { x++; return x; }); })));
3614 S[string] aas;
3615 static assert(is(typeof(() { aas.require("a", S(1234)); })));
3616 static assert(is(typeof(() { aas.update("a", { return S(1234); }, (ref S s) { s.x++; return s; }); })));
3617 static assert(!is(typeof(() @safe { aas.update("a", { return S(1234); }, (ref S s) { s.x++; return s; }); })));
3619 int[S] aais;
3620 static assert(is(typeof(() { aais.require(S(1234), 1234); })));
3621 static assert(is(typeof(() { aais.update(S(1234), { return 1234; }, (ref int x) { x++; return x; }); })));
3622 static assert(!is(typeof(() @safe { aais.require(S(1234), 1234); })));
3623 static assert(!is(typeof(() @safe { aais.update(S(1234), { return 1234; }, (ref int x) { x++; return x; }); })));
3626 @safe unittest
3628 struct S0
3630 int opCall(ref int v)
3632 return v + 1;
3636 struct S1
3638 int opCall()()
3640 return -2;
3643 T opCall(T)(ref T v)
3645 return v + 1;
3649 int[string] a = ["2" : 1];
3650 a.update("2", () => -1, S0.init);
3651 assert(a["2"] == 2);
3652 a.update("0", () => -1, S0.init);
3653 assert(a["0"] == -1);
3654 a.update("2", S1.init, S1.init);
3655 assert(a["2"] == 3);
3656 a.update("1", S1.init, S1.init);
3657 assert(a["1"] == -2);
3660 @system unittest
3662 int[string] aa;
3664 foreach (n; 0 .. 2)
3665 aa.update("k1", {
3666 return 7;
3667 }, (ref int v) {
3668 return v + 3;
3670 assert(aa["k1"] == 10);
3673 version (CoreDdoc)
3675 // This lets DDoc produce better documentation.
3678 Calculates the hash value of `arg` with an optional `seed` initial value.
3679 The result might not be equal to `typeid(T).getHash(&arg)`.
3681 Params:
3682 arg = argument to calculate the hash value of
3683 seed = optional `seed` value (may be used for hash chaining)
3685 Return: calculated hash value of `arg`
3687 size_t hashOf(T)(auto ref T arg, size_t seed)
3689 static import core.internal.hash;
3690 return core.internal.hash.hashOf(arg, seed);
3692 /// ditto
3693 size_t hashOf(T)(auto ref T arg)
3695 static import core.internal.hash;
3696 return core.internal.hash.hashOf(arg);
3699 @safe unittest
3701 auto h1 = "my.string".hashOf;
3702 assert(h1 == "my.string".hashOf);
3705 else
3707 public import core.internal.hash : hashOf;
3711 @system unittest
3713 class MyObject
3715 size_t myMegaHash() const @safe pure nothrow
3717 return 42;
3720 struct Test
3722 int a;
3723 string b;
3724 MyObject c;
3725 size_t toHash() const pure nothrow
3727 size_t hash = a.hashOf();
3728 hash = b.hashOf(hash);
3729 size_t h1 = c.myMegaHash();
3730 hash = h1.hashOf(hash); //Mix two hash values
3731 return hash;
3736 bool _xopEquals(in void*, in void*)
3738 throw new Error("TypeInfo.equals is not implemented");
3741 bool _xopCmp(in void*, in void*)
3743 throw new Error("TypeInfo.compare is not implemented");
3746 /******************************************
3747 * Create RTInfo for type T
3750 template RTInfoImpl(size_t[] pointerBitmap)
3752 immutable size_t[pointerBitmap.length] RTInfoImpl = pointerBitmap[];
3755 template NoPointersBitmapPayload(size_t N)
3757 enum size_t[N] NoPointersBitmapPayload = 0;
3760 template RTInfo(T)
3762 enum pointerBitmap = __traits(getPointerBitmap, T);
3763 static if (pointerBitmap[1 .. $] == NoPointersBitmapPayload!(pointerBitmap.length - 1))
3764 enum RTInfo = rtinfoNoPointers;
3765 else
3766 enum RTInfo = RTInfoImpl!(pointerBitmap).ptr;
3770 * shortcuts for the precise GC, also generated by the compiler
3771 * used instead of the actual pointer bitmap
3773 enum immutable(void)* rtinfoNoPointers = null;
3774 enum immutable(void)* rtinfoHasPointers = cast(void*)1;
3776 // Helper functions
3778 private inout(TypeInfo) getElement(return scope inout TypeInfo value) @trusted pure nothrow
3780 TypeInfo element = cast() value;
3781 for (;;)
3783 if (auto qualified = cast(TypeInfo_Const) element)
3784 element = qualified.base;
3785 else if (auto redefined = cast(TypeInfo_Enum) element)
3786 element = redefined.base;
3787 else if (auto staticArray = cast(TypeInfo_StaticArray) element)
3788 element = staticArray.value;
3789 else if (auto vector = cast(TypeInfo_Vector) element)
3790 element = vector.base;
3791 else
3792 break;
3794 return cast(inout) element;
3797 private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr, const size_t count) @trusted nothrow
3799 if (!count)
3800 return 0;
3802 const size_t elementSize = element.tsize;
3803 if (!elementSize)
3804 return 0;
3806 static bool hasCustomToHash(const scope TypeInfo value) @trusted pure nothrow
3808 const element = getElement(value);
3810 if (const struct_ = cast(const TypeInfo_Struct) element)
3811 return !!struct_.xtoHash;
3813 return cast(const TypeInfo_Array) element
3814 || cast(const TypeInfo_AssociativeArray) element
3815 || cast(const ClassInfo) element
3816 || cast(const TypeInfo_Interface) element;
3819 if (!hasCustomToHash(element))
3820 return hashOf(ptr[0 .. elementSize * count]);
3822 size_t hash = 0;
3823 foreach (size_t i; 0 .. count)
3824 hash = hashOf(element.getHash(ptr + i * elementSize), hash);
3825 return hash;
3828 /// Provide the .dup array property.
3829 @property auto dup(T)(T[] a)
3830 if (!is(const(T) : T))
3832 import core.internal.traits : Unconst;
3833 import core.internal.array.duplication : _dup;
3834 static assert(is(T : Unconst!T), "Cannot implicitly convert type "~T.stringof~
3835 " to "~Unconst!T.stringof~" in dup.");
3837 return _dup!(T, Unconst!T)(a);
3841 @safe unittest
3843 auto arr = [1, 2];
3844 auto arr2 = arr.dup;
3845 arr[0] = 0;
3846 assert(arr == [0, 2]);
3847 assert(arr2 == [1, 2]);
3850 /// ditto
3851 // const overload to support implicit conversion to immutable (unique result, see DIP29)
3852 @property T[] dup(T)(const(T)[] a)
3853 if (is(const(T) : T))
3855 import core.internal.array.duplication : _dup;
3856 return _dup!(const(T), T)(a);
3860 /// Provide the .idup array property.
3861 @property immutable(T)[] idup(T)(T[] a)
3863 import core.internal.array.duplication : _dup;
3864 static assert(is(T : immutable(T)), "Cannot implicitly convert type "~T.stringof~
3865 " to immutable in idup.");
3866 return _dup!(T, immutable(T))(a);
3869 /// ditto
3870 @property immutable(T)[] idup(T:void)(const(T)[] a)
3872 return a.dup;
3876 @safe unittest
3878 char[] arr = ['a', 'b', 'c'];
3879 string s = arr.idup;
3880 arr[0] = '.';
3881 assert(s == "abc");
3884 // HACK: This is a lie. `_d_arraysetcapacity` is neither `nothrow` nor `pure`, but this lie is
3885 // necessary for now to prevent breaking code.
3886 private extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* arrptr) pure nothrow;
3889 (Property) Gets the current _capacity of a slice. The _capacity is the size
3890 that the slice can grow to before the underlying array must be
3891 reallocated or extended.
3893 If an append must reallocate a slice with no possibility of extension, then
3894 `0` is returned. This happens when the slice references a static array, or
3895 if another slice references elements past the end of the current slice.
3897 Note: The _capacity of a slice may be impacted by operations on other slices.
3899 @property size_t capacity(T)(T[] arr) pure nothrow @trusted
3901 return _d_arraysetcapacity(typeid(T[]), 0, cast(void[]*)&arr);
3905 @safe unittest
3907 //Static array slice: no capacity
3908 int[4] sarray = [1, 2, 3, 4];
3909 int[] slice = sarray[];
3910 assert(sarray.capacity == 0);
3911 //Appending to slice will reallocate to a new array
3912 slice ~= 5;
3913 assert(slice.capacity >= 5);
3915 //Dynamic array slices
3916 int[] a = [1, 2, 3, 4];
3917 int[] b = a[1 .. $];
3918 int[] c = a[1 .. $ - 1];
3919 debug(SENTINEL) {} else // non-zero capacity very much depends on the array and GC implementation
3921 assert(a.capacity != 0);
3922 assert(a.capacity == b.capacity + 1); //both a and b share the same tail
3924 assert(c.capacity == 0); //an append to c must relocate c.
3928 Reserves capacity for a slice. The capacity is the size
3929 that the slice can grow to before the underlying array must be
3930 reallocated or extended.
3932 Returns: The new capacity of the array (which may be larger than
3933 the requested capacity).
3935 size_t reserve(T)(ref T[] arr, size_t newcapacity) pure nothrow @trusted
3937 if (__ctfe)
3938 return newcapacity;
3939 else
3940 return _d_arraysetcapacity(typeid(T[]), newcapacity, cast(void[]*)&arr);
3944 @safe unittest
3946 //Static array slice: no capacity. Reserve relocates.
3947 int[4] sarray = [1, 2, 3, 4];
3948 int[] slice = sarray[];
3949 auto u = slice.reserve(8);
3950 assert(u >= 8);
3951 assert(&sarray[0] !is &slice[0]);
3952 assert(slice.capacity == u);
3954 //Dynamic array slices
3955 int[] a = [1, 2, 3, 4];
3956 a.reserve(8); //prepare a for appending 4 more items
3957 auto p = &a[0];
3958 u = a.capacity;
3959 a ~= [5, 6, 7, 8];
3960 assert(p == &a[0]); //a should not have been reallocated
3961 assert(u == a.capacity); //a should not have been extended
3964 // https://issues.dlang.org/show_bug.cgi?id=12330, reserve() at CTFE time
3965 @safe unittest
3967 int[] foo() {
3968 int[] result;
3969 auto a = result.reserve = 5;
3970 assert(a == 5);
3971 return result;
3973 enum r = foo();
3976 // Issue 6646: should be possible to use array.reserve from SafeD.
3977 @safe unittest
3979 int[] a;
3980 a.reserve(10);
3983 // HACK: This is a lie. `_d_arrayshrinkfit` is not `nothrow`, but this lie is necessary
3984 // for now to prevent breaking code.
3985 private extern (C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow;
3988 Assume that it is safe to append to this array. Appends made to this array
3989 after calling this function may append in place, even if the array was a
3990 slice of a larger array to begin with.
3992 Use this only when it is certain there are no elements in use beyond the
3993 array in the memory block. If there are, those elements will be
3994 overwritten by appending to this array.
3996 Warning: Calling this function, and then using references to data located after the
3997 given array results in undefined behavior.
3999 Returns:
4000 The input is returned.
4002 auto ref inout(T[]) assumeSafeAppend(T)(auto ref inout(T[]) arr) nothrow @system
4004 _d_arrayshrinkfit(typeid(T[]), *(cast(void[]*)&arr));
4005 return arr;
4009 @system unittest
4011 int[] a = [1, 2, 3, 4];
4013 // Without assumeSafeAppend. Appending relocates.
4014 int[] b = a [0 .. 3];
4015 b ~= 5;
4016 assert(a.ptr != b.ptr);
4018 debug(SENTINEL) {} else
4020 // With assumeSafeAppend. Appending overwrites.
4021 int[] c = a [0 .. 3];
4022 c.assumeSafeAppend() ~= 5;
4023 assert(a.ptr == c.ptr);
4027 @system unittest
4029 int[] arr;
4030 auto newcap = arr.reserve(2000);
4031 assert(newcap >= 2000);
4032 assert(newcap == arr.capacity);
4033 auto ptr = arr.ptr;
4034 foreach (i; 0..2000)
4035 arr ~= i;
4036 assert(ptr == arr.ptr);
4037 arr = arr[0..1];
4038 arr.assumeSafeAppend();
4039 arr ~= 5;
4040 assert(ptr == arr.ptr);
4043 @system unittest
4045 int[] arr = [1, 2, 3];
4046 void foo(ref int[] i)
4048 i ~= 5;
4050 arr = arr[0 .. 2];
4051 foo(assumeSafeAppend(arr)); //pass by ref
4052 assert(arr[]==[1, 2, 5]);
4053 arr = arr[0 .. 1].assumeSafeAppend(); //pass by value
4056 // https://issues.dlang.org/show_bug.cgi?id=10574
4057 @system unittest
4059 int[] a;
4060 immutable(int[]) b;
4061 auto a2 = &assumeSafeAppend(a);
4062 auto b2 = &assumeSafeAppend(b);
4063 auto a3 = assumeSafeAppend(a[]);
4064 auto b3 = assumeSafeAppend(b[]);
4065 assert(is(typeof(*a2) == int[]));
4066 assert(is(typeof(*b2) == immutable(int[])));
4067 assert(is(typeof(a3) == int[]));
4068 assert(is(typeof(b3) == immutable(int[])));
4071 private void _doPostblit(T)(T[] arr)
4073 // infer static postblit type, run postblit if any
4074 static if (__traits(hasPostblit, T))
4076 static if (__traits(isStaticArray, T) && is(T : E[], E))
4077 _doPostblit(cast(E[]) arr);
4078 else static if (!is(typeof(arr[0].__xpostblit())) && is(immutable T == immutable U, U))
4079 foreach (ref elem; (() @trusted => cast(U[]) arr)())
4080 elem.__xpostblit();
4081 else
4082 foreach (ref elem; arr)
4083 elem.__xpostblit();
4088 Destroys the given object and optionally resets to initial state. It's used to
4089 _destroy an object, calling its destructor or finalizer so it no longer
4090 references any other objects. It does $(I not) initiate a GC cycle or free
4091 any GC memory.
4092 If `initialize` is supplied `false`, the object is considered invalid after
4093 destruction, and should not be referenced.
4095 void destroy(bool initialize = true, T)(ref T obj) if (is(T == struct))
4097 import core.internal.destruction : destructRecurse;
4099 destructRecurse(obj);
4101 static if (initialize)
4103 import core.internal.lifetime : emplaceInitializer;
4104 emplaceInitializer(obj); // emplace T.init
4108 @safe unittest
4110 struct A { string s = "A"; }
4111 A a = {s: "B"};
4112 assert(a.s == "B");
4113 a.destroy;
4114 assert(a.s == "A");
4117 nothrow @safe @nogc unittest
4120 struct A { string s = "A"; }
4121 A a;
4122 a.s = "asd";
4123 destroy!false(a);
4124 assert(a.s == "asd");
4125 destroy(a);
4126 assert(a.s == "A");
4129 static int destroyed = 0;
4130 struct C
4132 string s = "C";
4133 ~this() nothrow @safe @nogc
4135 destroyed ++;
4139 struct B
4141 C c;
4142 string s = "B";
4143 ~this() nothrow @safe @nogc
4145 destroyed ++;
4148 B a;
4149 a.s = "asd";
4150 a.c.s = "jkl";
4151 destroy!false(a);
4152 assert(destroyed == 2);
4153 assert(a.s == "asd");
4154 assert(a.c.s == "jkl" );
4155 destroy(a);
4156 assert(destroyed == 4);
4157 assert(a.s == "B");
4158 assert(a.c.s == "C" );
4162 private extern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true) nothrow;
4164 /// ditto
4165 void destroy(bool initialize = true, T)(T obj) if (is(T == class))
4167 static if (__traits(getLinkage, T) == "C++")
4169 static if (__traits(hasMember, T, "__xdtor"))
4170 obj.__xdtor();
4172 static if (initialize)
4174 const initializer = __traits(initSymbol, T);
4175 (cast(void*)obj)[0 .. initializer.length] = initializer[];
4178 else
4180 // Bypass overloaded opCast
4181 auto ptr = (() @trusted => *cast(void**) &obj)();
4182 rt_finalize2(ptr, true, initialize);
4186 /// ditto
4187 void destroy(bool initialize = true, T)(T obj) if (is(T == interface))
4189 static assert(__traits(getLinkage, T) == "D", "Invalid call to destroy() on extern(" ~ __traits(getLinkage, T) ~ ") interface");
4191 destroy!initialize(cast(Object)obj);
4194 /// Reference type demonstration
4195 @system unittest
4197 class C
4199 struct Agg
4201 static int dtorCount;
4203 int x = 10;
4204 ~this() { dtorCount++; }
4207 static int dtorCount;
4209 string s = "S";
4210 Agg a;
4211 ~this() { dtorCount++; }
4214 C c = new C();
4215 assert(c.dtorCount == 0); // destructor not yet called
4216 assert(c.s == "S"); // initial state `c.s` is `"S"`
4217 assert(c.a.dtorCount == 0); // destructor not yet called
4218 assert(c.a.x == 10); // initial state `c.a.x` is `10`
4219 c.s = "T";
4220 c.a.x = 30;
4221 assert(c.s == "T"); // `c.s` is `"T"`
4222 destroy(c);
4223 assert(c.dtorCount == 1); // `c`'s destructor was called
4224 assert(c.s == "S"); // `c.s` is back to its inital state, `"S"`
4225 assert(c.a.dtorCount == 1); // `c.a`'s destructor was called
4226 assert(c.a.x == 10); // `c.a.x` is back to its inital state, `10`
4229 /// C++ classes work too
4230 @system unittest
4232 extern (C++) class CPP
4234 struct Agg
4236 __gshared int dtorCount;
4238 int x = 10;
4239 ~this() { dtorCount++; }
4242 __gshared int dtorCount;
4244 string s = "S";
4245 Agg a;
4246 ~this() { dtorCount++; }
4249 CPP cpp = new CPP();
4250 assert(cpp.dtorCount == 0); // destructor not yet called
4251 assert(cpp.s == "S"); // initial state `cpp.s` is `"S"`
4252 assert(cpp.a.dtorCount == 0); // destructor not yet called
4253 assert(cpp.a.x == 10); // initial state `cpp.a.x` is `10`
4254 cpp.s = "T";
4255 cpp.a.x = 30;
4256 assert(cpp.s == "T"); // `cpp.s` is `"T"`
4257 destroy!false(cpp); // destroy without initialization
4258 assert(cpp.dtorCount == 1); // `cpp`'s destructor was called
4259 assert(cpp.s == "T"); // `cpp.s` is not initialized
4260 assert(cpp.a.dtorCount == 1); // `cpp.a`'s destructor was called
4261 assert(cpp.a.x == 30); // `cpp.a.x` is not initialized
4262 destroy(cpp);
4263 assert(cpp.dtorCount == 2); // `cpp`'s destructor was called again
4264 assert(cpp.s == "S"); // `cpp.s` is back to its inital state, `"S"`
4265 assert(cpp.a.dtorCount == 2); // `cpp.a`'s destructor was called again
4266 assert(cpp.a.x == 10); // `cpp.a.x` is back to its inital state, `10`
4269 /// Value type demonstration
4270 @safe unittest
4272 int i;
4273 assert(i == 0); // `i`'s initial state is `0`
4274 i = 1;
4275 assert(i == 1); // `i` changed to `1`
4276 destroy!false(i);
4277 assert(i == 1); // `i` was not initialized
4278 destroy(i);
4279 assert(i == 0); // `i` is back to its initial state `0`
4282 /// Nested struct type
4283 @system unittest
4285 int dtorCount;
4286 struct A
4288 int i;
4289 ~this()
4291 dtorCount++; // capture local variable
4294 A a = A(5);
4295 destroy!false(a);
4296 assert(dtorCount == 1);
4297 assert(a.i == 5);
4299 destroy(a);
4300 assert(dtorCount == 2);
4301 assert(a.i == 0);
4303 // the context pointer is now null
4304 // restore it so the dtor can run
4305 import core.lifetime : emplace;
4306 emplace(&a, A(0));
4307 // dtor also called here
4310 @system unittest
4312 extern(C++)
4313 static class C
4315 void* ptr;
4316 this() {}
4319 destroy!false(new C());
4320 destroy!true(new C());
4323 @system unittest
4325 // class with an `alias this`
4326 class A
4328 static int dtorCount;
4329 ~this()
4331 dtorCount++;
4335 class B
4337 A a;
4338 alias a this;
4339 this()
4341 a = new A;
4343 static int dtorCount;
4344 ~this()
4346 dtorCount++;
4349 auto b = new B;
4350 assert(A.dtorCount == 0);
4351 assert(B.dtorCount == 0);
4352 destroy(b);
4353 assert(A.dtorCount == 0);
4354 assert(B.dtorCount == 1);
4356 auto a = new A;
4357 destroy(a);
4358 assert(A.dtorCount == 1);
4361 @system unittest
4363 interface I { }
4365 class A: I { string s = "A"; this() {} }
4366 auto a = new A, b = new A;
4367 a.s = b.s = "asd";
4368 destroy(a);
4369 assert(a.s == "A");
4371 I i = b;
4372 destroy(i);
4373 assert(b.s == "A");
4376 static bool destroyed = false;
4377 class B: I
4379 string s = "B";
4380 this() {}
4381 ~this()
4383 destroyed = true;
4386 auto a = new B, b = new B;
4387 a.s = b.s = "asd";
4388 destroy(a);
4389 assert(destroyed);
4390 assert(a.s == "B");
4392 destroyed = false;
4393 I i = b;
4394 destroy(i);
4395 assert(destroyed);
4396 assert(b.s == "B");
4398 // this test is invalid now that the default ctor is not run after clearing
4399 version (none)
4401 class C
4403 string s;
4404 this()
4406 s = "C";
4409 auto a = new C;
4410 a.s = "asd";
4411 destroy(a);
4412 assert(a.s == "C");
4416 nothrow @safe @nogc unittest
4419 struct A { string s = "A"; }
4420 A a;
4421 a.s = "asd";
4422 destroy!false(a);
4423 assert(a.s == "asd");
4424 destroy(a);
4425 assert(a.s == "A");
4428 static int destroyed = 0;
4429 struct C
4431 string s = "C";
4432 ~this() nothrow @safe @nogc
4434 destroyed ++;
4438 struct B
4440 C c;
4441 string s = "B";
4442 ~this() nothrow @safe @nogc
4444 destroyed ++;
4447 B a;
4448 a.s = "asd";
4449 a.c.s = "jkl";
4450 destroy!false(a);
4451 assert(destroyed == 2);
4452 assert(a.s == "asd");
4453 assert(a.c.s == "jkl" );
4454 destroy(a);
4455 assert(destroyed == 4);
4456 assert(a.s == "B");
4457 assert(a.c.s == "C" );
4461 nothrow unittest
4463 // Bugzilla 20049: Test to ensure proper behavior of `nothrow` destructors
4464 class C
4466 static int dtorCount = 0;
4467 this() nothrow {}
4468 ~this() nothrow { dtorCount++; }
4471 auto c = new C;
4472 destroy(c);
4473 assert(C.dtorCount == 1);
4476 // https://issues.dlang.org/show_bug.cgi?id=22832
4477 nothrow unittest
4479 static struct A {}
4480 static class B
4482 A opCast(T : A)() { return A(); }
4485 destroy(B.init);
4488 // make sure destroy!false skips re-initialization
4489 unittest
4491 static struct S { int x; }
4492 static class C { int x; }
4493 static extern(C++) class Cpp { int x; }
4495 static void test(T)(T inst)
4497 inst.x = 123;
4498 destroy!false(inst);
4499 assert(inst.x == 123, T.stringof);
4502 test(S());
4503 test(new C());
4504 test(new Cpp());
4507 /// ditto
4508 void destroy(bool initialize = true, T)(ref T obj)
4509 if (__traits(isStaticArray, T))
4511 foreach_reverse (ref e; obj[])
4512 destroy!initialize(e);
4515 @safe unittest
4517 int[2] a;
4518 a[0] = 1;
4519 a[1] = 2;
4520 destroy!false(a);
4521 assert(a == [ 1, 2 ]);
4522 destroy(a);
4523 assert(a == [ 0, 0 ]);
4526 @safe unittest
4528 static struct vec2f {
4529 float[2] values;
4530 alias values this;
4533 vec2f v;
4534 destroy!(true, vec2f)(v);
4537 @system unittest
4539 // Bugzilla 15009
4540 static string op;
4541 static struct S
4543 int x;
4544 this(int x) { op ~= "C" ~ cast(char)('0'+x); this.x = x; }
4545 this(this) { op ~= "P" ~ cast(char)('0'+x); }
4546 ~this() { op ~= "D" ~ cast(char)('0'+x); }
4550 S[2] a1 = [S(1), S(2)];
4551 op = "";
4553 assert(op == "D2D1"); // built-in scope destruction
4555 S[2] a1 = [S(1), S(2)];
4556 op = "";
4557 destroy(a1);
4558 assert(op == "D2D1"); // consistent with built-in behavior
4562 S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];
4563 op = "";
4565 assert(op == "D4D3D2D1");
4567 S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];
4568 op = "";
4569 destroy(a2);
4570 assert(op == "D4D3D2D1", op);
4574 // https://issues.dlang.org/show_bug.cgi?id=19218
4575 @system unittest
4577 static struct S
4579 static dtorCount = 0;
4580 ~this() { ++dtorCount; }
4583 static interface I
4585 ref S[3] getArray();
4586 alias getArray this;
4589 static class C : I
4591 static dtorCount = 0;
4592 ~this() { ++dtorCount; }
4594 S[3] a;
4595 alias a this;
4597 ref S[3] getArray() { return a; }
4600 C c = new C();
4601 destroy(c);
4602 assert(S.dtorCount == 3);
4603 assert(C.dtorCount == 1);
4605 I i = new C();
4606 destroy(i);
4607 assert(S.dtorCount == 6);
4608 assert(C.dtorCount == 2);
4611 /// ditto
4612 void destroy(bool initialize = true, T)(ref T obj)
4613 if (!is(T == struct) && !is(T == interface) && !is(T == class) && !__traits(isStaticArray, T))
4615 static if (initialize)
4616 obj = T.init;
4619 @safe unittest
4622 int a = 42;
4623 destroy!false(a);
4624 assert(a == 42);
4625 destroy(a);
4626 assert(a == 0);
4629 float a = 42;
4630 destroy!false(a);
4631 assert(a == 42);
4632 destroy(a);
4633 assert(a != a); // isnan
4637 @safe unittest
4639 // Bugzilla 14746
4640 static struct HasDtor
4642 ~this() { assert(0); }
4644 static struct Owner
4646 HasDtor* ptr;
4647 alias ptr this;
4650 Owner o;
4651 assert(o.ptr is null);
4652 destroy(o); // must not reach in HasDtor.__dtor()
4655 /* ************************************************************************
4656 COMPILER SUPPORT
4657 The compiler lowers certain expressions to instantiations of the following
4658 templates. They must be implicitly imported, which is why they are here
4659 in this file. They must also be `public` as they must be visible from the
4660 scope in which they are instantiated. They are explicitly undocumented as
4661 they are only intended to be instantiated by the compiler, not the user.
4662 **************************************************************************/
4664 public import core.internal.entrypoint : _d_cmain;
4666 public import core.internal.array.appending : _d_arrayappendT;
4667 version (D_ProfileGC)
4669 public import core.internal.array.appending : _d_arrayappendTTrace;
4670 public import core.internal.array.appending : _d_arrayappendcTXTrace;
4671 public import core.internal.array.concatenation : _d_arraycatnTXTrace;
4672 public import core.lifetime : _d_newitemTTrace;
4673 public import core.internal.array.construction : _d_newarrayTTrace;
4674 public import core.internal.array.construction : _d_newarraymTXTrace;
4676 public import core.internal.array.appending : _d_arrayappendcTX;
4677 public import core.internal.array.comparison : __cmp;
4678 public import core.internal.array.equality : __equals;
4679 public import core.internal.array.casting: __ArrayCast;
4680 public import core.internal.array.concatenation : _d_arraycatnTX;
4681 public import core.internal.array.construction : _d_arrayctor;
4682 public import core.internal.array.construction : _d_arraysetctor;
4683 public import core.internal.array.construction : _d_newarrayT;
4684 public import core.internal.array.construction : _d_newarraymTX;
4685 public import core.internal.array.arrayassign : _d_arrayassign_l;
4686 public import core.internal.array.arrayassign : _d_arrayassign_r;
4687 public import core.internal.array.arrayassign : _d_arraysetassign;
4688 public import core.internal.array.capacity: _d_arraysetlengthTImpl;
4690 public import core.internal.dassert: _d_assert_fail;
4692 public import core.internal.destruction: __ArrayDtor;
4694 public import core.internal.moving: __move_post_blt;
4696 public import core.internal.postblit: __ArrayPostblit;
4698 public import core.internal.switch_: __switch;
4699 public import core.internal.switch_: __switch_error;
4701 public import core.lifetime : _d_delstructImpl;
4702 public import core.lifetime : _d_newThrowable;
4703 public import core.lifetime : _d_newclassT;
4704 public import core.lifetime : _d_newclassTTrace;
4705 public import core.lifetime : _d_newitemT;
4707 public @trusted @nogc nothrow pure extern (C) void _d_delThrowable(scope Throwable);
4709 // Compare class and interface objects for ordering.
4710 int __cmp(C1, C2)(C1 lhs, C2 rhs)
4711 if ((is(C1 : const(Object)) || (is(C1 == interface) && (__traits(getLinkage, C1) == "D"))) &&
4712 (is(C2 : const(Object)) || (is(C2 == interface) && (__traits(getLinkage, C2) == "D"))))
4714 static if (is(C1 == typeof(null)) && is(C2 == typeof(null)))
4716 return 0;
4718 else static if (is(C1 == typeof(null)))
4720 // Regard null references as always being "less than"
4721 return -1;
4723 else static if (is(C2 == typeof(null)))
4725 return 1;
4727 else
4729 if (lhs is rhs)
4730 return 0;
4731 if (lhs is null)
4732 return -1;
4733 if (rhs is null)
4734 return 1;
4735 return lhs.opCmp(rhs);
4739 // objects
4740 @safe unittest
4742 class C
4744 int i;
4745 this(int i) { this.i = i; }
4747 override int opCmp(Object c) const @safe
4749 return i - (cast(C)c).i;
4753 auto c1 = new C(1);
4754 auto c2 = new C(2);
4755 assert(__cmp(c1, null) > 0);
4756 assert(__cmp(null, c1) < 0);
4757 assert(__cmp(c1, c1) == 0);
4758 assert(__cmp(c1, c2) < 0);
4759 assert(__cmp(c2, c1) > 0);
4761 assert(__cmp([c1, c1][], [c2, c2][]) < 0);
4762 assert(__cmp([c2, c2], [c1, c1]) > 0);
4765 // structs
4766 @safe unittest
4768 struct C
4770 ubyte i;
4771 this(ubyte i) { this.i = i; }
4774 auto c1 = C(1);
4775 auto c2 = C(2);
4777 assert(__cmp([c1, c1][], [c2, c2][]) < 0);
4778 assert(__cmp([c2, c2], [c1, c1]) > 0);
4779 assert(__cmp([c2, c2], [c2, c1]) > 0);
4782 @safe unittest
4784 auto a = "hello"c;
4786 assert(a > "hel");
4787 assert(a >= "hel");
4788 assert(a < "helloo");
4789 assert(a <= "helloo");
4790 assert(a > "betty");
4791 assert(a >= "betty");
4792 assert(a == "hello");
4793 assert(a <= "hello");
4794 assert(a >= "hello");
4795 assert(a < "я");
4798 // Used in Exception Handling LSDA tables to 'wrap' C++ type info
4799 // so it can be distinguished from D TypeInfo
4800 class __cpp_type_info_ptr
4802 void* ptr; // opaque pointer to C++ RTTI type info
4805 // Compiler hook into the runtime implementation of array (vector) operations.
4806 template _arrayOp(Args...)
4808 import core.internal.array.operations;
4809 alias _arrayOp = arrayOp!Args;
4812 public import core.builtins : __ctfeWrite;
4816 Provides an "inline import", i.e. an `import` that is only available for a
4817 limited lookup. For example:
4820 void fun(imported!"std.stdio".File input)
4822 ... use File from std.stdio normally ...
4826 There is no need to import `std.stdio` at top level, so `fun` carries its own
4827 dependencies. The same approach can be used for template constraints:
4830 void fun(T)(imported!"std.stdio".File input, T value)
4831 if (imported!"std.traits".isIntegral!T)
4837 An inline import may be used in conjunction with the `with` statement as well.
4838 Inside the scope controlled by `with`, all symbols in the imported module are
4839 made available:
4842 void fun()
4844 with (imported!"std.datetime")
4845 with (imported!"std.stdio")
4847 Clock.currTime.writeln;
4852 The advantages of inline imports over top-level uses of the `import` declaration
4853 are the following:
4855 $(UL
4856 $(LI The `imported` template specifies dependencies at declaration level, not at
4857 module level. This allows reasoning about the dependency cost of declarations in
4858 separation instead of aggregated at module level.)
4859 $(LI Declarations using `imported` are easier to move around because they don't
4860 require top-level context, making for simpler and quicker refactorings.)
4861 $(LI Declarations using `imported` scale better with templates. This is because
4862 templates that are not instantiated do not have their parameters and constraints
4863 instantiated, so additional modules are not imported without necessity. This
4864 makes the cost of unused templates negligible. Dependencies are pulled on a need
4865 basis depending on the declarations used by client code.)
4868 The use of `imported` also has drawbacks:
4870 $(UL
4871 $(LI If most declarations in a module need the same imports, then factoring them
4872 at top level, outside the declarations, is simpler than repeating them.)
4873 $(LI Traditional dependency-tracking tools such as make and other build systems
4874 assume file-level dependencies and need special tooling (such as rdmd) in order
4875 to work efficiently.)
4876 $(LI Dependencies at the top of a module are easier to inspect quickly than
4877 dependencies spread throughout the module.)
4880 See_Also: The $(HTTP forum.dlang.org/post/tzqzmqhankrkbrfsrmbo@forum.dlang.org,
4881 forum discussion) that led to the creation of the `imported` facility. Credit is
4882 due to Daniel Nielsen and Dominikus Dittes Scherkl.
4885 template imported(string moduleName)
4887 mixin("import imported = " ~ moduleName ~ ";");