Modular handling of externals
[delight/core.git] / phobos2 / internal / object.d
blob75e8fa01af17dfedda4a9e79bbe5e0c3e1463a86
2 /**
3 * Part of the D programming language runtime library.
4 * Forms the symbols available to all D programs. Includes
5 * Object, which is the root of the class object hierarchy.
7 * This module is implicitly imported.
8 * Macros:
9 * WIKI = Phobos/Object
13 * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
14 * Written by Walter Bright
16 * This software is provided 'as-is', without any express or implied
17 * warranty. In no event will the authors be held liable for any damages
18 * arising from the use of this software.
20 * Permission is granted to anyone to use this software for any purpose,
21 * including commercial applications, and to alter it and redistribute it
22 * freely, in both source and binary form, subject to the following
23 * restrictions:
25 * o The origin of this software must not be misrepresented; you must not
26 * claim that you wrote the original software. If you use this software
27 * in a product, an acknowledgment in the product documentation would be
28 * appreciated but is not required.
29 * o Altered source versions must be plainly marked as such, and must not
30 * be misrepresented as being the original software.
31 * o This notice may not be removed or altered from any source
32 * distribution.
35 /* NOTE: This file has been patched from the original DMD distribution to
36 work with the GDC compiler.
38 Modified by David Friedman, April 2005
42 module object;
44 import std.outofmemory;
46 /// Standard boolean type.
47 alias bool bit;
49 /**
50 * An unsigned integral type large enough to span the memory space. Use for
51 * array indices and pointer offsets for maximal portability to
52 * architectures that have different memory address ranges. This is
53 * analogous to C's size_t.
55 alias typeof(int.sizeof) size_t;
57 /**
58 * A signed integral type large enough to span the memory space. Use for
59 * pointer differences and for size_t differences for maximal portability to
60 * architectures that have different memory address ranges. This is
61 * analogous to C's ptrdiff_t.
63 alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
65 alias size_t hash_t;
67 alias invariant(char)[] string;
68 alias invariant(wchar)[] wstring;
69 alias invariant(dchar)[] dstring;
71 extern (C)
72 { /// C's printf function.
73 int printf(const char *, ...);
74 void trace_term();
76 int memcmp(in void *, in void *, size_t);
77 void* memcpy(void *, in void *, size_t);
78 void* calloc(size_t, size_t);
79 void* realloc(void*, size_t);
80 void free(void*);
82 Object _d_newclass(ClassInfo ci);
85 /* *************************
86 * Internal struct pointed to by the hidden .monitor member.
88 struct Monitor
90 void delegate(Object)[] delegates;
92 /* More stuff goes here defined by internal/monitor.c */
95 /******************
96 * All D class objects inherit from Object.
98 class Object
100 void print()
102 string s = toString();
103 printf("%.*s\n", cast(int) s.length, s.ptr);
107 * Convert Object to a human readable string.
109 string toString()
111 return this.classinfo.name;
115 * Compute hash function for Object.
117 hash_t toHash()
119 // BUG: this prevents a compacting GC from working, needs to be fixed
120 return cast(size_t)cast(void *)this;
124 * Compare with another Object obj.
125 * Returns:
126 * $(TABLE
127 * $(TR $(TD this < obj) $(TD < 0))
128 * $(TR $(TD this == obj) $(TD 0))
129 * $(TR $(TD this > obj) $(TD > 0))
132 int opCmp(Object o)
134 // BUG: this prevents a compacting GC from working, needs to be fixed
135 //return cast(int)cast(void *)this - cast(int)cast(void *)o;
137 throw new Error(cast(string) ("need opCmp for class "
138 ~ this.classinfo.name));
142 * Returns !=0 if this object does have the same contents as obj.
144 int opEquals(Object o)
146 return cast(int)(this is o);
149 /* **
150 * Call delegate dg, passing this to it, when this object gets destroyed.
151 * Use extreme caution, as the list of delegates is stored in a place
152 * not known to the gc. Thus, if any objects pointed to by one of these
153 * delegates gets freed by the gc, calling the delegate will cause a
154 * crash.
155 * This is only for use by library developers, as it will need to be
156 * redone if weak pointers are added or a moving gc is developed.
158 final void notifyRegister(void delegate(Object) dg)
160 //printf("notifyRegister(dg = %llx, o = %p)\n", dg, this);
161 synchronized (this)
163 Monitor* m = cast(Monitor*)(cast(void**)this)[1];
164 foreach (inout x; m.delegates)
166 if (!x || x == dg)
167 { x = dg;
168 return;
172 // Increase size of delegates[]
173 auto len = m.delegates.length;
174 auto startlen = len;
175 if (len == 0)
177 len = 4;
178 auto p = calloc((void delegate(Object)).sizeof, len);
179 if (!p)
180 _d_OutOfMemory();
181 m.delegates = (cast(void delegate(Object)*)p)[0 .. len];
183 else
185 len += len + 4;
186 auto p = realloc(m.delegates.ptr, (void delegate(Object)).sizeof * len);
187 if (!p)
188 _d_OutOfMemory();
189 m.delegates = (cast(void delegate(Object)*)p)[0 .. len];
190 m.delegates[startlen .. len] = null;
192 m.delegates[startlen] = dg;
196 /* **
197 * Remove delegate dg from the notify list.
198 * This is only for use by library developers, as it will need to be
199 * redone if weak pointers are added or a moving gc is developed.
201 final void notifyUnRegister(void delegate(Object) dg)
203 synchronized (this)
205 Monitor* m = cast(Monitor*)(cast(void**)this)[1];
206 foreach (inout x; m.delegates)
208 if (x == dg)
209 x = null;
214 /******
215 * Create instance of class specified by classname.
216 * The class must either have no constructors or have
217 * a default constructor.
218 * Returns:
219 * null if failed
221 static Object factory(string classname)
223 auto ci = ClassInfo.find(classname);
224 if (ci)
226 return ci.create();
228 return null;
232 extern (C) void _d_notify_release(Object o)
234 //printf("_d_notify_release(o = %p)\n", o);
235 Monitor* m = cast(Monitor*)(cast(void**)o)[1];
236 if (m.delegates.length)
238 auto dgs = m.delegates;
239 synchronized (o)
241 dgs = m.delegates;
242 m.delegates = null;
245 foreach (dg; dgs)
247 if (dg)
248 { //printf("calling dg = %llx (%p)\n", dg, o);
249 dg(o);
253 free(dgs.ptr);
259 * Information about an interface.
260 * When an object is accessed via an interface, an Interface* appears as the
261 * first entry in its vtbl.
263 struct Interface
265 ClassInfo classinfo; /// .classinfo for this interface (not for containing class)
266 void *[] vtbl;
267 ptrdiff_t offset; /// offset to Interface 'this' from Object 'this'
270 import std.moduleinit;
272 * Runtime type information about a class. Can be retrieved for any class type
273 * or instance by using the .classinfo property.
274 * A pointer to this appears as the first entry in the class's vtbl[].
276 class ClassInfo : Object
278 byte[] init; /** class static initializer
279 * (init.length gives size in bytes of class)
281 string name; /// class name
282 void *[] vtbl; /// virtual function pointer table
283 Interface[] interfaces; /// interfaces this class implements
284 ClassInfo base; /// base class
285 void *destructor;
286 void (*classInvariant)(Object);
287 uint flags;
288 // 1: // is IUnknown or is derived from IUnknown
289 // 2: // has no possible pointers into GC memory
290 // 4: // has offTi[] member
291 // 8: // has constructors
292 // 16: // has xgetMembers member
293 void *deallocator;
294 OffsetTypeInfo[] offTi;
295 void function(Object) defaultConstructor; // default Constructor
296 const(MemberInfo[]) function(string) xgetMembers;
298 /*************
299 * Search all modules for ClassInfo corresponding to classname.
300 * Returns: null if not found
302 static ClassInfo find(string classname)
304 foreach (m; ModuleInfo.modules())
306 //writefln("module %s, %d", m.name, m.localClasses.length);
307 foreach (c; m.localClasses)
309 //writefln("\tclass %s", c.name);
310 if (c.name == classname)
311 return c;
314 return null;
317 /********************
318 * Create instance of Object represented by 'this'.
319 * Returns:
320 * the object created, or null if the Object does
321 * does not have a default constructor
323 Object create()
325 if (flags & 8 && !defaultConstructor)
326 return null;
327 Object o = _d_newclass(this);
328 if (flags & 8 && defaultConstructor)
330 defaultConstructor(o);
332 return o;
335 /*************************
336 * Search for all members with the name 'name'.
337 * If name[] is null, return all members.
339 const(MemberInfo[]) getMembers(string name)
341 if (flags & 16 && xgetMembers)
343 return xgetMembers(name);
345 return null;
349 /* ========================================================================== */
351 private import std.string;
354 * Array of pairs giving the offset and type information for each
355 * member in an aggregate.
357 struct OffsetTypeInfo
359 size_t offset; /// Offset of member from start of object
360 TypeInfo ti; /// TypeInfo for this member
365 * Runtime type information about a type.
366 * Can be retrieved for any type using a
367 * <a href="../expression.html#typeidexpression">TypeidExpression</a>.
369 class TypeInfo
371 override hash_t toHash()
372 { hash_t hash;
374 foreach (char c; this.toString())
375 hash = hash * 9 + c;
376 return hash;
379 override int opCmp(Object o)
381 if (this is o)
382 return 0;
383 TypeInfo ti = cast(TypeInfo)o;
384 if (ti is null)
385 return 1;
386 return std.string.cmp(this.toString(), ti.toString());
389 override int opEquals(Object o)
391 /* TypeInfo instances are singletons, but duplicates can exist
392 * across DLL's. Therefore, comparing for a name match is
393 * sufficient.
395 if (this is o)
396 return 1;
397 TypeInfo ti = cast(TypeInfo)o;
398 return cast(int)(ti && this.toString() == ti.toString());
401 /// Returns a hash of the instance of a type.
402 hash_t getHash(in void *p) { return cast(size_t)p; }
404 /// Compares two instances for equality.
405 int equals(in void *p1, in void *p2) { return cast(int)(p1 == p2); }
407 /// Compares two instances for &lt;, ==, or &gt;.
408 int compare(in void *p1, in void *p2) { return 0; }
410 /// Returns size of the type.
411 size_t tsize() { return 0; }
413 /// Swaps two instances of the type.
414 void swap(void *p1, void *p2)
416 size_t n = tsize();
417 for (size_t i = 0; i < n; i++)
418 { byte t;
420 t = (cast(byte *)p1)[i];
421 (cast(byte *)p1)[i] = (cast(byte *)p2)[i];
422 (cast(byte *)p2)[i] = t;
426 /// Get TypeInfo for 'next' type, as defined by what kind of type this is,
427 /// null if none.
428 TypeInfo next() { return null; }
430 /// Return default initializer, null if default initialize to 0
431 void[] init() { return null; }
433 /// Get flags for type: 1 means GC should scan for pointers
434 uint flags() { return 0; }
436 /// Get type information on the contents of the type; null if not available
437 OffsetTypeInfo[] offTi() { return null; }
439 /// Run the destructor on the object and all its sub-objects
440 void destroy(void *p) { }
442 /// Run the postblit on the object and all its sub-objects
443 void postblit(void *p) { }
446 class TypeInfo_Typedef : TypeInfo
448 override string toString() { return name; }
450 override int opEquals(Object o)
451 { TypeInfo_Typedef c;
453 return cast(int)
454 (this is o ||
455 ((c = cast(TypeInfo_Typedef)o) !is null &&
456 this.name == c.name &&
457 this.base == c.base));
460 override hash_t getHash(in void *p) { return base.getHash(p); }
461 override int equals(in void *p1, in void *p2) { return base.equals(p1, p2); }
462 override int compare(in void *p1, in void *p2) { return base.compare(p1, p2); }
463 override size_t tsize() { return base.tsize(); }
464 override void swap(void *p1, void *p2) { return base.swap(p1, p2); }
466 override TypeInfo next() { return base.next(); }
467 override uint flags() { return base.flags(); }
468 override void[] init() { return m_init.length ? m_init : base.init(); }
470 override void destroy(void *p) { base.destroy(p); }
471 override void postblit(void *p) { base.postblit(p); }
473 TypeInfo base;
474 string name;
475 void[] m_init;
478 class TypeInfo_Enum : TypeInfo_Typedef
482 class TypeInfo_Pointer : TypeInfo
484 override string toString() { return cast(string) (m_next.toString() ~ "*"); }
486 override int opEquals(Object o)
487 { TypeInfo_Pointer c;
489 return this is o ||
490 ((c = cast(TypeInfo_Pointer)o) !is null &&
491 this.m_next == c.m_next);
494 override hash_t getHash(in void *p)
496 return cast(size_t)*cast(void* *)p;
499 override int equals(in void *p1, in void *p2)
501 return cast(int)(*cast(void* *)p1 == *cast(void* *)p2);
504 override int compare(in void *p1, in void *p2)
506 if (*cast(void* *)p1 < *cast(void* *)p2)
507 return -1;
508 else if (*cast(void* *)p1 > *cast(void* *)p2)
509 return 1;
510 else
511 return 0;
514 override size_t tsize()
516 return (void*).sizeof;
519 override void swap(void *p1, void *p2)
520 { void* tmp;
521 tmp = *cast(void**)p1;
522 *cast(void**)p1 = *cast(void**)p2;
523 *cast(void**)p2 = tmp;
526 override TypeInfo next() { return m_next; }
527 override uint flags() { return 1; }
529 TypeInfo m_next;
532 class TypeInfo_Array : TypeInfo
534 override string toString() { return cast(string) (value.toString() ~ "[]"); }
536 override int opEquals(Object o)
537 { TypeInfo_Array c;
539 return cast(int)
540 (this is o ||
541 ((c = cast(TypeInfo_Array)o) !is null &&
542 this.value == c.value));
545 override hash_t getHash(in void *p)
546 { size_t sz = value.tsize();
547 hash_t hash = 0;
548 void[] a = *cast(void[]*)p;
549 for (size_t i = 0; i < a.length; i++)
550 hash += value.getHash(a.ptr + i * sz);
551 return hash;
554 override int equals(in void *p1, in void *p2)
556 void[] a1 = *cast(void[]*)p1;
557 void[] a2 = *cast(void[]*)p2;
558 if (a1.length != a2.length)
559 return 0;
560 size_t sz = value.tsize();
561 for (size_t i = 0; i < a1.length; i++)
563 if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))
564 return 0;
566 return 1;
569 override int compare(in void *p1, in void *p2)
571 void[] a1 = *cast(void[]*)p1;
572 void[] a2 = *cast(void[]*)p2;
573 size_t sz = value.tsize();
574 size_t len = a1.length;
576 if (a2.length < len)
577 len = a2.length;
578 for (size_t u = 0; u < len; u++)
580 int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
581 if (result)
582 return result;
584 return cast(int)a1.length - cast(int)a2.length;
587 override size_t tsize()
589 return (void[]).sizeof;
592 override void swap(void *p1, void *p2)
593 { void[] tmp;
594 tmp = *cast(void[]*)p1;
595 *cast(void[]*)p1 = *cast(void[]*)p2;
596 *cast(void[]*)p2 = tmp;
599 TypeInfo value;
601 override TypeInfo next()
603 return value;
606 override uint flags() { return 1; }
609 class TypeInfo_StaticArray : TypeInfo
611 override string toString()
613 return cast(string)
614 (value.toString() ~ "[" ~ std.string.toString(len) ~ "]");
617 override int opEquals(Object o)
618 { TypeInfo_StaticArray c;
620 return cast(int)
621 (this is o ||
622 ((c = cast(TypeInfo_StaticArray)o) !is null &&
623 this.len == c.len &&
624 this.value == c.value));
627 override hash_t getHash(in void *p)
628 { size_t sz = value.tsize();
629 hash_t hash = 0;
630 for (size_t i = 0; i < len; i++)
631 hash += value.getHash(p + i * sz);
632 return hash;
635 override int equals(in void *p1, in void *p2)
637 size_t sz = value.tsize();
639 for (size_t u = 0; u < len; u++)
641 if (!value.equals(p1 + u * sz, p2 + u * sz))
642 return 0;
644 return 1;
647 override int compare(in void *p1, in void *p2)
649 size_t sz = value.tsize();
651 for (size_t u = 0; u < len; u++)
653 int result = value.compare(p1 + u * sz, p2 + u * sz);
654 if (result)
655 return result;
657 return 0;
660 override size_t tsize()
662 return len * value.tsize();
665 override void swap(void *p1, void *p2)
666 { void* tmp;
667 size_t sz = value.tsize();
668 ubyte[16] buffer;
669 void* pbuffer;
671 if (sz < buffer.sizeof)
672 tmp = buffer.ptr;
673 else
674 tmp = pbuffer = (new void[sz]).ptr;
676 for (size_t u = 0; u < len; u += sz)
677 { size_t o = u * sz;
678 memcpy(tmp, p1 + o, sz);
679 memcpy(p1 + o, p2 + o, sz);
680 memcpy(p2 + o, tmp, sz);
682 if (pbuffer)
683 delete pbuffer;
686 override void[] init() { return value.init(); }
687 override TypeInfo next() { return value; }
688 override uint flags() { return value.flags(); }
690 override void destroy(void *p)
692 auto sz = value.tsize();
693 p += sz * len;
694 foreach (i; 0 .. len)
696 p -= sz;
697 value.destroy(p);
701 override void postblit(void *p)
703 auto sz = value.tsize();
704 foreach (i; 0 .. len)
706 value.postblit(p);
707 p += sz;
711 TypeInfo value;
712 size_t len;
715 class TypeInfo_AssociativeArray : TypeInfo
717 override string toString()
719 return cast(string) (value.toString() ~ "[" ~ key.toString() ~ "]");
722 override int opEquals(Object o)
723 { TypeInfo_AssociativeArray c;
725 return this is o ||
726 ((c = cast(TypeInfo_AssociativeArray)o) !is null &&
727 this.key == c.key &&
728 this.value == c.value);
731 // BUG: need to add the rest of the functions
733 override size_t tsize()
735 return (char[int]).sizeof;
738 override TypeInfo next() { return value; }
739 override uint flags() { return 1; }
741 TypeInfo value;
742 TypeInfo key;
745 class TypeInfo_Function : TypeInfo
747 override string toString()
749 return cast(string) (next.toString() ~ "()");
752 override int opEquals(Object o)
753 { TypeInfo_Function c;
755 return this is o ||
756 ((c = cast(TypeInfo_Function)o) !is null &&
757 this.next == c.next);
760 // BUG: need to add the rest of the functions
762 override size_t tsize()
764 return 0; // no size for functions
767 TypeInfo next; // function return type
770 class TypeInfo_Delegate : TypeInfo
772 override string toString()
774 return cast(string) (next.toString() ~ " delegate()");
777 override int opEquals(Object o)
778 { TypeInfo_Delegate c;
780 return this is o ||
781 ((c = cast(TypeInfo_Delegate)o) !is null &&
782 this.next == c.next);
785 // BUG: need to add the rest of the functions
787 override size_t tsize()
788 { alias int delegate() dg;
789 return dg.sizeof;
792 override uint flags() { return 1; }
794 TypeInfo next; // delegate return type
797 class TypeInfo_Class : TypeInfo
799 override string toString() { return info.name; }
801 override int opEquals(Object o)
802 { TypeInfo_Class c;
804 return this is o ||
805 ((c = cast(TypeInfo_Class)o) !is null &&
806 this.info.name == c.classinfo.name);
809 override hash_t getHash(in void *p)
811 Object o = *cast(Object*)p;
812 return o ? o.toHash() : 0;
815 override int equals(in void *p1, in void *p2)
817 Object o1 = *cast(Object*)p1;
818 Object o2 = *cast(Object*)p2;
820 return (o1 is o2) || (o1 && o1.opEquals(o2));
823 override int compare(in void *p1, in void *p2)
825 Object o1 = *cast(Object*)p1;
826 Object o2 = *cast(Object*)p2;
827 int c = 0;
829 // Regard null references as always being "less than"
830 if (o1 !is o2)
832 if (o1)
833 { if (!o2)
834 c = 1;
835 else
836 c = o1.opCmp(o2);
838 else
839 c = -1;
841 return c;
844 override size_t tsize()
846 return Object.sizeof;
849 override uint flags() { return 1; }
851 override OffsetTypeInfo[] offTi()
853 return (info.flags & 4) ? info.offTi : null;
856 ClassInfo info;
859 class TypeInfo_Interface : TypeInfo
861 override string toString() { return info.name; }
863 override int opEquals(Object o)
864 { TypeInfo_Interface c;
866 return this is o ||
867 ((c = cast(TypeInfo_Interface)o) !is null &&
868 this.info.name == c.classinfo.name);
871 override hash_t getHash(in void *p)
873 Interface* pi = **cast(Interface ***)*cast(void**)p;
874 Object o = cast(Object)(*cast(void**)p - pi.offset);
875 assert(o);
876 return o.toHash();
879 override int equals(in void *p1, in void *p2)
881 Interface* pi = **cast(Interface ***)*cast(void**)p1;
882 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
883 pi = **cast(Interface ***)*cast(void**)p2;
884 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
886 return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
889 override int compare(in void *p1, in void *p2)
891 Interface* pi = **cast(Interface ***)*cast(void**)p1;
892 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
893 pi = **cast(Interface ***)*cast(void**)p2;
894 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
895 int c = 0;
897 // Regard null references as always being "less than"
898 if (o1 != o2)
900 if (o1)
901 { if (!o2)
902 c = 1;
903 else
904 c = o1.opCmp(o2);
906 else
907 c = -1;
909 return c;
912 override size_t tsize()
914 return Object.sizeof;
917 override uint flags() { return 1; }
919 ClassInfo info;
922 class TypeInfo_Struct : TypeInfo
924 override string toString() { return name; }
926 override int opEquals(Object o)
927 { TypeInfo_Struct s;
929 return this is o ||
930 ((s = cast(TypeInfo_Struct)o) !is null &&
931 this.name == s.name &&
932 this.init.length == s.init.length);
935 override hash_t getHash(in void *p)
936 { hash_t h;
938 assert(p);
939 if (xtoHash)
940 { //printf("getHash() using xtoHash\n");
941 h = (*xtoHash)(p);
943 else
945 //printf("getHash() using default hash\n");
946 // A sorry hash algorithm.
947 // Should use the one for strings.
948 // BUG: relies on the GC not moving objects
949 auto q = cast(const(ubyte)*)p;
950 for (size_t i = 0; i < init.length; i++)
951 { h = h * 9 + *q;
952 q++;
955 return h;
958 override int equals(in void *p2, in void *p1)
959 { int c;
961 if (p1 == p2)
962 c = 1;
963 else if (!p1 || !p2)
964 c = 0;
965 else if (xopEquals)
967 version (GNU)
968 // GDC and DMD use different calling conventions
969 c = (*xopEquals)(p2, p1);
970 else
971 c = (*xopEquals)(p1, p2);
973 else
974 // BUG: relies on the GC not moving objects
975 c = (memcmp(p1, p2, init.length) == 0);
976 return c;
979 override int compare(in void *p2, in void *p1)
981 int c = 0;
983 // Regard null references as always being "less than"
984 if (p1 != p2)
986 if (p1)
987 { if (!p2)
988 c = 1;
989 else if (xopCmp)
991 version (GNU)
992 // GDC and DMD use different calling conventions
993 c = (*xopCmp)(p2, p1);
994 else
995 c = (*xopCmp)(p1, p2);
997 else
998 // BUG: relies on the GC not moving objects
999 c = memcmp(p1, p2, init.length);
1001 else
1002 c = -1;
1004 return c;
1007 override size_t tsize()
1009 return init.length;
1012 override void[] init() { return m_init; }
1014 override uint flags() { return m_flags; }
1016 override void destroy(void *p)
1018 if (xdtor)
1019 (*xdtor)(p);
1022 override void postblit(void *p)
1024 if (xpostblit)
1025 (*xpostblit)(p);
1028 string name;
1029 void[] m_init; // initializer; init.ptr == null if 0 initialize
1031 hash_t function(in void*) xtoHash;
1032 int function(in void*, in void*) xopEquals;
1033 int function(in void*, in void*) xopCmp;
1034 string function(const(void)*) xtoString;
1036 uint m_flags;
1038 const(MemberInfo[]) function(string) xgetMembers;
1039 void function(void*) xdtor;
1040 void function(void*) xpostblit;
1043 class TypeInfo_Tuple : TypeInfo
1045 TypeInfo[] elements;
1047 override string toString()
1049 string s;
1050 s = "(";
1051 foreach (i, element; elements)
1053 if (i)
1054 s ~= ',';
1055 s ~= element.toString();
1057 s ~= ")";
1058 return s;
1061 override int opEquals(Object o)
1063 if (this is o)
1064 return 1;
1066 auto t = cast(TypeInfo_Tuple)o;
1067 if (t && elements.length == t.elements.length)
1069 for (size_t i = 0; i < elements.length; i++)
1071 if (elements[i] != t.elements[i])
1072 return 0;
1074 return 1;
1076 return 0;
1079 override hash_t getHash(in void *p)
1081 assert(0);
1084 override int equals(in void *p1, in void *p2)
1086 assert(0);
1089 override int compare(in void *p1, in void *p2)
1091 assert(0);
1094 override size_t tsize()
1096 assert(0);
1099 override void swap(void *p1, void *p2)
1101 assert(0);
1104 override void destroy(void *p)
1106 assert(0);
1109 override void postblit(void *p)
1111 assert(0);
1115 class TypeInfo_Const : TypeInfo
1117 override string toString() { return cast(string)
1118 ("const(" ~ base.toString() ~ ")"); }
1120 override int opEquals(Object o) { return base.opEquals(o); }
1121 override hash_t getHash(in void *p) { return base.getHash(p); }
1122 override int equals(in void *p1, in void *p2) { return base.equals(p1, p2); }
1123 override int compare(in void *p1, in void *p2) { return base.compare(p1, p2); }
1124 override size_t tsize() { return base.tsize(); }
1125 override void swap(void *p1, void *p2) { return base.swap(p1, p2); }
1127 override TypeInfo next() { return base.next(); }
1128 override uint flags() { return base.flags(); }
1129 override void[] init() { return base.init(); }
1131 TypeInfo base;
1134 class TypeInfo_Invariant : TypeInfo_Const
1136 override string toString() { return cast(string)
1137 ("invariant(" ~ base.toString() ~ ")"); }
1140 /* ========================================================================== */
1142 abstract class MemberInfo
1144 string name();
1147 class MemberInfo_field : MemberInfo
1149 this(string name, TypeInfo ti, size_t offset)
1151 m_name = name;
1152 m_typeinfo = ti;
1153 m_offset = offset;
1156 override string name() { return m_name; }
1157 TypeInfo typeInfo() { return m_typeinfo; }
1158 size_t offset() { return m_offset; }
1160 string m_name;
1161 TypeInfo m_typeinfo;
1162 size_t m_offset;
1165 class MemberInfo_function : MemberInfo
1167 this(string name, TypeInfo ti, void* fp, uint flags)
1169 m_name = name;
1170 m_typeinfo = ti;
1171 m_fp = fp;
1172 m_flags = flags;
1175 override string name() { return m_name; }
1176 TypeInfo typeInfo() { return m_typeinfo; }
1177 void* fp() { return m_fp; }
1178 uint flags() { return m_flags; }
1181 string m_name;
1182 TypeInfo m_typeinfo;
1183 void* m_fp;
1184 uint m_flags;
1188 /* ========================================================================== */
1192 * All recoverable exceptions should be derived from class Exception.
1194 class Exception : Object
1196 string msg;
1197 Exception next;
1200 * Constructor; msg is a descriptive message for the exception.
1202 this(string msg)
1204 this.msg = msg;
1207 this(string msg, Exception next)
1209 this.msg = msg;
1210 this.next = next;
1213 override void print()
1215 string s = toString();
1216 printf("%.*s\n", cast(int) s.length, s.ptr);
1219 override string toString() { return msg; }
1223 * All irrecoverable exceptions should be derived from class Error.
1225 class Error : Exception
1229 * Constructor; msg is a descriptive message for the exception.
1231 this(string msg)
1233 super(msg);
1236 this(string msg, Exception next)
1238 super(msg, next);
1242 //extern (C) int nullext = 0;
1244 /**If the top-level main throws this, the message will be printed to stderr
1245 * and the program terminates with the given exit code.
1247 class SystemExit : Exception {
1248 int exitCode;
1250 this(string msg, int exitCode = 1)
1252 this.exitCode = exitCode;
1253 super(msg);