2 * $(SCRIPT inhibitQuickIndex = 1;)
5 * $(TR $(TH Category) $(TH Symbols))
6 * $(TR $(TD Arrays) $(TD
7 * $(MYREF assumeSafeAppend)
9 * $(A #.dup.2, $(TT dup))
13 * $(TR $(TD Associative arrays) $(TD
26 * $(TR $(TD General) $(TD
32 * $(TR $(TD Classes) $(TD
39 * $(TR $(TD Type info) $(TD
42 * $(MYREF OffsetTypeInfo)
44 * $(MYREF rtinfoNoPointers)
46 * $(MYREF TypeInfo_Class)
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
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)
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.
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().
89 // No TypeInfo-based core.vararg.va_arg().
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
101 else version (iOS) {}
102 else version (TVOS) {}
103 else version (WatchOS) {}
104 else version = WithArgTypes;
108 * All D class objects inherit from Object.
113 * Convert Object to a human readable string.
117 return typeid(this).name;
122 enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
123 enum fqn_unittest = "object.Object." ~ unittest_sym_name; // object.__unittest_LX_CY
127 Object obj = new Object;
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.
155 * $(TR $(TD this < obj) $(TD < 0))
156 * $(TR $(TD this == obj) $(TD 0))
157 * $(TR $(TD this > obj) $(TD > 0))
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);
171 Object obj = new Object;
176 obj.opCmp(new Object);
181 assert(e.msg == "need opCmp for class object.Object");
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.
198 * // the typed overload first. It can use all the attribute you want
199 * bool opEquals(const Child c) const @safe pure nothrow @nogc
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);
214 bool opEquals(Object o)
226 * Create instance of class specified by the fully qualified name
228 * The class must either have no constructors or have
229 * a default constructor.
244 * auto c = cast(C)Object.factory("foo.bar.C");
245 * assert(c !is null && c.x == 10);
249 static Object factory(string classname)
251 auto ci = TypeInfo_Class.find(classname);
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 (issue 7147). But CTFE also guarantees that equal TypeInfos are
294 always identical. So, no opEquals needed during CTFE. */
299 // General case => symmetric calls to method opEquals
300 return rhs.opEquals(lhs);
304 // this is a compatibility hack for the old const cast behavior
305 // if none of the new overloads compile, we'll go back plain Object,
306 // including casting away const. It does this through the pointer
307 // to bypass any opCast that may be present on the original class.
308 return .opEquals!(Object, Object)(*cast(Object*) &lhs, *cast(Object*) &rhs);
313 /// If aliased to the same object or both null => equal
314 @system unittest // this one is not @safe because it goes through the Object base method
316 class F { int flag; this(int flag) { this.flag = flag; } }
319 assert(f == f); // both null
321 assert(f == f); // both aliased to the same object
324 /// If either is null => non-equal
327 class F { int flag; this(int flag) { this.flag = flag; } }
329 assert(!(new F(0) == f));
330 assert(!(f == new F(0)));
333 /// If same exact type => one call to method opEquals
334 /// This test passes `@safe` because it defines a new opEquals with `@safe`
346 bool opEquals(const F o) const @safe nothrow pure
348 return flag == o.flag;
353 assert(new F(0) == new F(0));
354 assert(!(new F(0) == new F(1)));
357 /// General case => symmetric calls to method opEquals
360 int fEquals, gEquals;
373 this(int flag) { super(flag); }
375 bool opEquals(const Base o) @safe
378 return flag == o.flag;
384 this(int flag) { super(flag); }
386 bool opEquals(const Base o) @safe
389 return flag == o.flag;
393 assert(new F(1) == new G(1));
394 assert(fEquals == 1);
395 assert(gEquals == 1);
399 This test shows an example for a comprehensive inheritance equality chain too.
407 this(int member) pure @safe nothrow @nogc
409 this.member = member;
412 override bool opEquals(Object rhs) const
414 return this.opEquals(cast(Base) rhs);
417 bool opEquals(const Base rhs) const @nogc pure nothrow @safe
421 return this.member == rhs.member;
425 // works through the direct class with attributes enabled, except for pure and nogc in the current TypeInfo implementation
426 bool testThroughBase() nothrow @safe
428 Base b1 = new Base(0);
429 Base b2 = new Base(0);
431 Base b3 = new Base(1);
436 static assert(testThroughBase());
438 // also works through the base class interface thanks to the override, but no more attributes
439 bool testThroughObject()
441 Object o1 = new Base(0);
442 Object o2 = new Base(0);
444 Object o3 = new Base(1);
449 static assert(testThroughObject());
451 // Each time you make a child, you want to override all old opEquals
452 // and add a new overload for the new child.
453 static class Child : Base
457 this(int member, int member2) pure @safe nothrow @nogc
460 this.member2 = member2;
463 // override the whole chain so it works consistently though any base
464 override bool opEquals(Object rhs) const
466 return this.opEquals(cast(Child) rhs);
468 override bool opEquals(const Base rhs) const
470 return this.opEquals(cast(const Child) rhs);
472 // and then add the new overload, if necessary, to handle new members
473 bool opEquals(const Child rhs) const @nogc pure nothrow @safe
477 // can call back to the devirtualized base test with implicit conversion
478 // then compare the new member too. or we could have just compared the base
479 // member directly here as well.
480 return Base.opEquals(rhs) && this.member2 == rhs.member2;
483 // a mixin template, of course, could automate this.
486 bool testThroughChild()
488 Child a = new Child(0, 0);
489 Child b = new Child(0, 1);
503 static assert(testThroughChild());
506 // To cover const Object opEquals
509 const Object obj1 = new Object;
510 const Object obj2 = new Object;
512 assert(obj1 == obj1);
513 assert(obj1 != obj2);
516 // https://issues.dlang.org/show_bug.cgi?id=23291
519 static shared class C { bool opEquals(const(shared(C)) rhs) const shared { return true;}}
520 const(C) c = new C();
523 assert(a[0] == b[0]);
526 private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow;
528 void setSameMutex(shared Object ownee, shared Object owner)
530 _d_setSameMutex(ownee, owner);
535 shared Object obj1 = new Object;
540 shared C obj2 = new shared(C);
543 assert(obj1.__monitor != obj2.__monitor);
544 assert(obj1.__monitor is null);
546 setSameMutex(obj1, obj2);
547 assert(obj1.__monitor == obj2.__monitor);
548 assert(obj1.__monitor !is null);
552 * Information about an interface.
553 * When an object is accessed via an interface, an Interface* appears as the
554 * first entry in its vtbl.
558 /// Class info returned by `typeid` for this interface (not for containing class)
559 TypeInfo_Class classinfo;
561 size_t offset; /// offset to Interface 'this' from Object 'this'
565 * Array of pairs giving the offset and type information for each
566 * member in an aggregate.
568 struct OffsetTypeInfo
570 size_t offset; /// Offset of member from start of object
571 TypeInfo ti; /// TypeInfo for this member
575 * Runtime type information about a type.
576 * Can be retrieved for any type using a
577 * $(GLINK2 expression,TypeidExpression, TypeidExpression).
581 override string toString() const @safe nothrow
583 return typeid(this).name;
586 override size_t toHash() @trusted const nothrow
588 return hashOf(this.toString());
591 override int opCmp(Object rhs)
595 auto ti = cast(TypeInfo) rhs;
598 return __cmp(this.toString(), ti.toString());
603 assert(typeid(void) <= typeid(void));
604 assert(typeid(void).opCmp(null));
605 assert(!typeid(void).opCmp(typeid(void)));
608 override bool opEquals(Object o)
610 return opEquals(cast(TypeInfo) o);
613 bool opEquals(const TypeInfo ti) @safe nothrow const
615 /* TypeInfo instances are singletons, but duplicates can exist
616 * across DLL's. Therefore, comparing for a name match is
621 return ti && this.toString() == ti.toString();
626 auto anotherObj = new Object();
628 assert(typeid(void).opEquals(typeid(void)));
629 assert(typeid(void) != anotherObj); // calling .opEquals here directly is a type mismatch
633 * Computes a hash of the instance of a type.
635 * p = pointer to start of instance of the type
639 * fix https://issues.dlang.org/show_bug.cgi?id=12516 e.g. by changing this to a truly safe interface.
641 size_t getHash(scope const void* p) @trusted nothrow const
646 /// Compares two instances for equality.
647 bool equals(in void* p1, in void* p2) const { return p1 == p2; }
649 /// Compares two instances for <, ==, or >.
650 int compare(in void* p1, in void* p2) const { return _xopCmp(p1, p2); }
652 /// Returns size of the type.
653 @property size_t tsize() nothrow pure const @safe @nogc { return 0; }
655 /// Swaps two instances of the type.
656 void swap(void* p1, void* p2) const
658 size_t remaining = tsize;
659 // If the type might contain pointers perform the swap in pointer-sized
660 // chunks in case a garbage collection pass interrupts this function.
661 if ((cast(size_t) p1 | cast(size_t) p2) % (void*).alignof == 0)
663 while (remaining >= (void*).sizeof)
665 void* tmp = *cast(void**) p1;
666 *cast(void**) p1 = *cast(void**) p2;
667 *cast(void**) p2 = tmp;
668 p1 += (void*).sizeof;
669 p2 += (void*).sizeof;
670 remaining -= (void*).sizeof;
673 for (size_t i = 0; i < remaining; i++)
675 byte t = (cast(byte *)p1)[i];
676 (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
677 (cast(byte*)p2)[i] = t;
683 class _TypeInfo_Dummy : TypeInfo
685 override const(void)[] initializer() const { return []; }
686 @property override size_t tsize() nothrow pure const @safe @nogc { return tsize_val; }
690 auto dummy = new _TypeInfo_Dummy();
691 cast(void)dummy.initializer(); // For coverage completeness
695 // does nothing because tsize is 0
699 dummy.tsize_val = int.sizeof;
704 void* ptr_a = null, ptr_b = cast(void*)1;
705 dummy.tsize_val = (void*).sizeof;
706 dummy.swap(&ptr_a, &ptr_b);
707 assert(ptr_a is cast(void*)1);
708 assert(ptr_b is null);
711 /** Get TypeInfo for 'next' type, as defined by what kind of type this is,
713 @property inout(TypeInfo) next() nothrow pure inout @nogc { return null; }
716 * Return default initializer. If the type should be initialized to all
717 * zeros, an array with a null ptr and a length equal to the type size will
718 * be returned. For static arrays, this returns the default initializer for
719 * a single element of the array, use `tsize` to get the correct size.
721 abstract const(void)[] initializer() nothrow pure const @safe @nogc;
723 /** Get flags for type: 1 means GC should scan for pointers,
724 2 means arg of this type is passed in SIMD register(s) if available */
725 @property uint flags() nothrow pure const @safe @nogc { return 0; }
727 /// Get type information on the contents of the type; null if not available
728 const(OffsetTypeInfo)[] offTi() const { return null; }
729 /// Run the destructor on the object and all its sub-objects
730 void destroy(void* p) const {}
731 /// Run the postblit on the object and all its sub-objects
732 void postblit(void* p) const {}
735 /// Return alignment of type
736 @property size_t talign() nothrow pure const @safe @nogc { return tsize; }
738 /** Return internal info on arguments fitting into 8byte.
739 * See X86-64 ABI 3.2.3
741 version (WithArgTypes) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow
747 /** Return info used by the garbage collector to do precise collection.
749 @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return rtinfoHasPointers; } // better safe than sorry
754 class _TypeInfo_Dummy : TypeInfo
756 override const(void)[] initializer() const { return []; }
758 auto dummy = new _TypeInfo_Dummy();
759 cast(void)dummy.initializer(); // For coverage completeness
761 assert(dummy.rtInfo() is rtinfoHasPointers);
762 assert(typeid(void).rtInfo() is rtinfoNoPointers);
764 assert(dummy.tsize() == 0);
769 dummy.compare(null, null);
773 assert(e.msg == "TypeInfo.compare is not implemented");
777 assert(dummy.equals(null, null));
778 assert(!dummy.equals(cast(void*)1, null));
783 assert(typeid(void).next() is null);
784 assert(typeid(void).offTi() is null);
785 assert(typeid(void).tsize() == 1);
787 version (WithArgTypes)
791 assert(typeid(void).argTypes(ti1, ti2) == 0);
792 assert(typeid(void) is ti1);
794 assert(ti1 !is null);
801 class _ZypeInfo_Dummy : TypeInfo
803 override const(void)[] initializer() const { return []; }
805 auto dummy2 = new _ZypeInfo_Dummy();
806 cast(void)dummy2.initializer(); // For coverage completeness
808 assert(typeid(void) > dummy2);
809 assert(dummy2 < typeid(void));
814 enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
815 enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
817 class _TypeInfo_Dummy : TypeInfo
819 override const(void)[] initializer() const { return []; }
822 auto dummy = new _TypeInfo_Dummy();
823 cast(void)dummy.initializer(); // For coverage completeness
825 assert(dummy.toString() == fqn_unittest ~ "._TypeInfo_Dummy");
826 assert(dummy.toHash() == hashOf(dummy.toString()));
827 assert(dummy.getHash(null) == 0);
830 class TypeInfo_Enum : TypeInfo
832 override string toString() const pure { return name; }
834 override bool opEquals(Object o)
838 auto c = cast(const TypeInfo_Enum)o;
839 return c && this.name == c.name &&
848 assert(typeid(E).opEquals(typeid(E)));
849 assert(!typeid(E).opEquals(typeid(EE)));
852 override size_t getHash(scope const void* p) const { return base.getHash(p); }
860 assert(typeid(E).getHash(&e1) == hashOf(E.A));
861 assert(typeid(E).getHash(&e2) == hashOf(E.B));
863 enum ES : string { A = "foo", B = "bar" }
867 assert(typeid(ES).getHash(&es1) == hashOf("foo"));
868 assert(typeid(ES).getHash(&es2) == hashOf("bar"));
871 override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
880 assert(typeid(E).equals(&e1, &e1));
881 assert(!typeid(E).equals(&e1, &e2));
884 override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
893 assert(typeid(E).compare(&e1, &e1) == 0);
894 assert(typeid(E).compare(&e1, &e2) < 0);
895 assert(typeid(E).compare(&e2, &e1) > 0);
898 override @property size_t tsize() nothrow pure const { return base.tsize; }
903 enum ES : string { A = "a", B = "b", C = "c"}
905 assert(typeid(E).tsize == E.sizeof);
906 assert(typeid(ES).tsize == ES.sizeof);
907 assert(typeid(E).tsize != ES.sizeof);
910 override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
919 typeid(E).swap(&e1, &e2);
924 override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
930 assert(typeid(E).next is null);
933 override @property uint flags() nothrow pure const { return base.flags; }
939 assert(typeid(E).flags == 0);
942 override const(OffsetTypeInfo)[] offTi() const { return base.offTi; }
948 assert(typeid(E).offTi is null);
951 override void destroy(void* p) const { return base.destroy(p); }
952 override void postblit(void* p) const { return base.postblit(p); }
954 override const(void)[] initializer() const
956 return m_init.length ? m_init : base.initializer();
959 override @property size_t talign() nothrow pure const { return base.talign; }
961 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
963 return base.argTypes(arg1, arg2);
966 override @property immutable(void)* rtInfo() const { return base.rtInfo; }
975 enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
976 enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
981 assert(typeid(E).toString() == fqn_unittest ~ ".E");
985 @safe unittest // issue 12233
987 static assert(is(typeof(TypeInfo.init) == TypeInfo));
988 assert(TypeInfo.init is null);
992 // Please make sure to keep this in sync with TypeInfo_P (src/rt/typeinfo/ti_ptr.d)
993 class TypeInfo_Pointer : TypeInfo
995 override string toString() const { return m_next.toString() ~ "*"; }
997 override bool opEquals(Object o)
1001 auto c = cast(const TypeInfo_Pointer)o;
1002 return c && this.m_next == c.m_next;
1005 override size_t getHash(scope const void* p) @trusted const
1007 size_t addr = cast(size_t) *cast(const void**)p;
1008 return addr ^ (addr >> 4);
1011 override bool equals(in void* p1, in void* p2) const
1013 return *cast(void**)p1 == *cast(void**)p2;
1016 override int compare(in void* p1, in void* p2) const
1018 const v1 = *cast(void**) p1, v2 = *cast(void**) p2;
1019 return (v1 > v2) - (v1 < v2);
1022 override @property size_t tsize() nothrow pure const
1024 return (void*).sizeof;
1027 override const(void)[] initializer() const @trusted
1029 return (cast(void *)null)[0 .. (void*).sizeof];
1032 override void swap(void* p1, void* p2) const
1034 void* tmp = *cast(void**)p1;
1035 *cast(void**)p1 = *cast(void**)p2;
1036 *cast(void**)p2 = tmp;
1039 override @property inout(TypeInfo) next() nothrow pure inout { return m_next; }
1040 override @property uint flags() nothrow pure const { return 1; }
1045 class TypeInfo_Array : TypeInfo
1047 override string toString() const { return value.toString() ~ "[]"; }
1049 override bool opEquals(Object o)
1053 auto c = cast(const TypeInfo_Array)o;
1054 return c && this.value == c.value;
1057 override size_t getHash(scope const void* p) @trusted const
1059 void[] a = *cast(void[]*)p;
1060 return getArrayHash(value, a.ptr, a.length);
1063 override bool equals(in void* p1, in void* p2) const
1065 void[] a1 = *cast(void[]*)p1;
1066 void[] a2 = *cast(void[]*)p2;
1067 if (a1.length != a2.length)
1069 size_t sz = value.tsize;
1070 for (size_t i = 0; i < a1.length; i++)
1072 if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))
1078 override int compare(in void* p1, in void* p2) const
1080 void[] a1 = *cast(void[]*)p1;
1081 void[] a2 = *cast(void[]*)p2;
1082 size_t sz = value.tsize;
1083 size_t len = a1.length;
1085 if (a2.length < len)
1087 for (size_t u = 0; u < len; u++)
1089 immutable int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
1093 return (a1.length > a2.length) - (a1.length < a2.length);
1096 override @property size_t tsize() nothrow pure const
1098 return (void[]).sizeof;
1101 override const(void)[] initializer() const @trusted
1103 return (cast(void *)null)[0 .. (void[]).sizeof];
1106 override void swap(void* p1, void* p2) const
1108 void[] tmp = *cast(void[]*)p1;
1109 *cast(void[]*)p1 = *cast(void[]*)p2;
1110 *cast(void[]*)p2 = tmp;
1115 override @property inout(TypeInfo) next() nothrow pure inout
1120 override @property uint flags() nothrow pure const { return 1; }
1122 override @property size_t talign() nothrow pure const
1124 return (void[]).alignof;
1127 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1129 arg1 = typeid(size_t);
1130 arg2 = typeid(void*);
1134 override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(void[]); }
1137 class TypeInfo_StaticArray : TypeInfo
1139 override string toString() const
1141 import core.internal.string : unsignedToTempString;
1143 char[20] tmpBuff = void;
1144 const lenString = unsignedToTempString(len, tmpBuff);
1146 return (() @trusted => cast(string) (value.toString() ~ "[" ~ lenString ~ "]"))();
1149 override bool opEquals(Object o)
1153 auto c = cast(const TypeInfo_StaticArray)o;
1154 return c && this.len == c.len &&
1155 this.value == c.value;
1158 override size_t getHash(scope const void* p) @trusted const
1160 return getArrayHash(value, p, len);
1163 override bool equals(in void* p1, in void* p2) const
1165 size_t sz = value.tsize;
1167 for (size_t u = 0; u < len; u++)
1169 if (!value.equals(p1 + u * sz, p2 + u * sz))
1175 override int compare(in void* p1, in void* p2) const
1177 size_t sz = value.tsize;
1179 for (size_t u = 0; u < len; u++)
1181 immutable int result = value.compare(p1 + u * sz, p2 + u * sz);
1188 override @property size_t tsize() nothrow pure const
1190 return len * value.tsize;
1193 override void swap(void* p1, void* p2) const
1195 import core.stdc.string : memcpy;
1197 size_t remaining = value.tsize * len;
1198 void[size_t.sizeof * 4] buffer = void;
1199 while (remaining > buffer.length)
1201 memcpy(buffer.ptr, p1, buffer.length);
1202 memcpy(p1, p2, buffer.length);
1203 memcpy(p2, buffer.ptr, buffer.length);
1204 p1 += buffer.length;
1205 p2 += buffer.length;
1206 remaining -= buffer.length;
1208 memcpy(buffer.ptr, p1, remaining);
1209 memcpy(p1, p2, remaining);
1210 memcpy(p2, buffer.ptr, remaining);
1213 override const(void)[] initializer() nothrow pure const
1215 return value.initializer();
1218 override @property inout(TypeInfo) next() nothrow pure inout { return value; }
1219 override @property uint flags() nothrow pure const { return value.flags; }
1221 override void destroy(void* p) const
1223 immutable sz = value.tsize;
1225 foreach (i; 0 .. len)
1232 override void postblit(void* p) const
1234 immutable sz = value.tsize;
1235 foreach (i; 0 .. len)
1245 override @property size_t talign() nothrow pure const
1247 return value.talign;
1250 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1252 arg1 = typeid(void*);
1256 // just return the rtInfo of the element, we have no generic type T to run RTInfo!T on
1257 override @property immutable(void)* rtInfo() nothrow pure const @safe { return value.rtInfo(); }
1260 // https://issues.dlang.org/show_bug.cgi?id=21315
1264 foreach (int i; 0 .. 16)
1269 typeid(int[16]).swap(&a, &b);
1270 foreach (int i; 0 .. 16)
1277 class TypeInfo_AssociativeArray : TypeInfo
1279 override string toString() const
1281 return value.toString() ~ "[" ~ key.toString() ~ "]";
1284 override bool opEquals(Object o)
1288 auto c = cast(const TypeInfo_AssociativeArray)o;
1289 return c && this.key == c.key &&
1290 this.value == c.value;
1293 override bool equals(in void* p1, in void* p2) @trusted const
1295 return !!_aaEqual(this, *cast(const AA*) p1, *cast(const AA*) p2);
1298 override hash_t getHash(scope const void* p) nothrow @trusted const
1300 return _aaGetHash(cast(AA*)p, this);
1303 // BUG: need to add the rest of the functions
1305 override @property size_t tsize() nothrow pure const
1307 return (char[int]).sizeof;
1310 override const(void)[] initializer() const @trusted
1312 return (cast(void *)null)[0 .. (char[int]).sizeof];
1315 override @property inout(TypeInfo) next() nothrow pure inout { return value; }
1316 override @property uint flags() nothrow pure const { return 1; }
1321 override @property size_t talign() nothrow pure const
1323 return (char[int]).alignof;
1326 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1328 arg1 = typeid(void*);
1333 class TypeInfo_Vector : TypeInfo
1335 override string toString() const { return "__vector(" ~ base.toString() ~ ")"; }
1337 override bool opEquals(Object o)
1341 auto c = cast(const TypeInfo_Vector)o;
1342 return c && this.base == c.base;
1345 override size_t getHash(scope const void* p) const { return base.getHash(p); }
1346 override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
1347 override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
1348 override @property size_t tsize() nothrow pure const { return base.tsize; }
1349 override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
1351 override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
1352 override @property uint flags() nothrow pure const { return 2; /* passed in SIMD register */ }
1354 override const(void)[] initializer() nothrow pure const
1356 return base.initializer();
1359 override @property size_t talign() nothrow pure const { return 16; }
1361 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1363 return base.argTypes(arg1, arg2);
1369 class TypeInfo_Function : TypeInfo
1371 override string toString() const pure @trusted
1373 import core.demangle : demangleType;
1375 alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;
1376 SafeDemangleFunctionType demangle = cast(SafeDemangleFunctionType) &demangleType;
1378 return cast(string) demangle(deco);
1381 override bool opEquals(Object o)
1385 auto c = cast(const TypeInfo_Function)o;
1386 return c && this.deco == c.deco;
1389 // BUG: need to add the rest of the functions
1391 override @property size_t tsize() nothrow pure const
1393 return 0; // no size for functions
1396 override const(void)[] initializer() const @safe
1401 override @property immutable(void)* rtInfo() nothrow pure const @safe { return rtinfoNoPointers; }
1406 * Mangled function type string
1417 int func(int a, int b);
1420 alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
1421 assert(typeid(functionTypes[0]).toString() == "void function()");
1422 assert(typeid(functionTypes[1]).toString() == "void function(int)");
1423 assert(typeid(functionTypes[2]).toString() == "int function(int, int)");
1434 alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
1436 Object obj = typeid(functionTypes[0]);
1437 assert(obj.opEquals(typeid(functionTypes[0])));
1438 assert(typeid(functionTypes[0]) == typeid(functionTypes[0]));
1439 assert(typeid(functionTypes[0]) != typeid(functionTypes[1]));
1441 assert(typeid(functionTypes[0]).tsize() == 0);
1442 assert(typeid(functionTypes[0]).initializer() is null);
1443 assert(typeid(functionTypes[0]).rtInfo() is null);
1446 class TypeInfo_Delegate : TypeInfo
1448 override string toString() const pure @trusted
1450 import core.demangle : demangleType;
1452 alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;
1453 SafeDemangleFunctionType demangle = cast(SafeDemangleFunctionType) &demangleType;
1455 return cast(string) demangle(deco);
1460 double sqr(double x) { return x * x; }
1461 sqr(double.init); // for coverage completeness
1463 auto delegate_str = "double delegate(double) pure nothrow @nogc @safe";
1465 assert(typeid(typeof(&sqr)).toString() == delegate_str);
1466 assert(delegate_str.hashOf() == typeid(typeof(&sqr)).hashOf());
1467 assert(typeid(typeof(&sqr)).toHash() == typeid(typeof(&sqr)).hashOf());
1471 alias delegate_type = typeof((int a, int b) => a + b + g);
1472 delegate_str = "int delegate(int, int) pure nothrow @nogc @safe";
1474 assert(typeid(delegate_type).toString() == delegate_str);
1475 assert(delegate_str.hashOf() == typeid(delegate_type).hashOf());
1476 assert(typeid(delegate_type).toHash() == typeid(delegate_type).hashOf());
1479 override bool opEquals(Object o)
1483 auto c = cast(const TypeInfo_Delegate)o;
1484 return c && this.deco == c.deco;
1489 double sqr(double x) { return x * x; }
1490 int dbl(int x) { return x + x; }
1491 sqr(double.init); // for coverage completeness
1492 dbl(int.init); // for coverage completeness
1494 Object obj = typeid(typeof(&sqr));
1495 assert(obj.opEquals(typeid(typeof(&sqr))));
1496 assert(typeid(typeof(&sqr)) == typeid(typeof(&sqr)));
1497 assert(typeid(typeof(&dbl)) != typeid(typeof(&sqr)));
1500 override size_t getHash(scope const void* p) @trusted const
1502 return hashOf(*cast(const void delegate() *)p);
1505 override bool equals(in void* p1, in void* p2) const
1507 auto dg1 = *cast(void delegate()*)p1;
1508 auto dg2 = *cast(void delegate()*)p2;
1512 override int compare(in void* p1, in void* p2) const
1514 auto dg1 = *cast(void delegate()*)p1;
1515 auto dg2 = *cast(void delegate()*)p2;
1525 override @property size_t tsize() nothrow pure const
1527 alias dg = int delegate();
1531 override const(void)[] initializer() const @trusted
1533 return (cast(void *)null)[0 .. (int delegate()).sizeof];
1536 override @property uint flags() nothrow pure const { return 1; }
1541 override @property size_t talign() nothrow pure const
1543 alias dg = int delegate();
1547 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
1549 arg1 = typeid(void*);
1550 arg2 = typeid(void*);
1554 override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(int delegate()); }
1557 private extern (C) Object _d_newclass(const TypeInfo_Class ci);
1558 private extern (C) int _d_isbaseof(scope TypeInfo_Class child,
1559 scope const TypeInfo_Class parent) @nogc nothrow pure @safe; // rt.cast_
1562 * Runtime type information about a class.
1563 * Can be retrieved from an object instance by using the
1564 * $(DDSUBLINK spec/expression,typeid_expressions,typeid expression).
1566 class TypeInfo_Class : TypeInfo
1568 override string toString() const pure { return name; }
1570 override bool opEquals(const TypeInfo o) const
1574 auto c = cast(const TypeInfo_Class)o;
1575 return c && this.name == c.name;
1578 override size_t getHash(scope const void* p) @trusted const
1580 auto o = *cast(Object*)p;
1581 return o ? o.toHash() : 0;
1584 override bool equals(in void* p1, in void* p2) const
1586 Object o1 = *cast(Object*)p1;
1587 Object o2 = *cast(Object*)p2;
1589 return (o1 is o2) || (o1 && o1.opEquals(o2));
1592 override int compare(in void* p1, in void* p2) const
1594 Object o1 = *cast(Object*)p1;
1595 Object o2 = *cast(Object*)p2;
1598 // Regard null references as always being "less than"
1614 override @property size_t tsize() nothrow pure const
1616 return Object.sizeof;
1619 override const(void)[] initializer() nothrow pure const @safe
1624 override @property uint flags() nothrow pure const { return 1; }
1626 override @property const(OffsetTypeInfo)[] offTi() nothrow pure const
1631 final @property auto info() @safe @nogc nothrow pure const return { return this; }
1632 final @property auto typeinfo() @safe @nogc nothrow pure const return { return this; }
1634 byte[] m_init; /** class static initializer
1635 * (init.length gives size in bytes of class)
1637 string name; /// class name
1638 void*[] vtbl; /// virtual function pointer table
1639 Interface[] interfaces; /// interfaces this class implements
1640 TypeInfo_Class base; /// base class
1642 void function(Object) classInvariant;
1643 enum ClassFlags : uint
1649 hasGetMembers = 0x10,
1657 OffsetTypeInfo[] m_offTi;
1658 void function(Object) defaultConstructor; // default Constructor
1660 immutable(void)* m_RTInfo; // data for precise GC
1661 override @property immutable(void)* rtInfo() const { return m_RTInfo; }
1664 * Search all modules for TypeInfo_Class corresponding to classname.
1665 * Returns: null if not found
1667 static const(TypeInfo_Class) find(const scope char[] classname)
1669 foreach (m; ModuleInfo)
1673 //writefln("module %s, %d", m.name, m.localClasses.length);
1674 foreach (c; m.localClasses)
1678 //writefln("\tclass %s", c.name);
1679 if (c.name == classname)
1688 * Create instance of Object represented by 'this'.
1690 Object create() const
1692 if (m_flags & 8 && !defaultConstructor)
1694 if (m_flags & 64) // abstract
1696 Object o = _d_newclass(this);
1697 if (m_flags & 8 && defaultConstructor)
1699 defaultConstructor(o);
1705 * Returns true if the class described by `child` derives from or is
1706 * the class described by this `TypeInfo_Class`. Always returns false
1707 * if the argument is null.
1710 * child = TypeInfo for some class
1712 * true if the class described by `child` derives from or is the
1713 * class described by this `TypeInfo_Class`.
1715 final bool isBaseOf(scope const TypeInfo_Class child) const @nogc nothrow pure @trusted
1719 // If this TypeInfo_Class represents an actual class we only need
1720 // to check the child and its direct ancestors.
1721 for (auto ti = cast() child; ti !is null; ti = ti.base)
1728 // If this TypeInfo_Class is the .info field of a TypeInfo_Interface
1729 // we also need to recursively check the child's interfaces.
1730 return child !is null && _d_isbaseof(cast() child, this);
1735 alias ClassInfo = TypeInfo_Class;
1745 assert(typeid(X).initializer is typeid(X).m_init);
1746 assert(typeid(X).initializer.length == typeid(const(X)).initializer.length);
1747 assert(typeid(X).initializer.length == typeid(shared(X)).initializer.length);
1748 assert(typeid(X).initializer.length == typeid(immutable(X)).initializer.length);
1751 class TypeInfo_Interface : TypeInfo
1753 override string toString() const pure { return info.name; }
1755 override bool opEquals(Object o)
1759 auto c = cast(const TypeInfo_Interface)o;
1760 return c && this.info.name == typeid(c).name;
1763 override size_t getHash(scope const void* p) @trusted const
1765 if (!*cast(void**)p)
1769 Interface* pi = **cast(Interface ***)*cast(void**)p;
1770 Object o = cast(Object)(*cast(void**)p - pi.offset);
1775 override bool equals(in void* p1, in void* p2) const
1777 Interface* pi = **cast(Interface ***)*cast(void**)p1;
1778 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
1779 pi = **cast(Interface ***)*cast(void**)p2;
1780 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
1782 return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
1785 override int compare(in void* p1, in void* p2) const
1787 Interface* pi = **cast(Interface ***)*cast(void**)p1;
1788 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
1789 pi = **cast(Interface ***)*cast(void**)p2;
1790 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
1793 // Regard null references as always being "less than"
1809 override @property size_t tsize() nothrow pure const
1811 return Object.sizeof;
1814 override const(void)[] initializer() const @trusted
1816 return (cast(void *)null)[0 .. Object.sizeof];
1819 override @property uint flags() nothrow pure const { return 1; }
1821 TypeInfo_Class info;
1824 * Returns true if the class described by `child` derives from the
1825 * interface described by this `TypeInfo_Interface`. Always returns
1826 * false if the argument is null.
1829 * child = TypeInfo for some class
1831 * true if the class described by `child` derives from the
1832 * interface described by this `TypeInfo_Interface`.
1834 final bool isBaseOf(scope const TypeInfo_Class child) const @nogc nothrow pure @trusted
1836 return child !is null && _d_isbaseof(cast() child, this.info);
1840 * Returns true if the interface described by `child` derives from
1841 * or is the interface described by this `TypeInfo_Interface`.
1842 * Always returns false if the argument is null.
1845 * child = TypeInfo for some interface
1847 * true if the interface described by `child` derives from or is
1848 * the interface described by this `TypeInfo_Interface`.
1850 final bool isBaseOf(scope const TypeInfo_Interface child) const @nogc nothrow pure @trusted
1852 return child !is null && _d_isbaseof(cast() child.info, this.info);
1858 enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
1859 enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
1863 assert(fqn_unittest ~ ".I" == typeid(I).info.name);
1864 assert((fqn_unittest ~ ".I").hashOf() == typeid(I).hashOf());
1865 assert(typeid(I).toHash() == typeid(I).hashOf());
1868 class TypeInfo_Struct : TypeInfo
1870 override string toString() const { return name; }
1872 override size_t toHash() const
1874 return hashOf(this.mangledName);
1877 override bool opEquals(Object o)
1881 auto s = cast(const TypeInfo_Struct)o;
1882 return s && this.mangledName == s.mangledName;
1885 override size_t getHash(scope const void* p) @trusted pure nothrow const
1890 return (*xtoHash)(p);
1894 return hashOf(p[0 .. initializer().length]);
1898 override bool equals(in void* p1, in void* p2) @trusted pure nothrow const
1900 import core.stdc.string : memcmp;
1906 const dg = _memberFunc(p1, xopEquals);
1907 return dg.xopEquals(p2);
1912 // BUG: relies on the GC not moving objects
1913 return memcmp(p1, p2, initializer().length) == 0;
1916 override int compare(in void* p1, in void* p2) @trusted pure nothrow const
1918 import core.stdc.string : memcmp;
1920 // Regard null references as always being "less than"
1929 const dg = _memberFunc(p1, xopCmp);
1930 return dg.xopCmp(p2);
1933 // BUG: relies on the GC not moving objects
1934 return memcmp(p1, p2, initializer().length);
1942 override @property size_t tsize() nothrow pure const
1944 return initializer().length;
1947 override const(void)[] initializer() nothrow pure const @safe
1952 override @property uint flags() nothrow pure const { return m_flags; }
1954 override @property size_t talign() nothrow pure const { return m_align; }
1956 final override void destroy(void* p) const
1960 if (m_flags & StructFlags.isDynamicType)
1961 (*xdtorti)(p, this);
1967 override void postblit(void* p) const
1975 final @property string name() nothrow const @trusted
1977 import core.demangle : demangleType;
1979 if (mangledName is null) // e.g., opaque structs
1982 const key = cast(const void*) this; // faster lookup than TypeInfo_Struct, at the cost of potential duplicates per binary
1983 static string[typeof(key)] demangledNamesCache; // per thread
1986 //return demangledNamesCache.require(key, cast(string) demangleType(mangledName));
1988 if (auto pDemangled = key in demangledNamesCache)
1991 const demangled = cast(string) demangleType(mangledName);
1992 demangledNamesCache[key] = demangled;
1996 void[] m_init; // initializer; m_init.ptr == null if 0 initialize
2000 size_t function(in void*) xtoHash;
2001 bool function(in void*, in void*) xopEquals;
2002 int function(in void*, in void*) xopCmp;
2003 string function(in void*) xtoString;
2005 enum StructFlags : uint
2008 isDynamicType = 0x2, // built at runtime, needs type info in xdtor
2010 StructFlags m_flags;
2014 void function(void*) xdtor;
2015 void function(void*, const TypeInfo_Struct ti) xdtorti;
2017 void function(void*) xpostblit;
2021 override @property immutable(void)* rtInfo() nothrow pure const @safe { return m_RTInfo; }
2023 version (WithArgTypes)
2025 override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2034 immutable(void)* m_RTInfo; // data for precise GC
2036 // The xopEquals and xopCmp members are function pointers to member
2037 // functions, which is not guaranteed to share the same ABI, as it is not
2038 // known whether the `this` parameter is the first or second argument.
2039 // This wrapper is to convert it to a delegate which will always pass the
2040 // `this` parameter in the correct way.
2041 private struct _memberFunc
2048 const void* funcptr;
2052 bool delegate(in void*) xopEquals;
2053 int delegate(in void*) xopCmp;
2063 bool opEquals(ref const S rhs) const
2069 assert(!typeid(S).equals(&s, &s));
2072 class TypeInfo_Tuple : TypeInfo
2074 TypeInfo[] elements;
2076 override string toString() const
2079 foreach (i, element; elements)
2083 s ~= element.toString();
2089 override bool opEquals(Object o)
2094 auto t = cast(const TypeInfo_Tuple)o;
2095 if (t && elements.length == t.elements.length)
2097 for (size_t i = 0; i < elements.length; i++)
2099 if (elements[i] != t.elements[i])
2107 override size_t getHash(scope const void* p) const
2112 override bool equals(in void* p1, in void* p2) const
2117 override int compare(in void* p1, in void* p2) const
2122 override @property size_t tsize() nothrow pure const
2127 override const(void)[] initializer() const @trusted
2132 override void swap(void* p1, void* p2) const
2137 override void destroy(void* p) const
2142 override void postblit(void* p) const
2147 override @property size_t talign() nothrow pure const
2152 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2158 class TypeInfo_Const : TypeInfo
2160 override string toString() const
2162 return cast(string) ("const(" ~ base.toString() ~ ")");
2165 //override bool opEquals(Object o) { return base.opEquals(o); }
2166 override bool opEquals(Object o)
2171 if (typeid(this) != typeid(o))
2174 auto t = cast(TypeInfo_Const)o;
2175 return base.opEquals(t.base);
2178 override size_t getHash(scope const void *p) const { return base.getHash(p); }
2179 override bool equals(in void *p1, in void *p2) const { return base.equals(p1, p2); }
2180 override int compare(in void *p1, in void *p2) const { return base.compare(p1, p2); }
2181 override @property size_t tsize() nothrow pure const { return base.tsize; }
2182 override void swap(void *p1, void *p2) const { return base.swap(p1, p2); }
2184 override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
2185 override @property uint flags() nothrow pure const { return base.flags; }
2187 override const(void)[] initializer() nothrow pure const
2189 return base.initializer();
2192 override @property size_t talign() nothrow pure const { return base.talign; }
2194 version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
2196 return base.argTypes(arg1, arg2);
2202 class TypeInfo_Invariant : TypeInfo_Const
2204 override string toString() const
2206 return cast(string) ("immutable(" ~ base.toString() ~ ")");
2210 class TypeInfo_Shared : TypeInfo_Const
2212 override string toString() const
2214 return cast(string) ("shared(" ~ base.toString() ~ ")");
2218 class TypeInfo_Inout : TypeInfo_Const
2220 override string toString() const
2222 return cast(string) ("inout(" ~ base.toString() ~ ")");
2226 // Contents of Moduleinfo._flags
2229 MIctorstart = 0x1, // we've started constructing it
2230 MIctordone = 0x2, // finished construction
2231 MIstandalone = 0x4, // module ctor does not depend on other module
2232 // ctors being done first
2237 MIxgetMembers = 0x80,
2240 MIimportedModules = 0x400,
2241 MIlocalClasses = 0x800,
2245 /*****************************************
2246 * An instance of ModuleInfo is generated into the object file for each compiled module.
2248 * It provides access to various aspects of the module.
2249 * It is not generated for betterC.
2253 uint _flags; // MIxxxx
2254 uint _index; // index into _moduleinfo_array[]
2258 deprecated("ModuleInfo cannot be copy-assigned because it is a variable-sized struct.")
2259 void opAssign(const scope ModuleInfo m) { _flags = m._flags; _index = m._index; }
2267 private void* addrOf(int flag) return nothrow pure @nogc
2270 assert(flag >= MItlsctor && flag <= MIname);
2271 assert(!(flag & (flag - 1)) && !(flag & ~(flag - 1) << 1));
2275 import core.stdc.string : strlen;
2277 void* p = cast(void*)&this + ModuleInfo.sizeof;
2279 if (flags & MItlsctor)
2281 if (flag == MItlsctor) return p;
2282 p += typeof(tlsctor).sizeof;
2284 if (flags & MItlsdtor)
2286 if (flag == MItlsdtor) return p;
2287 p += typeof(tlsdtor).sizeof;
2291 if (flag == MIctor) return p;
2292 p += typeof(ctor).sizeof;
2296 if (flag == MIdtor) return p;
2297 p += typeof(dtor).sizeof;
2299 if (flags & MIxgetMembers)
2301 if (flag == MIxgetMembers) return p;
2302 p += typeof(xgetMembers).sizeof;
2304 if (flags & MIictor)
2306 if (flag == MIictor) return p;
2307 p += typeof(ictor).sizeof;
2309 if (flags & MIunitTest)
2311 if (flag == MIunitTest) return p;
2312 p += typeof(unitTest).sizeof;
2314 if (flags & MIimportedModules)
2316 if (flag == MIimportedModules) return p;
2317 p += size_t.sizeof + *cast(size_t*)p * typeof(importedModules[0]).sizeof;
2319 if (flags & MIlocalClasses)
2321 if (flag == MIlocalClasses) return p;
2322 p += size_t.sizeof + *cast(size_t*)p * typeof(localClasses[0]).sizeof;
2324 if (true || flags & MIname) // always available for now
2326 if (flag == MIname) return p;
2327 p += strlen(cast(immutable char*)p);
2332 @property uint index() nothrow pure @nogc { return _index; }
2334 @property uint flags() nothrow pure @nogc { return _flags; }
2336 /************************
2338 * module constructor for thread locals, `null` if there isn't one
2340 @property void function() tlsctor() nothrow pure @nogc
2342 return flags & MItlsctor ? *cast(typeof(return)*)addrOf(MItlsctor) : null;
2345 /************************
2347 * module destructor for thread locals, `null` if there isn't one
2349 @property void function() tlsdtor() nothrow pure @nogc
2351 return flags & MItlsdtor ? *cast(typeof(return)*)addrOf(MItlsdtor) : null;
2354 /*****************************
2356 * address of a module's `const(MemberInfo)[] getMembers(string)` function, `null` if there isn't one
2358 @property void* xgetMembers() nothrow pure @nogc
2360 return flags & MIxgetMembers ? *cast(typeof(return)*)addrOf(MIxgetMembers) : null;
2363 /************************
2365 * module constructor, `null` if there isn't one
2367 @property void function() ctor() nothrow pure @nogc
2369 return flags & MIctor ? *cast(typeof(return)*)addrOf(MIctor) : null;
2372 /************************
2374 * module destructor, `null` if there isn't one
2376 @property void function() dtor() nothrow pure @nogc
2378 return flags & MIdtor ? *cast(typeof(return)*)addrOf(MIdtor) : null;
2381 /************************
2383 * module order independent constructor, `null` if there isn't one
2385 @property void function() ictor() nothrow pure @nogc
2387 return flags & MIictor ? *cast(typeof(return)*)addrOf(MIictor) : null;
2392 * address of function that runs the module's unittests, `null` if there isn't one
2394 @property void function() unitTest() nothrow pure @nogc
2396 return flags & MIunitTest ? *cast(typeof(return)*)addrOf(MIunitTest) : null;
2401 * array of pointers to the ModuleInfo's of modules imported by this one
2403 @property immutable(ModuleInfo*)[] importedModules() return nothrow pure @nogc
2405 if (flags & MIimportedModules)
2407 auto p = cast(size_t*)addrOf(MIimportedModules);
2408 return (cast(immutable(ModuleInfo*)*)(p + 1))[0 .. *p];
2415 * array of TypeInfo_Class references for classes defined in this module
2417 @property TypeInfo_Class[] localClasses() return nothrow pure @nogc
2419 if (flags & MIlocalClasses)
2421 auto p = cast(size_t*)addrOf(MIlocalClasses);
2422 return (cast(TypeInfo_Class*)(p + 1))[0 .. *p];
2427 /********************
2429 * name of module, `null` if no name
2431 @property string name() return nothrow pure @nogc
2433 import core.stdc.string : strlen;
2435 auto p = cast(immutable char*) addrOf(MIname);
2436 return p[0 .. strlen(p)];
2439 static int opApply(scope int delegate(ModuleInfo*) dg)
2441 import core.internal.traits : externDFunc;
2442 alias moduleinfos_apply = externDFunc!("rt.minfo.moduleinfos_apply",
2443 int function(scope int delegate(immutable(ModuleInfo*))));
2444 // Bugzilla 13084 - enforcing immutable ModuleInfo would break client code
2445 return moduleinfos_apply(
2446 (immutable(ModuleInfo*)m) => dg(cast(ModuleInfo*)m));
2453 foreach (m; ModuleInfo)
2459 ///////////////////////////////////////////////////////////////////////////////
2461 ///////////////////////////////////////////////////////////////////////////////
2465 * The base class of all thrown objects.
2467 * All thrown objects must inherit from Throwable. Class $(D Exception), which
2468 * derives from this class, represents the category of thrown objects that are
2469 * safe to catch and handle. In principle, one should not catch Throwable
2470 * objects that are not derived from $(D Exception), as they represent
2471 * unrecoverable runtime errors. Certain runtime guarantees may fail to hold
2472 * when these errors are thrown, making it unsafe to continue execution after
2475 class Throwable : Object
2479 int opApply(scope int delegate(ref const(char[]))) const;
2480 int opApply(scope int delegate(ref size_t, ref const(char[]))) const;
2481 string toString() const;
2484 alias TraceDeallocator = void function(TraceInfo) nothrow;
2486 string msg; /// A message describing the error.
2489 * The _file name of the D source code corresponding with
2490 * where the error was thrown from.
2494 * The _line number of the D source code corresponding with
2495 * where the error was thrown from.
2500 * The stack trace of where the error happened. This is an opaque object
2501 * that can either be converted to $(D string), or iterated over with $(D
2502 * foreach) to extract the items in the stack trace (as strings).
2507 * If set, this is used to deallocate the TraceInfo on destruction.
2509 TraceDeallocator infoDeallocator;
2513 * A reference to the _next error in the list. This is used when a new
2514 * $(D Throwable) is thrown from inside a $(D catch) block. The originally
2515 * caught $(D Exception) will be chained to the new $(D Throwable) via this
2518 private Throwable nextInChain;
2520 private uint _refcount; // 0 : allocated by GC
2521 // 1 : allocated by _d_newThrowable()
2522 // 2.. : reference count + 1
2526 * A reference to the _next error in the list. This is used when a new
2527 * $(D Throwable) is thrown from inside a $(D catch) block. The originally
2528 * caught $(D Exception) will be chained to the new $(D Throwable) via this
2531 @property inout(Throwable) next() @safe inout return scope pure nothrow @nogc { return nextInChain; }
2534 * Replace next in chain with `tail`.
2535 * Use `chainTogether` instead if at all possible.
2537 @property void next(Throwable tail) @safe scope pure nothrow @nogc
2539 if (tail && tail._refcount)
2540 ++tail._refcount; // increment the replacement *first*
2542 auto n = nextInChain;
2543 nextInChain = null; // sever the tail before deleting it
2545 if (n && n._refcount)
2546 _d_delThrowable(n); // now delete the old tail
2548 nextInChain = tail; // and set the new tail
2553 * mutable reference to the reference count, which is
2554 * 0 - allocated by the GC, 1 - allocated by _d_newThrowable(),
2555 * and >=2 which is the reference count + 1
2557 * Marked as `@system` to discourage casual use of it.
2559 @system @nogc final pure nothrow ref uint refcount() return { return _refcount; }
2562 * Loop over the chain of Throwables.
2564 int opApply(scope int delegate(Throwable) dg)
2567 for (Throwable t = this; t; t = t.nextInChain)
2577 * Append `e2` to chain of exceptions that starts with `e1`.
2579 * e1 = start of chain (can be null)
2580 * e2 = second part of chain (can be null)
2582 * Throwable that is at the start of the chain; null if both `e1` and `e2` are null
2584 static @__future @system @nogc pure nothrow Throwable chainTogether(return scope Throwable e1, return scope Throwable e2)
2593 for (auto e = e1; 1; e = e.nextInChain)
2604 @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)
2607 this.nextInChain = nextInChain;
2608 if (nextInChain && nextInChain._refcount)
2609 ++nextInChain._refcount;
2610 //this.info = _d_traceContext();
2613 @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)
2615 this(msg, nextInChain);
2618 //this.info = _d_traceContext();
2621 @trusted nothrow ~this()
2623 if (nextInChain && nextInChain._refcount)
2624 _d_delThrowable(nextInChain);
2625 // handle owned traceinfo
2626 if (infoDeallocator !is null)
2628 infoDeallocator(info);
2629 info = null; // avoid any kind of dangling pointers if we can help
2635 * Overrides $(D Object.toString) and returns the error message.
2636 * Internally this forwards to the $(D toString) overload that
2637 * takes a $(D_PARAM sink) delegate.
2639 override string toString()
2642 toString((in buf) { s ~= buf; });
2647 * The Throwable hierarchy uses a toString overload that takes a
2648 * $(D_PARAM _sink) delegate to avoid GC allocations, which cannot be
2649 * performed in certain error situations. Override this $(D
2650 * toString) method to customize the error message.
2652 void toString(scope void delegate(in char[]) sink) const
2654 import core.internal.string : unsignedToTempString;
2656 char[20] tmpBuff = void;
2658 sink(typeid(this).name);
2659 sink("@"); sink(file);
2660 sink("("); sink(unsignedToTempString(line, tmpBuff)); sink(")");
2664 sink(": "); sink(msg);
2670 sink("\n----------------");
2673 sink("\n"); sink(t);
2678 // ignore more errors
2684 * Get the message describing the error.
2686 * This getter is an alternative way to access the Exception's message,
2687 * with the added advantage of being override-able in subclasses.
2688 * Subclasses are hence free to do their own memory managements without
2689 * being tied to the requirement of providing a `string` in a field.
2691 * The default behavior is to return the `Throwable.msg` field.
2694 * A message representing the cause of the `Throwable`
2696 @__future const(char)[] message() const @safe nothrow
2704 * The base class of all errors that are safe to catch and handle.
2706 * In principle, only thrown objects derived from this class are safe to catch
2707 * inside a $(D catch) block. Thrown objects not derived from Exception
2708 * represent runtime errors that should not be caught, as certain runtime
2709 * guarantees may not hold, making it unsafe to continue program execution.
2711 class Exception : Throwable
2715 * Creates a new instance of Exception. The nextInChain parameter is used
2716 * internally and should always be $(D null) when passed by user code.
2717 * This constructor does not automatically throw the newly-created
2718 * Exception; the $(D throw) expression should be used for that purpose.
2720 @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null)
2722 super(msg, file, line, nextInChain);
2725 @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
2727 super(msg, file, line, nextInChain);
2737 throw new Exception("msg");
2742 assert(e.msg == "msg");
2750 auto e = new Exception("msg");
2751 assert(e.file == __FILE__);
2752 assert(e.line == __LINE__ - 2);
2753 assert(e.nextInChain is null);
2754 assert(e.msg == "msg");
2758 auto e = new Exception("msg", new Exception("It's an Exception!"), "hello", 42);
2759 assert(e.file == "hello");
2760 assert(e.line == 42);
2761 assert(e.nextInChain !is null);
2762 assert(e.msg == "msg");
2766 auto e = new Exception("msg", "hello", 42, new Exception("It's an Exception!"));
2767 assert(e.file == "hello");
2768 assert(e.line == 42);
2769 assert(e.nextInChain !is null);
2770 assert(e.msg == "msg");
2774 auto e = new Exception("message");
2775 assert(e.message == "message");
2781 * The base class of all unrecoverable runtime errors.
2783 * This represents the category of $(D Throwable) objects that are $(B not)
2784 * safe to catch and handle. In principle, one should not catch Error
2785 * objects, as they represent unrecoverable runtime errors.
2786 * Certain runtime guarantees may fail to hold when these errors are
2787 * thrown, making it unsafe to continue execution after catching them.
2789 class Error : Throwable
2792 * Creates a new instance of Error. The nextInChain parameter is used
2793 * internally and should always be $(D null) when passed by user code.
2794 * This constructor does not automatically throw the newly-created
2795 * Error; the $(D throw) statement should be used for that purpose.
2797 @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)
2799 super(msg, nextInChain);
2800 bypassedException = null;
2803 @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)
2805 super(msg, file, line, nextInChain);
2806 bypassedException = null;
2809 /** The first $(D Exception) which was bypassed when this Error was thrown,
2810 or $(D null) if no $(D Exception)s were pending. */
2811 Throwable bypassedException;
2820 throw new Error("msg");
2825 assert(e.msg == "msg");
2833 auto e = new Error("msg");
2834 assert(e.file is null);
2835 assert(e.line == 0);
2836 assert(e.nextInChain is null);
2837 assert(e.msg == "msg");
2838 assert(e.bypassedException is null);
2842 auto e = new Error("msg", new Exception("It's an Exception!"));
2843 assert(e.file is null);
2844 assert(e.line == 0);
2845 assert(e.nextInChain !is null);
2846 assert(e.msg == "msg");
2847 assert(e.bypassedException is null);
2851 auto e = new Error("msg", "hello", 42, new Exception("It's an Exception!"));
2852 assert(e.file == "hello");
2853 assert(e.line == 42);
2854 assert(e.nextInChain !is null);
2855 assert(e.msg == "msg");
2856 assert(e.bypassedException is null);
2862 // from druntime/src/rt/aaA.d
2864 private struct AA { void* impl; }
2865 // size_t _aaLen(in AA aa) pure nothrow @nogc;
2866 private void* _aaGetY(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow;
2867 private void* _aaGetX(scope AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow;
2868 // inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
2869 inout(void[]) _aaValues(inout AA aa, const size_t keysz, const size_t valsz, const TypeInfo tiValueArray) pure nothrow;
2870 inout(void[]) _aaKeys(inout AA aa, const size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
2871 void* _aaRehash(AA* paa, const scope TypeInfo keyti) pure nothrow;
2872 void _aaClear(AA aa) pure nothrow;
2874 // alias _dg_t = extern(D) int delegate(void*);
2875 // int _aaApply(AA aa, size_t keysize, _dg_t dg);
2877 // alias _dg2_t = extern(D) int delegate(void*, void*);
2878 // int _aaApply2(AA aa, size_t keysize, _dg2_t dg);
2880 private struct AARange { AA impl; size_t idx; }
2881 AARange _aaRange(AA aa) pure nothrow @nogc @safe;
2882 bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe;
2883 void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe;
2884 void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe;
2885 void _aaRangePopFront(ref AARange r) pure nothrow @nogc @safe;
2887 int _aaEqual(scope const TypeInfo tiRaw, scope const AA aa1, scope const AA aa2);
2888 hash_t _aaGetHash(scope const AA* aa, scope const TypeInfo tiRaw) nothrow;
2891 _d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code.
2892 This is a typesystem hole, however this is existing hole.
2893 Early compiler didn't check purity of toHash or postblit functions, if key is a UDT thus
2894 copiler allowed to create AA literal with keys, which have impure unsafe toHash methods.
2896 void* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys, void[] values) pure;
2899 void* aaLiteral(Key, Value)(Key[] keys, Value[] values) @trusted pure
2901 return _d_assocarrayliteralTX(typeid(Value[Key]), *cast(void[]*)&keys, *cast(void[]*)&values);
2904 alias AssociativeArray(Key, Value) = Value[Key];
2906 /***********************************
2907 * Removes all remaining keys and values from an associative array.
2909 * aa = The associative array.
2911 void clear(Value, Key)(Value[Key] aa)
2913 _aaClear(*cast(AA *) &aa);
2917 void clear(Value, Key)(Value[Key]* aa)
2919 _aaClear(*cast(AA *) aa);
2925 auto aa = ["k1": 2];
2927 assert("k1" !in aa);
2930 /***********************************
2931 * Reorganizes the associative array in place so that lookups are more
2934 * aa = The associative array.
2936 * The rehashed associative array.
2938 T rehash(T : Value[Key], Value, Key)(T aa)
2940 _aaRehash(cast(AA*)&aa, typeid(Value[Key]));
2945 T rehash(T : Value[Key], Value, Key)(T* aa)
2947 _aaRehash(cast(AA*)aa, typeid(Value[Key]));
2952 T rehash(T : shared Value[Key], Value, Key)(T aa)
2954 _aaRehash(cast(AA*)&aa, typeid(Value[Key]));
2959 T rehash(T : shared Value[Key], Value, Key)(T* aa)
2961 _aaRehash(cast(AA*)aa, typeid(Value[Key]));
2965 /***********************************
2966 * Creates a new associative array of the same size and copies the contents of
2967 * the associative array into it.
2969 * aa = The associative array.
2971 V[K] dup(T : V[K], K, V)(T aa)
2973 //pragma(msg, "K = ", K, ", V = ", V);
2975 // Bug10720 - check whether V is copyable
2976 static assert(is(typeof({ V v = aa[K.init]; })),
2977 "cannot call " ~ T.stringof ~ ".dup because " ~ V.stringof ~ " is not copyable");
2981 //foreach (k, ref v; aa)
2982 // result[k] = v; // Bug13701 - won't work if V is not mutable
2984 ref V duplicateElem(ref K k, ref const V v) @trusted pure nothrow
2986 import core.stdc.string : memcpy;
2988 void* pv = _aaGetY(cast(AA*)&result, typeid(V[K]), V.sizeof, &k);
2989 memcpy(pv, &v, V.sizeof);
2993 foreach (k, ref v; aa)
2995 static if (!__traits(hasPostblit, V))
2996 duplicateElem(k, v);
2997 else static if (__traits(isStaticArray, V))
2998 _doPostblit(duplicateElem(k, v)[]);
2999 else static if (!is(typeof(v.__xpostblit())) && is(immutable V == immutable UV, UV))
3000 (() @trusted => *cast(UV*) &duplicateElem(k, v))().__xpostblit();
3002 duplicateElem(k, v).__xpostblit();
3009 V[K] dup(T : V[K], K, V)(T* aa)
3017 auto aa = ["k1": 2];
3020 assert("k2" !in a2);
3023 // this should never be made public.
3024 private AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe
3026 // ensure we are dealing with a genuine AA.
3027 static if (is(const(V[K]) == const(T)))
3030 const(V[K]) realAA = aa;
3031 return _aaRange(() @trusted { return *cast(AA*)&realAA; } ());
3034 /***********************************
3035 * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3036 * which will iterate over the keys of the associative array. The keys are
3037 * returned by reference.
3039 * If structural changes are made to the array (removing or adding keys), all
3040 * ranges previously obtained through this function are invalidated. The
3041 * following example program will dereference a null pointer:
3044 * import std.stdio : writeln;
3046 * auto dict = ["k1": 1, "k2": 2];
3047 * auto keyRange = dict.byKey;
3049 * writeln(keyRange.front); // Segmentation fault
3053 * aa = The associative array.
3055 * A forward range referencing the keys of the associative array.
3057 auto byKey(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3059 import core.internal.traits : substInout;
3061 static struct Result
3066 @property bool empty() @safe { return _aaRangeEmpty(r); }
3067 @property ref front() @trusted
3069 return *cast(substInout!K*) _aaRangeFrontKey(r);
3071 void popFront() @safe { _aaRangePopFront(r); }
3072 @property Result save() { return this; }
3075 return Result(_aaToRange(aa));
3079 auto byKey(T : V[K], K, V)(T* aa) pure nothrow @nogc
3081 return (*aa).byKey();
3087 auto dict = [1: "v1", 2: "v2"];
3089 foreach (v; dict.byKey)
3095 /***********************************
3096 * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3097 * which will iterate over the values of the associative array. The values are
3098 * returned by reference.
3100 * If structural changes are made to the array (removing or adding keys), all
3101 * ranges previously obtained through this function are invalidated. The
3102 * following example program will dereference a null pointer:
3105 * import std.stdio : writeln;
3107 * auto dict = ["k1": 1, "k2": 2];
3108 * auto valueRange = dict.byValue;
3110 * writeln(valueRange.front); // Segmentation fault
3114 * aa = The associative array.
3116 * A forward range referencing the values of the associative array.
3118 auto byValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3120 import core.internal.traits : substInout;
3122 static struct Result
3127 @property bool empty() @safe { return _aaRangeEmpty(r); }
3128 @property ref front() @trusted
3130 return *cast(substInout!V*) _aaRangeFrontValue(r);
3132 void popFront() @safe { _aaRangePopFront(r); }
3133 @property Result save() { return this; }
3136 return Result(_aaToRange(aa));
3140 auto byValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
3142 return (*aa).byValue();
3148 auto dict = ["k1": 1, "k2": 2];
3150 foreach (v; dict.byValue)
3156 /***********************************
3157 * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
3158 * which will iterate over the key-value pairs of the associative array. The
3159 * returned pairs are represented by an opaque type with `.key` and `.value`
3160 * properties for accessing references to the key and value of the pair,
3163 * If structural changes are made to the array (removing or adding keys), all
3164 * ranges previously obtained through this function are invalidated. The
3165 * following example program will dereference a null pointer:
3168 * import std.stdio : writeln;
3170 * auto dict = ["k1": 1, "k2": 2];
3171 * auto kvRange = dict.byKeyValue;
3173 * writeln(kvRange.front.key, ": ", kvRange.front.value); // Segmentation fault
3176 * Note that this is a low-level interface to iterating over the associative
3177 * array and is not compatible withth the
3178 * $(LINK2 $(ROOT_DIR)phobos/std_typecons.html#.Tuple,`Tuple`) type in Phobos.
3179 * For compatibility with `Tuple`, use
3180 * $(LINK2 $(ROOT_DIR)phobos/std_array.html#.byPair,std.array.byPair) instead.
3183 * aa = The associative array.
3185 * A forward range referencing the pairs of the associative array.
3187 auto byKeyValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
3189 import core.internal.traits : substInout;
3191 static struct Result
3196 @property bool empty() @safe { return _aaRangeEmpty(r); }
3197 @property auto front()
3201 // We save the pointers here so that the Pair we return
3202 // won't mutate when Result.popFront is called afterwards.
3206 @property ref key() inout @trusted
3208 return *cast(substInout!K*) keyp;
3210 @property ref value() inout @trusted
3212 return *cast(substInout!V*) valp;
3215 return Pair(_aaRangeFrontKey(r),
3216 _aaRangeFrontValue(r));
3218 void popFront() @safe { return _aaRangePopFront(r); }
3219 @property Result save() { return this; }
3222 return Result(_aaToRange(aa));
3226 auto byKeyValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
3228 return (*aa).byKeyValue();
3234 auto dict = ["k1": 1, "k2": 2];
3236 foreach (e; dict.byKeyValue)
3238 assert(e.key[1] == e.value + '0');
3245 /***********************************
3246 * Returns a newly allocated dynamic array containing a copy of the keys from
3247 * the associative array.
3249 * aa = The associative array.
3251 * A dynamic array containing a copy of the keys.
3253 Key[] keys(T : Value[Key], Value, Key)(T aa) @property
3255 // ensure we are dealing with a genuine AA.
3256 static if (is(const(Value[Key]) == const(T)))
3259 const(Value[Key]) realAA = aa;
3260 auto res = () @trusted {
3261 auto a = cast(void[])_aaKeys(*cast(inout(AA)*)&realAA, Key.sizeof, typeid(Key[]));
3262 return *cast(Key[]*)&a;
3264 static if (__traits(hasPostblit, Key))
3270 Key[] keys(T : Value[Key], Value, Key)(T *aa) @property
3278 auto aa = [1: "v1", 2: "v2"];
3280 foreach (k; aa.keys)
3291 void[][string] dict;
3296 assert(s.keys.length == 0);
3301 @safe static struct Key
3307 static assert(__traits(compiles, {
3319 this(this) @system {}
3322 static assert(!__traits(compiles, {
3329 /***********************************
3330 * Returns a newly allocated dynamic array containing a copy of the values from
3331 * the associative array.
3333 * aa = The associative array.
3335 * A dynamic array containing a copy of the values.
3337 Value[] values(T : Value[Key], Value, Key)(T aa) @property
3339 // ensure we are dealing with a genuine AA.
3340 static if (is(const(Value[Key]) == const(T)))
3343 const(Value[Key]) realAA = aa;
3344 auto res = () @trusted {
3345 auto a = cast(void[])_aaValues(*cast(inout(AA)*)&realAA, Key.sizeof, Value.sizeof, typeid(Value[]));
3346 return *cast(Value[]*)&a;
3348 static if (__traits(hasPostblit, Value))
3354 Value[] values(T : Value[Key], Value, Key)(T *aa) @property
3356 return (*aa).values;
3362 auto aa = ["k1": 1, "k2": 2];
3364 foreach (e; aa.values)
3375 void[][string] dict;
3380 assert(s.values.length == 0);
3385 @safe static struct Value
3391 static assert(__traits(compiles, {
3393 const _ = aa.values;
3403 this(this) @system {}
3406 static assert(!__traits(compiles, {
3408 const _ = aa.values;
3413 /***********************************
3414 * Looks up key; if it exists returns corresponding value else evaluates and
3415 * returns defaultValue.
3417 * aa = The associative array.
3419 * defaultValue = The default value.
3423 inout(V) get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)
3426 return p ? *p : defaultValue;
3430 inout(V) get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)
3432 return (*aa).get(key, defaultValue);
3438 auto aa = ["k1": 1];
3439 assert(aa.get("k1", 0) == 1);
3440 assert(aa.get("k2", 0) == 0);
3443 /***********************************
3444 * Looks up key; if it exists returns corresponding value else evaluates
3445 * value, adds it to the associative array and returns it.
3447 * aa = The associative array.
3449 * value = The required value.
3453 ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init)
3456 // if key is @safe-ly copyable, `require` can infer @safe
3457 static if (isSafeCopyable!K)
3459 auto p = () @trusted
3461 return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3466 auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3472 *p = value; // Not `return (*p = value)` since if `=` is overloaded
3473 return *p; // this might not return a ref to the left-hand side.
3480 auto aa = ["k1": 1];
3481 assert(aa.require("k1", 0) == 1);
3482 assert(aa.require("k2", 0) == 0);
3483 assert(aa["k2"] == 0);
3486 // Tests whether T can be @safe-ly copied. Use a union to exclude destructor from the test.
3487 private enum bool isSafeCopyable(T) = is(typeof(() @safe { union U { T x; } T *x; auto u = U(*x); }));
3489 /***********************************
3490 * Calls `create` if `key` doesn't exist in the associative array,
3491 * otherwise calls `update`.
3492 * `create` returns a corresponding value for `key`.
3493 * `update` accepts a key parameter. If it returns a value, the value is
3496 * aa = The associative array.
3498 * create = The callable to create a value for `key`.
3500 * update = The callable to call if `key` exists.
3501 * Takes a K argument, returns a V or void.
3503 void update(K, V, C, U)(ref V[K] aa, K key, scope C create, scope U update)
3504 if (is(typeof(create()) : V) && (is(typeof(update(aa[K.init])) : V) || is(typeof(update(aa[K.init])) == void)))
3507 // if key is @safe-ly copyable, `update` may infer @safe
3508 static if (isSafeCopyable!K)
3510 auto p = () @trusted
3512 return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3517 auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
3523 static if (is(typeof(update(*p)) == void))
3538 (int) {} // not executed
3540 assert(aa["key"] == 1);
3542 // update value by ref
3544 () => 0, // not executed
3548 assert(aa["key"] == 2);
3550 // update from return value
3552 () => 0, // not executed
3555 assert(aa["key"] == 4);
3557 // 'update' without changing value
3559 () => 0, // not executed
3561 // do something else
3563 assert(aa["key"] == 4);
3572 this(this) @system {}
3576 bool opEquals(S rhs) { assert(0); }
3577 size_t toHash() { assert(0); }
3581 static assert(is(typeof(() @safe { aai.require("a", 1234); })));
3582 static assert(is(typeof(() @safe { aai.update("a", { return 1234; }, (ref int x) { x++; return x; }); })));
3585 static assert(is(typeof(() { aas.require("a", S(1234)); })));
3586 static assert(is(typeof(() { aas.update("a", { return S(1234); }, (ref S s) { s.x++; return s; }); })));
3587 static assert(!is(typeof(() @safe { aas.update("a", { return S(1234); }, (ref S s) { s.x++; return s; }); })));
3590 static assert(is(typeof(() { aais.require(S(1234), 1234); })));
3591 static assert(is(typeof(() { aais.update(S(1234), { return 1234; }, (ref int x) { x++; return x; }); })));
3592 static assert(!is(typeof(() @safe { aais.require(S(1234), 1234); })));
3593 static assert(!is(typeof(() @safe { aais.update(S(1234), { return 1234; }, (ref int x) { x++; return x; }); })));
3600 int opCall(ref int v)
3613 T opCall(T)(ref T v)
3619 int[string] a = ["2" : 1];
3620 a.update("2", () => -1, S0.init);
3621 assert(a["2"] == 2);
3622 a.update("0", () => -1, S0.init);
3623 assert(a["0"] == -1);
3624 a.update("2", S1.init, S1.init);
3625 assert(a["2"] == 3);
3626 a.update("1", S1.init, S1.init);
3627 assert(a["1"] == -2);
3640 assert(aa["k1"] == 10);
3645 // This lets DDoc produce better documentation.
3648 Calculates the hash value of `arg` with an optional `seed` initial value.
3649 The result might not be equal to `typeid(T).getHash(&arg)`.
3652 arg = argument to calculate the hash value of
3653 seed = optional `seed` value (may be used for hash chaining)
3655 Return: calculated hash value of `arg`
3657 size_t hashOf(T)(auto ref T arg, size_t seed)
3659 static import core.internal.hash;
3660 return core.internal.hash.hashOf(arg, seed);
3663 size_t hashOf(T)(auto ref T arg)
3665 static import core.internal.hash;
3666 return core.internal.hash.hashOf(arg);
3671 auto h1 = "my.string".hashOf;
3672 assert(h1 == "my.string".hashOf);
3677 public import core.internal.hash : hashOf;
3685 size_t myMegaHash() const @safe pure nothrow
3695 size_t toHash() const pure nothrow
3697 size_t hash = a.hashOf();
3698 hash = b.hashOf(hash);
3699 size_t h1 = c.myMegaHash();
3700 hash = h1.hashOf(hash); //Mix two hash values
3706 bool _xopEquals(in void*, in void*)
3708 throw new Error("TypeInfo.equals is not implemented");
3711 bool _xopCmp(in void*, in void*)
3713 throw new Error("TypeInfo.compare is not implemented");
3716 /******************************************
3717 * Create RTInfo for type T
3720 template RTInfoImpl(size_t[] pointerBitmap)
3722 immutable size_t[pointerBitmap.length] RTInfoImpl = pointerBitmap[];
3725 template NoPointersBitmapPayload(size_t N)
3727 enum size_t[N] NoPointersBitmapPayload = 0;
3732 enum pointerBitmap = __traits(getPointerBitmap, T);
3733 static if (pointerBitmap[1 .. $] == NoPointersBitmapPayload!(pointerBitmap.length - 1))
3734 enum RTInfo = rtinfoNoPointers;
3736 enum RTInfo = RTInfoImpl!(pointerBitmap).ptr;
3740 * shortcuts for the precise GC, also generated by the compiler
3741 * used instead of the actual pointer bitmap
3743 enum immutable(void)* rtinfoNoPointers = null;
3744 enum immutable(void)* rtinfoHasPointers = cast(void*)1;
3748 private inout(TypeInfo) getElement(return scope inout TypeInfo value) @trusted pure nothrow
3750 TypeInfo element = cast() value;
3753 if (auto qualified = cast(TypeInfo_Const) element)
3754 element = qualified.base;
3755 else if (auto redefined = cast(TypeInfo_Enum) element)
3756 element = redefined.base;
3757 else if (auto staticArray = cast(TypeInfo_StaticArray) element)
3758 element = staticArray.value;
3759 else if (auto vector = cast(TypeInfo_Vector) element)
3760 element = vector.base;
3764 return cast(inout) element;
3767 private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr, const size_t count) @trusted nothrow
3772 const size_t elementSize = element.tsize;
3776 static bool hasCustomToHash(const scope TypeInfo value) @trusted pure nothrow
3778 const element = getElement(value);
3780 if (const struct_ = cast(const TypeInfo_Struct) element)
3781 return !!struct_.xtoHash;
3783 return cast(const TypeInfo_Array) element
3784 || cast(const TypeInfo_AssociativeArray) element
3785 || cast(const ClassInfo) element
3786 || cast(const TypeInfo_Interface) element;
3789 if (!hasCustomToHash(element))
3790 return hashOf(ptr[0 .. elementSize * count]);
3793 foreach (size_t i; 0 .. count)
3794 hash = hashOf(element.getHash(ptr + i * elementSize), hash);
3798 /// Provide the .dup array property.
3799 @property auto dup(T)(T[] a)
3800 if (!is(const(T) : T))
3802 import core.internal.traits : Unconst;
3803 import core.internal.array.duplication : _dup;
3804 static assert(is(T : Unconst!T), "Cannot implicitly convert type "~T.stringof~
3805 " to "~Unconst!T.stringof~" in dup.");
3807 return _dup!(T, Unconst!T)(a);
3814 auto arr2 = arr.dup;
3816 assert(arr == [0, 2]);
3817 assert(arr2 == [1, 2]);
3821 // const overload to support implicit conversion to immutable (unique result, see DIP29)
3822 @property T[] dup(T)(const(T)[] a)
3823 if (is(const(T) : T))
3825 import core.internal.array.duplication : _dup;
3826 return _dup!(const(T), T)(a);
3830 /// Provide the .idup array property.
3831 @property immutable(T)[] idup(T)(T[] a)
3833 import core.internal.array.duplication : _dup;
3834 static assert(is(T : immutable(T)), "Cannot implicitly convert type "~T.stringof~
3835 " to immutable in idup.");
3836 return _dup!(T, immutable(T))(a);
3840 @property immutable(T)[] idup(T:void)(const(T)[] a)
3848 char[] arr = ['a', 'b', 'c'];
3849 string s = arr.idup;
3854 // HACK: This is a lie. `_d_arraysetcapacity` is neither `nothrow` nor `pure`, but this lie is
3855 // necessary for now to prevent breaking code.
3856 private extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* arrptr) pure nothrow;
3859 (Property) Gets the current _capacity of a slice. The _capacity is the size
3860 that the slice can grow to before the underlying array must be
3861 reallocated or extended.
3863 If an append must reallocate a slice with no possibility of extension, then
3864 `0` is returned. This happens when the slice references a static array, or
3865 if another slice references elements past the end of the current slice.
3867 Note: The _capacity of a slice may be impacted by operations on other slices.
3869 @property size_t capacity(T)(T[] arr) pure nothrow @trusted
3871 return _d_arraysetcapacity(typeid(T[]), 0, cast(void[]*)&arr);
3877 //Static array slice: no capacity
3878 int[4] sarray = [1, 2, 3, 4];
3879 int[] slice = sarray[];
3880 assert(sarray.capacity == 0);
3881 //Appending to slice will reallocate to a new array
3883 assert(slice.capacity >= 5);
3885 //Dynamic array slices
3886 int[] a = [1, 2, 3, 4];
3887 int[] b = a[1 .. $];
3888 int[] c = a[1 .. $ - 1];
3889 debug(SENTINEL) {} else // non-zero capacity very much depends on the array and GC implementation
3891 assert(a.capacity != 0);
3892 assert(a.capacity == b.capacity + 1); //both a and b share the same tail
3894 assert(c.capacity == 0); //an append to c must relocate c.
3898 Reserves capacity for a slice. The capacity is the size
3899 that the slice can grow to before the underlying array must be
3900 reallocated or extended.
3902 Returns: The new capacity of the array (which may be larger than
3903 the requested capacity).
3905 size_t reserve(T)(ref T[] arr, size_t newcapacity) pure nothrow @trusted
3910 return _d_arraysetcapacity(typeid(T[]), newcapacity, cast(void[]*)&arr);
3916 //Static array slice: no capacity. Reserve relocates.
3917 int[4] sarray = [1, 2, 3, 4];
3918 int[] slice = sarray[];
3919 auto u = slice.reserve(8);
3921 assert(&sarray[0] !is &slice[0]);
3922 assert(slice.capacity == u);
3924 //Dynamic array slices
3925 int[] a = [1, 2, 3, 4];
3926 a.reserve(8); //prepare a for appending 4 more items
3930 assert(p == &a[0]); //a should not have been reallocated
3931 assert(u == a.capacity); //a should not have been extended
3934 // https://issues.dlang.org/show_bug.cgi?id=12330, reserve() at CTFE time
3939 auto a = result.reserve = 5;
3946 // Issue 6646: should be possible to use array.reserve from SafeD.
3953 // HACK: This is a lie. `_d_arrayshrinkfit` is not `nothrow`, but this lie is necessary
3954 // for now to prevent breaking code.
3955 private extern (C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow;
3958 Assume that it is safe to append to this array. Appends made to this array
3959 after calling this function may append in place, even if the array was a
3960 slice of a larger array to begin with.
3962 Use this only when it is certain there are no elements in use beyond the
3963 array in the memory block. If there are, those elements will be
3964 overwritten by appending to this array.
3966 Warning: Calling this function, and then using references to data located after the
3967 given array results in undefined behavior.
3970 The input is returned.
3972 auto ref inout(T[]) assumeSafeAppend(T)(auto ref inout(T[]) arr) nothrow @system
3974 _d_arrayshrinkfit(typeid(T[]), *(cast(void[]*)&arr));
3981 int[] a = [1, 2, 3, 4];
3983 // Without assumeSafeAppend. Appending relocates.
3984 int[] b = a [0 .. 3];
3986 assert(a.ptr != b.ptr);
3988 debug(SENTINEL) {} else
3990 // With assumeSafeAppend. Appending overwrites.
3991 int[] c = a [0 .. 3];
3992 c.assumeSafeAppend() ~= 5;
3993 assert(a.ptr == c.ptr);
4000 auto newcap = arr.reserve(2000);
4001 assert(newcap >= 2000);
4002 assert(newcap == arr.capacity);
4004 foreach (i; 0..2000)
4006 assert(ptr == arr.ptr);
4008 arr.assumeSafeAppend();
4010 assert(ptr == arr.ptr);
4015 int[] arr = [1, 2, 3];
4016 void foo(ref int[] i)
4021 foo(assumeSafeAppend(arr)); //pass by ref
4022 assert(arr[]==[1, 2, 5]);
4023 arr = arr[0 .. 1].assumeSafeAppend(); //pass by value
4026 // https://issues.dlang.org/show_bug.cgi?id=10574
4031 auto a2 = &assumeSafeAppend(a);
4032 auto b2 = &assumeSafeAppend(b);
4033 auto a3 = assumeSafeAppend(a[]);
4034 auto b3 = assumeSafeAppend(b[]);
4035 assert(is(typeof(*a2) == int[]));
4036 assert(is(typeof(*b2) == immutable(int[])));
4037 assert(is(typeof(a3) == int[]));
4038 assert(is(typeof(b3) == immutable(int[])));
4041 private void _doPostblit(T)(T[] arr)
4043 // infer static postblit type, run postblit if any
4044 static if (__traits(hasPostblit, T))
4046 static if (__traits(isStaticArray, T) && is(T : E[], E))
4047 _doPostblit(cast(E[]) arr);
4048 else static if (!is(typeof(arr[0].__xpostblit())) && is(immutable T == immutable U, U))
4049 foreach (ref elem; (() @trusted => cast(U[]) arr)())
4052 foreach (ref elem; arr)
4058 Destroys the given object and optionally resets to initial state. It's used to
4059 _destroy an object, calling its destructor or finalizer so it no longer
4060 references any other objects. It does $(I not) initiate a GC cycle or free
4062 If `initialize` is supplied `false`, the object is considered invalid after
4063 destruction, and should not be referenced.
4065 void destroy(bool initialize = true, T)(ref T obj) if (is(T == struct))
4067 import core.internal.destruction : destructRecurse;
4069 destructRecurse(obj);
4071 static if (initialize)
4073 import core.internal.lifetime : emplaceInitializer;
4074 emplaceInitializer(obj); // emplace T.init
4080 struct A { string s = "A"; }
4087 nothrow @safe @nogc unittest
4090 struct A { string s = "A"; }
4094 assert(a.s == "asd");
4099 static int destroyed = 0;
4103 ~this() nothrow @safe @nogc
4113 ~this() nothrow @safe @nogc
4122 assert(destroyed == 2);
4123 assert(a.s == "asd");
4124 assert(a.c.s == "jkl" );
4126 assert(destroyed == 4);
4128 assert(a.c.s == "C" );
4132 private extern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true) nothrow;
4135 void destroy(bool initialize = true, T)(T obj) if (is(T == class))
4137 static if (__traits(getLinkage, T) == "C++")
4139 static if (__traits(hasMember, T, "__xdtor"))
4142 static if (initialize)
4144 const initializer = __traits(initSymbol, T);
4145 (cast(void*)obj)[0 .. initializer.length] = initializer[];
4150 // Bypass overloaded opCast
4151 auto ptr = (() @trusted => *cast(void**) &obj)();
4152 rt_finalize2(ptr, true, initialize);
4157 void destroy(bool initialize = true, T)(T obj) if (is(T == interface))
4159 static assert(__traits(getLinkage, T) == "D", "Invalid call to destroy() on extern(" ~ __traits(getLinkage, T) ~ ") interface");
4161 destroy!initialize(cast(Object)obj);
4164 /// Reference type demonstration
4171 static int dtorCount;
4174 ~this() { dtorCount++; }
4177 static int dtorCount;
4181 ~this() { dtorCount++; }
4185 assert(c.dtorCount == 0); // destructor not yet called
4186 assert(c.s == "S"); // initial state `c.s` is `"S"`
4187 assert(c.a.dtorCount == 0); // destructor not yet called
4188 assert(c.a.x == 10); // initial state `c.a.x` is `10`
4191 assert(c.s == "T"); // `c.s` is `"T"`
4193 assert(c.dtorCount == 1); // `c`'s destructor was called
4194 assert(c.s == "S"); // `c.s` is back to its inital state, `"S"`
4195 assert(c.a.dtorCount == 1); // `c.a`'s destructor was called
4196 assert(c.a.x == 10); // `c.a.x` is back to its inital state, `10`
4198 // check C++ classes work too!
4199 extern (C++) class CPP
4203 __gshared int dtorCount;
4206 ~this() { dtorCount++; }
4209 __gshared int dtorCount;
4213 ~this() { dtorCount++; }
4216 CPP cpp = new CPP();
4217 assert(cpp.dtorCount == 0); // destructor not yet called
4218 assert(cpp.s == "S"); // initial state `cpp.s` is `"S"`
4219 assert(cpp.a.dtorCount == 0); // destructor not yet called
4220 assert(cpp.a.x == 10); // initial state `cpp.a.x` is `10`
4223 assert(cpp.s == "T"); // `cpp.s` is `"T"`
4224 destroy!false(cpp); // destroy without initialization
4225 assert(cpp.dtorCount == 1); // `cpp`'s destructor was called
4226 assert(cpp.s == "T"); // `cpp.s` is not initialized
4227 assert(cpp.a.dtorCount == 1); // `cpp.a`'s destructor was called
4228 assert(cpp.a.x == 30); // `cpp.a.x` is not initialized
4230 assert(cpp.dtorCount == 2); // `cpp`'s destructor was called again
4231 assert(cpp.s == "S"); // `cpp.s` is back to its inital state, `"S"`
4232 assert(cpp.a.dtorCount == 2); // `cpp.a`'s destructor was called again
4233 assert(cpp.a.x == 10); // `cpp.a.x` is back to its inital state, `10`
4236 /// Value type demonstration
4240 assert(i == 0); // `i`'s initial state is `0`
4242 assert(i == 1); // `i` changed to `1`
4244 assert(i == 1); // `i` was not initialized
4246 assert(i == 0); // `i` is back to its initial state `0`
4258 destroy!false(new C());
4259 destroy!true(new C());
4266 class A: I { string s = "A"; this() {} }
4267 auto a = new A, b = new A;
4277 static bool destroyed = false;
4287 auto a = new B, b = new B;
4299 // this test is invalid now that the default ctor is not run after clearing
4317 nothrow @safe @nogc unittest
4320 struct A { string s = "A"; }
4324 assert(a.s == "asd");
4329 static int destroyed = 0;
4333 ~this() nothrow @safe @nogc
4343 ~this() nothrow @safe @nogc
4352 assert(destroyed == 2);
4353 assert(a.s == "asd");
4354 assert(a.c.s == "jkl" );
4356 assert(destroyed == 4);
4358 assert(a.c.s == "C" );
4364 // Bugzilla 20049: Test to ensure proper behavior of `nothrow` destructors
4367 static int dtorCount = 0;
4369 ~this() nothrow { dtorCount++; }
4374 assert(C.dtorCount == 1);
4377 // https://issues.dlang.org/show_bug.cgi?id=22832
4383 A opCast(T : A)() { return A(); }
4389 // make sure destroy!false skips re-initialization
4392 static struct S { int x; }
4393 static class C { int x; }
4394 static extern(C++) class Cpp { int x; }
4396 static void test(T)(T inst)
4399 destroy!false(inst);
4400 assert(inst.x == 123, T.stringof);
4409 void destroy(bool initialize = true, T)(ref T obj)
4410 if (__traits(isStaticArray, T))
4412 foreach_reverse (ref e; obj[])
4413 destroy!initialize(e);
4422 assert(a == [ 1, 2 ]);
4424 assert(a == [ 0, 0 ]);
4429 static struct vec2f {
4435 destroy!(true, vec2f)(v);
4445 this(int x) { op ~= "C" ~ cast(char)('0'+x); this.x = x; }
4446 this(this) { op ~= "P" ~ cast(char)('0'+x); }
4447 ~this() { op ~= "D" ~ cast(char)('0'+x); }
4451 S[2] a1 = [S(1), S(2)];
4454 assert(op == "D2D1"); // built-in scope destruction
4456 S[2] a1 = [S(1), S(2)];
4459 assert(op == "D2D1"); // consistent with built-in behavior
4463 S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];
4466 assert(op == "D4D3D2D1");
4468 S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];
4471 assert(op == "D4D3D2D1", op);
4476 void destroy(bool initialize = true, T)(ref T obj)
4477 if (!is(T == struct) && !is(T == interface) && !is(T == class) && !__traits(isStaticArray, T))
4479 static if (initialize)
4497 assert(a != a); // isnan
4504 static struct HasDtor
4506 ~this() { assert(0); }
4515 assert(o.ptr is null);
4516 destroy(o); // must not reach in HasDtor.__dtor()
4519 /* ************************************************************************
4521 The compiler lowers certain expressions to instantiations of the following
4522 templates. They must be implicitly imported, which is why they are here
4523 in this file. They must also be `public` as they must be visible from the
4524 scope in which they are instantiated. They are explicitly undocumented as
4525 they are only intended to be instantiated by the compiler, not the user.
4526 **************************************************************************/
4528 public import core.internal.entrypoint : _d_cmain;
4530 public import core.internal.array.appending : _d_arrayappendT;
4531 version (D_ProfileGC)
4532 public import core.internal.array.appending : _d_arrayappendTTrace;
4533 public import core.internal.array.appending : _d_arrayappendcTXImpl;
4534 public import core.internal.array.comparison : __cmp;
4535 public import core.internal.array.equality : __equals;
4536 public import core.internal.array.casting: __ArrayCast;
4537 public import core.internal.array.concatenation : _d_arraycatnTXImpl;
4538 public import core.internal.array.construction : _d_arrayctor;
4539 public import core.internal.array.construction : _d_arraysetctor;
4540 public import core.internal.array.arrayassign : _d_arrayassign_l;
4541 public import core.internal.array.arrayassign : _d_arrayassign_r;
4542 public import core.internal.array.arrayassign : _d_arraysetassign;
4543 public import core.internal.array.capacity: _d_arraysetlengthTImpl;
4545 public import core.internal.dassert: _d_assert_fail;
4547 public import core.internal.destruction: __ArrayDtor;
4549 public import core.internal.moving: __move_post_blt;
4551 public import core.internal.postblit: __ArrayPostblit;
4553 public import core.internal.switch_: __switch;
4554 public import core.internal.switch_: __switch_error;
4556 public import core.lifetime : _d_delstructImpl;
4557 public import core.lifetime : _d_newThrowable;
4558 public import core.lifetime : _d_newclassT;
4559 public import core.lifetime : _d_newclassTTrace;
4561 public @trusted @nogc nothrow pure extern (C) void _d_delThrowable(scope Throwable);
4563 // Compare class and interface objects for ordering.
4564 int __cmp(C1, C2)(C1 lhs, C2 rhs)
4565 if ((is(C1 : const(Object)) || (is(C1 == interface) && (__traits(getLinkage, C1) == "D"))) &&
4566 (is(C2 : const(Object)) || (is(C2 == interface) && (__traits(getLinkage, C2) == "D"))))
4568 static if (is(C1 == typeof(null)) && is(C2 == typeof(null)))
4572 else static if (is(C1 == typeof(null)))
4574 // Regard null references as always being "less than"
4577 else static if (is(C2 == typeof(null)))
4589 return lhs.opCmp(rhs);
4599 this(int i) { this.i = i; }
4601 override int opCmp(Object c) const @safe
4603 return i - (cast(C)c).i;
4609 assert(__cmp(c1, null) > 0);
4610 assert(__cmp(null, c1) < 0);
4611 assert(__cmp(c1, c1) == 0);
4612 assert(__cmp(c1, c2) < 0);
4613 assert(__cmp(c2, c1) > 0);
4615 assert(__cmp([c1, c1][], [c2, c2][]) < 0);
4616 assert(__cmp([c2, c2], [c1, c1]) > 0);
4625 this(ubyte i) { this.i = i; }
4631 assert(__cmp([c1, c1][], [c2, c2][]) < 0);
4632 assert(__cmp([c2, c2], [c1, c1]) > 0);
4633 assert(__cmp([c2, c2], [c2, c1]) > 0);
4642 assert(a < "helloo");
4643 assert(a <= "helloo");
4644 assert(a > "betty");
4645 assert(a >= "betty");
4646 assert(a == "hello");
4647 assert(a <= "hello");
4648 assert(a >= "hello");
4652 // Used in Exception Handling LSDA tables to 'wrap' C++ type info
4653 // so it can be distinguished from D TypeInfo
4654 class __cpp_type_info_ptr
4656 void* ptr; // opaque pointer to C++ RTTI type info
4659 // Compiler hook into the runtime implementation of array (vector) operations.
4660 template _arrayOp(Args...)
4662 import core.internal.array.operations;
4663 alias _arrayOp = arrayOp!Args;
4666 public import core.builtins : __ctfeWrite;
4670 Provides an "inline import", i.e. an `import` that is only available for a
4671 limited lookup. For example:
4674 void fun(imported!"std.stdio".File input)
4676 ... use File from std.stdio normally ...
4680 There is no need to import `std.stdio` at top level, so `fun` carries its own
4681 dependencies. The same approach can be used for template constraints:
4684 void fun(T)(imported!"std.stdio".File input, T value)
4685 if (imported!"std.traits".isIntegral!T)
4691 An inline import may be used in conjunction with the `with` statement as well.
4692 Inside the scope controlled by `with`, all symbols in the imported module are
4698 with (imported!"std.datetime")
4699 with (imported!"std.stdio")
4701 Clock.currTime.writeln;
4706 The advantages of inline imports over top-level uses of the `import` declaration
4710 $(LI The `imported` template specifies dependencies at declaration level, not at
4711 module level. This allows reasoning about the dependency cost of declarations in
4712 separation instead of aggregated at module level.)
4713 $(LI Declarations using `imported` are easier to move around because they don't
4714 require top-level context, making for simpler and quicker refactorings.)
4715 $(LI Declarations using `imported` scale better with templates. This is because
4716 templates that are not instantiated do not have their parameters and constraints
4717 instantiated, so additional modules are not imported without necessity. This
4718 makes the cost of unused templates negligible. Dependencies are pulled on a need
4719 basis depending on the declarations used by client code.)
4722 The use of `imported` also has drawbacks:
4725 $(LI If most declarations in a module need the same imports, then factoring them
4726 at top level, outside the declarations, is simpler than repeating them.)
4727 $(LI Traditional dependency-tracking tools such as make and other build systems
4728 assume file-level dependencies and need special tooling (such as rdmd) in order
4729 to work efficiently.)
4730 $(LI Dependencies at the top of a module are easier to inspect quickly than
4731 dependencies spread throughout the module.)
4734 See_Also: The $(HTTP forum.dlang.org/post/tzqzmqhankrkbrfsrmbo@forum.dlang.org,
4735 forum discussion) that led to the creation of the `imported` facility. Credit is
4736 due to Daniel Nielsen and Dominikus Dittes Scherkl.
4739 template imported(string moduleName)
4741 mixin("import imported = " ~ moduleName ~ ";");