Changeset 772
- Timestamp:
- 06/30/08 13:30:45 (2 months ago)
- Files:
-
- trunk/phobos/internal/object.d (modified) (54 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/phobos/internal/object.d
r761 r772 7 7 * This module is implicitly imported. 8 8 * Macros: 9 * WIKI = Phobos/Object9 * WIKI = Phobos/Object 10 10 */ 11 11 … … 92 92 class Object 93 93 { 94 final Monitor * getMonitorPtr() 95 { 96 Monitor * mon = cast(Monitor*)(cast(void**)this)[1]; 97 return mon; 98 } 99 94 100 void print() 95 101 { 96 printf("%.*s\n", toString());102 printf("%.*s\n", toString()); 97 103 } 98 104 … … 102 108 string toString() 103 109 { 104 return this.classinfo.name;110 return this.classinfo.name; 105 111 } 106 112 … … 110 116 hash_t toHash() 111 117 { 112 // BUG: this prevents a compacting GC from working, needs to be fixed113 return cast(uint)cast(void *)this;118 // BUG: this prevents a compacting GC from working, needs to be fixed 119 return cast(uint)cast(void *)this; 114 120 } 115 121 … … 117 123 * Compare with another Object obj. 118 124 * Returns: 119 * $(TABLE125 * $(TABLE 120 126 * $(TR $(TD this < obj) $(TD < 0)) 121 127 * $(TR $(TD this == obj) $(TD 0)) … … 125 131 int opCmp(Object o) 126 132 { 127 // BUG: this prevents a compacting GC from working, needs to be fixed128 //return cast(int)cast(void *)this - cast(int)cast(void *)o;129 130 throw new Error(cast(string) ("need opCmp for class "133 // BUG: this prevents a compacting GC from working, needs to be fixed 134 // return cast(int)cast(void *)this - cast(int)cast(void *)o; 135 136 throw new Error(cast(string) ("need opCmp for class " 131 137 ~ this.classinfo.name)); 132 138 } … … 137 143 bool opEquals(Object o) 138 144 { 139 return (this is o);145 return (this is o); 140 146 } 141 147 … … 151 157 final void notifyRegister(void delegate(Object) dg) 152 158 { 153 //printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); 154 synchronized (this) 155 { 156 Monitor* m = cast(Monitor*)(cast(void**)this)[1]; 157 foreach (inout x; m.delegates) 158 { 159 if (!x || x == dg) 160 { x = dg; 161 return; 162 } 163 } 164 165 // Increase size of delegates[] 166 auto len = m.delegates.length; 167 auto startlen = len; 168 if (len == 0) 169 { 170 len = 4; 171 auto p = calloc((void delegate(Object)).sizeof, len); 172 if (!p) 173 _d_OutOfMemory(); 174 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; 175 } 176 else 177 { 178 len += len + 4; 179 auto p = realloc(m.delegates.ptr, (void delegate(Object)).sizeof * len); 180 if (!p) 181 _d_OutOfMemory(); 182 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; 183 m.delegates[startlen .. len] = null; 184 } 185 m.delegates[startlen] = dg; 186 } 159 //printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); 160 synchronized (this) 161 { 162 // Important: Monitor is guaranteed to be initialized 163 // as the side-effect of the synchronized clause above 164 Monitor * m = getMonitorPtr(); 165 assert(m != null); 166 foreach (inout x; m.delegates) 167 { 168 if (!x || x == dg) 169 { x = dg; 170 return; 171 } 172 } 173 174 // Increase size of delegates[] 175 auto len = m.delegates.length; 176 auto startlen = len; 177 if (len == 0) 178 { 179 len = 4; 180 auto p = calloc((void delegate(Object)).sizeof, len); 181 if (!p) 182 _d_OutOfMemory(); 183 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; 184 } 185 else 186 { 187 len += len + 4; 188 auto p = realloc(m.delegates.ptr, (void delegate(Object)).sizeof * len); 189 if (!p) 190 _d_OutOfMemory(); 191 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; 192 m.delegates[startlen .. len] = null; 193 } 194 m.delegates[startlen] = dg; 195 } 187 196 } 188 197 … … 194 203 final void notifyUnRegister(void delegate(Object) dg) 195 204 { 196 synchronized (this) 197 { 198 Monitor* m = cast(Monitor*)(cast(void**)this)[1]; 199 foreach (inout x; m.delegates) 200 { 201 if (x == dg) 202 x = null; 203 } 204 } 205 synchronized (this) 206 { 207 Monitor* m = getMonitorPtr(); 208 assert(m != null); 209 foreach (inout x; m.delegates) 210 { 211 if (x == dg) 212 x = null; 213 } 214 } 205 215 } 206 216 … … 210 220 * a default constructor. 211 221 * Returns: 212 * null if failed222 * null if failed 213 223 */ 214 224 static Object factory(string classname) 215 225 { 216 auto ci = ClassInfo.find(classname);217 if (ci)218 {219 return ci.create();220 }221 return null;226 auto ci = ClassInfo.find(classname); 227 if (ci) 228 { 229 return ci.create(); 230 } 231 return null; 222 232 } 223 233 } … … 226 236 { 227 237 //printf("_d_notify_release(o = %p)\n", o); 228 Monitor* m = cast(Monitor*)(cast(void**)o)[1]; 238 Monitor* m = o.getMonitorPtr(); 239 assert(m != null); 229 240 if (m.delegates.length) 230 241 { 231 auto dgs = m.delegates; 232 synchronized (o) 233 { 234 dgs = m.delegates; 235 m.delegates = null; 236 } 237 238 foreach (dg; dgs) 239 { 240 if (dg) 241 { //printf("calling dg = %llx (%p)\n", dg, o); 242 dg(o); 243 } 244 } 245 246 free(dgs.ptr); 242 auto dgs = m.delegates; 243 synchronized (o) 244 { 245 dgs = m.delegates; 246 m.delegates = null; 247 } 248 249 foreach (dg; dgs) 250 { 251 if (dg) 252 { 253 //printf("calling dg = %llx (%p)\n", dg, o); 254 dg(o); 255 } 256 } 257 258 free(dgs.ptr); 247 259 } 248 260 } … … 256 268 struct Interface 257 269 { 258 ClassInfo classinfo; /// .classinfo for this interface (not for containing class)270 ClassInfo classinfo; /// .classinfo for this interface (not for containing class) 259 271 void *[] vtbl; 260 int offset; /// offset to Interface 'this' from Object 'this'272 int offset; /// offset to Interface 'this' from Object 'this' 261 273 } 262 274 … … 269 281 class ClassInfo : Object 270 282 { 271 byte[] init; /** class static initializer272 * (init.length gives size in bytes of class)273 */274 string name; /// class name275 void *[] vtbl; /// virtual function pointer table276 Interface[] interfaces; /// interfaces this class implements277 ClassInfo base; /// base class283 byte[] init; /** class static initializer 284 * (init.length gives size in bytes of class) 285 */ 286 string name; /// class name 287 void *[] vtbl; /// virtual function pointer table 288 Interface[] interfaces; /// interfaces this class implements 289 ClassInfo base; /// base class 278 290 void *destructor; 279 291 void (*classInvariant)(Object); 280 292 uint flags; 281 // 1:// is IUnknown or is derived from IUnknown282 // 2:// has no possible pointers into GC memory283 // 4:// has offTi[] member284 // 8:// has constructors285 // 16: // has xgetMembers member293 // 1: // is IUnknown or is derived from IUnknown 294 // 2: // has no possible pointers into GC memory 295 // 4: // has offTi[] member 296 // 8: // has constructors 297 // 16: // has xgetMembers member 286 298 void *deallocator; 287 299 OffsetTypeInfo[] offTi; 288 void function(Object) defaultConstructor; // default Constructor300 void function(Object) defaultConstructor; 289 301 const(MemberInfo[]) function(string) xgetMembers; 290 302 … … 295 307 static ClassInfo find(string classname) 296 308 { 297 foreach (m; ModuleInfo.modules())298 {299 //writefln("module %s, %d", m.name, m.localClasses.length);300 foreach (c; m.localClasses)301 {302 //writefln("\tclass %s", c.name);303 if (c.name == classname)304 return c;305 }306 }307 return null;309 foreach (m; ModuleInfo.modules()) 310 { 311 //writefln("module %s, %d", m.name, m.localClasses.length); 312 foreach (c; m.localClasses) 313 { 314 //writefln("\tclass %s", c.name); 315 if (c.name == classname) 316 return c; 317 } 318 } 319 return null; 308 320 } 309 321 … … 311 323 * Create instance of Object represented by 'this'. 312 324 * Returns: 313 * the object created, or null if the Object does314 * does not have a default constructor325 * the object created, or null if the Object does 326 * does not have a default constructor 315 327 */ 316 328 Object create() 317 329 { 318 if (flags & 8 && !defaultConstructor)319 return null;320 Object o = _d_newclass(this);321 if (flags & 8 && defaultConstructor)322 {323 defaultConstructor(o);324 }325 return o;330 if (flags & 8 && !defaultConstructor) 331 return null; 332 Object o = _d_newclass(this); 333 if (flags & 8 && defaultConstructor) 334 { 335 defaultConstructor(o); 336 } 337 return o; 326 338 } 327 339 … … 332 344 const(MemberInfo[]) getMembers(string name) 333 345 { 334 if (flags & 16 && xgetMembers)335 {336 return xgetMembers(name);337 }338 return null;346 if (flags & 16 && xgetMembers) 347 { 348 return xgetMembers(name); 349 } 350 return null; 339 351 } 340 352 } … … 350 362 struct OffsetTypeInfo 351 363 { 352 size_t offset; /// Offset of member from start of object353 TypeInfo ti; /// TypeInfo for this member364 size_t offset; /// Offset of member from start of object 365 TypeInfo ti; /// TypeInfo for this member 354 366 } 355 367 … … 363 375 { 364 376 override hash_t toHash() 365 { hash_t hash; 366 367 foreach (char c; this.toString()) 368 hash = hash * 9 + c; 369 return hash; 377 { 378 hash_t hash; 379 380 foreach (char c; this.toString()) 381 hash = hash * 9 + c; 382 return hash; 370 383 } 371 384 372 385 override int opCmp(Object o) 373 386 { 374 if (this is o)375 return 0;376 TypeInfo ti = cast(TypeInfo)o;377 if (ti is null)378 return 1;379 return std.string.cmp(this.toString(), ti.toString());387 if (this is o) 388 return 0; 389 TypeInfo ti = cast(TypeInfo)o; 390 if (ti is null) 391 return 1; 392 return std.string.cmp(this.toString(), ti.toString()); 380 393 } 381 394 382 395 override bool opEquals(Object o) 383 396 { 384 /* TypeInfo instances are singletons, but duplicates can exist385 * across DLL's. Therefore, comparing for a name match is386 * sufficient.387 */388 if (this is o)389 return 1;390 TypeInfo ti = cast(TypeInfo)o;391 return (ti && this.toString() == ti.toString());397 /* TypeInfo instances are singletons, but duplicates can exist 398 * across DLL's. Therefore, comparing for a name match is 399 * sufficient. 400 */ 401 if (this is o) 402 return 1; 403 TypeInfo ti = cast(TypeInfo)o; 404 return (ti && this.toString() == ti.toString()); 392 405 } 393 406 … … 407 420 void swap(void *p1, void *p2) 408 421 { 409 size_t n = tsize();410 for (size_t i = 0; i < n; i++)411 { byte t;412 413 t = (cast(byte *)p1)[i];414 (cast(byte *)p1)[i] = (cast(byte *)p2)[i];415 (cast(byte *)p2)[i] = t;416 }422 size_t n = tsize(); 423 for (size_t i = 0; i < n; i++) 424 { byte t; 425 426 t = (cast(byte *)p1)[i]; 427 (cast(byte *)p1)[i] = (cast(byte *)p2)[i]; 428 (cast(byte *)p2)[i] = t; 429 } 417 430 } 418 431 … … 444 457 { TypeInfo_Typedef c; 445 458 446 returnthis is o ||447 ((c = cast(TypeInfo_Typedef)o) !is null &&448 this.name == c.name &&449 this.base == c.base);459 return this is o || 460 ((c = cast(TypeInfo_Typedef)o) !is null && 461 this.name == c.name && 462 this.base == c.base); 450 463 } 451 464 … … 479 492 { TypeInfo_Pointer c; 480 493 481 return this is o ||482 ((c = cast(TypeInfo_Pointer)o) !is null &&483 this.m_next == c.m_next);494 return this is o || 495 ((c = cast(TypeInfo_Pointer)o) !is null && 496 this.m_next == c.m_next); 484 497 } 485 498 … … 496 509 override int compare(in void *p1, in void *p2) 497 510 { 498 if (*cast(void* *)p1 < *cast(void* *)p2)499 return -1;500 else if (*cast(void* *)p1 > *cast(void* *)p2)501 return 1;502 else503 return 0;511 if (*cast(void* *)p1 < *cast(void* *)p2) 512 return -1; 513 else if (*cast(void* *)p1 > *cast(void* *)p2) 514 return 1; 515 else 516 return 0; 504 517 } 505 518 506 519 override size_t tsize() 507 520 { 508 return (void*).sizeof;521 return (void*).sizeof; 509 522 } 510 523 511 524 override void swap(void *p1, void *p2) 512 { void* tmp; 513 tmp = *cast(void**)p1; 514 *cast(void**)p1 = *cast(void**)p2; 515 *cast(void**)p2 = tmp; 525 { 526 void* tmp; 527 tmp = *cast(void**)p1; 528 *cast(void**)p1 = *cast(void**)p2; 529 *cast(void**)p2 = tmp; 516 530 } 517 531 … … 529 543 { TypeInfo_Array c; 530 544 531 return this is o ||532 ((c = cast(TypeInfo_Array)o) !is null &&533 this.value == c.value);545 return this is o || 546 ((c = cast(TypeInfo_Array)o) !is null && 547 this.value == c.value); 534 548 } 535 549 536 550 override hash_t getHash(in void *p) 537 { size_t sz = value.tsize(); 538 hash_t hash = 0; 539 void[] a = *cast(void[]*)p; 540 for (size_t i = 0; i < a.length; i++) 541 hash += value.getHash(a.ptr + i * sz); 551 { 552 size_t sz = value.tsize(); 553 hash_t hash = 0; 554 void[] a = *cast(void[]*)p; 555 for (size_t i = 0; i < a.length; i++) 556 hash += value.getHash(a.ptr + i * sz); 542 557 return hash; 543 558 } … … 545 560 override bool equals(in void *p1, in void *p2) 546 561 { 547 void[] a1 = *cast(void[]*)p1;548 void[] a2 = *cast(void[]*)p2;549 if (a1.length != a2.length)550 return 0;551 size_t sz = value.tsize();552 for (size_t i = 0; i < a1.length; i++)553 {554 if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))555 return 0;556 }562 void[] a1 = *cast(void[]*)p1; 563 void[] a2 = *cast(void[]*)p2; 564 if (a1.length != a2.length) 565 return 0; 566 size_t sz = value.tsize(); 567 for (size_t i = 0; i < a1.length; i++) 568 { 569 if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz)) 570 return 0; 571 } 557 572 return 1; 558 573 } … … 560 575 override int compare(in void *p1, in void *p2) 561 576 { 562 void[] a1 = *cast(void[]*)p1;563 void[] a2 = *cast(void[]*)p2;564 size_t sz = value.tsize();565 size_t len = a1.length;577 void[] a1 = *cast(void[]*)p1; 578 void[] a2 = *cast(void[]*)p2; 579 size_t sz = value.tsize(); 580 size_t len = a1.length; 566 581 567 582 if (a2.length < len) … … 578 593 override size_t tsize() 579 594 { 580 return (void[]).sizeof;595 return (void[]).sizeof; 581 596 } 582 597 583 598 override void swap(void *p1, void *p2) 584 { void[] tmp; 585 tmp = *cast(void[]*)p1; 586 *cast(void[]*)p1 = *cast(void[]*)p2; 587 *cast(void[]*)p2 = tmp; 599 { 600 void[] tmp; 601 tmp = *cast(void[]*)p1; 602 *cast(void[]*)p1 = *cast(void[]*)p2; 603 *cast(void[]*)p2 = tmp; 588 604 } 589 605 … … 592 608 override TypeInfo next() 593 609 { 594 return value;610 return value; 595 611 } 596 612 … … 602 618 override string toString() 603 619 { 604 return cast(string)620 return cast(string) 605 621 (value.toString() ~ "[" ~ std.string.toString(len) ~ "]"); 606 622 } … … 609 625 { TypeInfo_StaticArray c; 610 626 611 return this is o ||612 ((c = cast(TypeInfo_StaticArray)o) !is null &&613 this.len == c.len &&614 this.value == c.value);627 return this is o || 628 ((c = cast(TypeInfo_StaticArray)o) !is null && 629 this.len == c.len && 630 this.value == c.value); 615 631 } 616 632 617 633 override hash_t getHash(in void *p) 618 { size_t sz = value.tsize(); 619 hash_t hash = 0; 620 for (size_t i = 0; i < len; i++) 621 hash += value.getHash(p + i * sz); 634 { 635 size_t sz = value.tsize(); 636 hash_t hash = 0; 637 for (size_t i = 0; i < len; i++) 638 hash += value.getHash(p + i * sz); 622 639 return hash; 623 640 } … … 625 642 override bool equals(in void *p1, in void *p2) 626 643 { 627 size_t sz = value.tsize();644 size_t sz = value.tsize(); 628 645 629 646 for (size_t u = 0; u < len; u++) 630 647 { 631 if (!value.equals(p1 + u * sz, p2 + u * sz))632 return 0;648 if (!value.equals(p1 + u * sz, p2 + u * sz)) 649 return 0; 633 650 } 634 651 return 1; … … 637 654 override int compare(in void *p1, in void *p2) 638 655 { 639 size_t sz = value.tsize();656 size_t sz = value.tsize(); 640 657 641 658 for (size_t u = 0; u < len; u++) … … 650 667 override size_t tsize() 651 668 { 652 return len * value.tsize();669 return len * value.tsize(); 653 670 } 654 671 655 672 override void swap(void *p1, void *p2) 656 { void* tmp; 657 size_t sz = value.tsize(); 658 ubyte[16] buffer; 659 void* pbuffer; 660 661 if (sz < buffer.sizeof) 662 tmp = buffer.ptr; 663 else 664 tmp = pbuffer = (new void[sz]).ptr; 665 666 for (size_t u = 0; u < len; u += sz) 667 { size_t o = u * sz; 668 memcpy(tmp, p1 + o, sz); 669 memcpy(p1 + o, p2 + o, sz); 670 memcpy(p2 + o, tmp, sz); 671 } 672 if (pbuffer) 673 delete pbuffer; 673 { 674 void* tmp; 675 size_t sz = value.tsize(); 676 ubyte[16] buffer; 677 void* pbuffer; 678 679 if (sz < buffer.sizeof) 680 tmp = buffer.ptr; 681 else 682 tmp = pbuffer = (new void[sz]).ptr; 683 684 for (size_t u = 0; u < len; u += sz) 685 { size_t o = u * sz; 686 memcpy(tmp, p1 + o, sz); 687 memcpy(p1 + o, p2 + o, sz); 688 memcpy(p2 + o, tmp, sz); 689 } 690 if (pbuffer) 691 delete pbuffer; 674 692 } 675 693 … … 680 698 override void destroy(void *p) 681 699 { 682 auto sz = value.tsize();683 p += sz * len;684 foreach (i; 0 .. len)685 {686 p -= sz;687 value.destroy(p);688 }700 auto sz = value.tsize(); 701 p += sz * len; 702 foreach (i; 0 .. len) 703 { 704 p -= sz; 705 value.destroy(p); 706 } 689 707 } 690 708 691 709 override void postblit(void *p) 692 710 { 693 auto sz = value.tsize();694 foreach (i; 0 .. len)695 {696 value.postblit(p);697 p += sz;698 }711 auto sz = value.tsize(); 712 foreach (i; 0 .. len) 713 { 714 value.postblit(p); 715 p += sz; 716 } 699 717 } 700 718 … … 707 725 override string toString() 708 726 { 709 return cast(string) (value.toString() ~ "[" ~ key.toString() ~ "]");727 return cast(string) (value.toString() ~ "[" ~ key.toString() ~ "]"); 710 728 } 711 729 … … 713 731 { TypeInfo_AssociativeArray c; 714 732 715 return this is o ||716 ((c = cast(TypeInfo_AssociativeArray)o) !is null &&717 this.key == c.key &&718 this.value == c.value);733 return this is o || 734 ((c = cast(TypeInfo_AssociativeArray)o) !is null && 735 this.key == c.key && 736 this.value == c.value); 719 737 } 720 738 … … 723 741 override size_t tsize() 724 742 { 725 return (char[int]).sizeof;743 return (char[int]).sizeof; 726 744 } 727 745 … … 737 755 override string toString() 738 756 { 739 return cast(string) (next.toString() ~ "()");757 return cast(string) (next.toString() ~ "()"); 740 758 } 741 759 … … 743 761 { TypeInfo_Function c; 744 762 745 return this is o ||746 ((c = cast(TypeInfo_Function)o) !is null &&747 this.next == c.next);763 return this is o || 764 ((c = cast(TypeInfo_Function)o) !is null && 765 this.next == c.next); 748 766 } 749 767 … … 752 770 override size_t tsize() 753 771 { 754 return 0;// no size for functions755 } 756 757 TypeInfo next; // function return type772 return 0; // no size for functions 773 } 774 775 TypeInfo next; // function return type 758 776 } 759 777 … … 762 780 override string toString() 763 781 { 764 return cast(string) (next.toString() ~ " delegate()");782 return cast(string) (next.toString() ~ " delegate()"); 765 783 } 766 784 … … 768 786 { TypeInfo_Delegate c; 769 787 770 return this is o ||771 ((c = cast(TypeInfo_Delegate)o) !is null &&772 this.next == c.next);788 return this is o || 789 ((c = cast(TypeInfo_Delegate)o) !is null && 790 this.next == c.next); 773 791 } 774 792 … … 776 794 777 795 override size_t tsize() 778 { alias int delegate() dg; 779 return dg.sizeof; 796 { 797 alias int delegate() dg; 798 return dg.sizeof; 780 799 } 781 800 782 801 override uint flags() { return 1; } 783 802 784 TypeInfo next; // delegate return type803 TypeInfo next; // delegate return type 785 804 } 786 805 … … 792 811 { TypeInfo_Class c; 793 812 794 return this is o ||795 ((c = cast(TypeInfo_Class)o) !is null &&796 this.info.name == c.classinfo.name);813 return this is o || 814 ((c = cast(TypeInfo_Class)o) !is null && 815 this.info.name == c.classinfo.name); 797 816 } 798 817 799 818 override hash_t getHash(in void *p) 800 819 { 801 Object o = *cast(Object*)p;802 return o ? o.toHash() : 0;820 Object o = *cast(Object*)p; 821 return o ? o.toHash() : 0; 803 822 } 804 823 805 824 override bool equals(in void *p1, in void *p2) 806 825 { 807 Object o1 = *cast(Object*)p1;808 Object o2 = *cast(Object*)p2;809 810 return (o1 is o2) || (o1 && o1.opEquals(o2));826 Object o1 = *cast(Object*)p1; 827 Object o2 = *cast(Object*)p2; 828 829 return (o1 is o2) || (o1 && o1.opEquals(o2)); 811 830 } 812 831 813 832 override int compare(in void *p1, in void *p2) 814 833 { 815 Object o1 = *cast(Object*)p1; 816 Object o2 = *cast(Object*)p2; 817 int c = 0; 818 819 // Regard null references as always being "less than" 820 if (o1 !is o2) 821 { 822 if (o1) 823 { if (!o2) 824 c = 1; 825 else 826 c = o1.opCmp(o2); 827 } 828 else 829 c = -1; 830 } 831 return c; 834 Object o1 = *cast(Object*)p1; 835 Object o2 = *cast(Object*)p2; 836 int c = 0; 837 838 // Regard null references as always being "less than" 839 if (o1 !is o2) 840 { 841 if (o1) 842 { 843 if (!o2) 844 c = 1; 845 else 846 c = o1.opCmp(o2); 847 } 848 else 849 c = -1; 850 } 851 return c; 832 852 } 833 853 834 854 override size_t tsize() 835 855 { 836 return Object.sizeof;856 return Object.sizeof; 837 857 } 838 858 … … 841 861 override OffsetTypeInfo[] offTi() 842 862 { 843 return (info.flags & 4) ? info.offTi : null;863 return (info.flags & 4) ? info.offTi : null; 844 864 } 845 865 … … 854 874 { TypeInfo_Interface c; 855 875 856 return this is o ||857 ((c = cast(TypeInfo_Interface)o) !is null &&858 this.info.name == c.classinfo.name);876 return this is o || 877 ((c = cast(TypeInfo_Interface)o) !is null && 878 this.info.name == c.classinfo.name); 859 879 } 860 880 861 881 override hash_t getHash(in void *p) 862 882 { 863 Interface* pi = **cast(Interface ***)*cast(void**)p;864 Object o = cast(Object)(*cast(void**)p - pi.offset);865 assert(o);866 return o.toHash();883 Interface* pi = **cast(Interface ***)*cast(void**)p; 884 Object o = cast(Object)(*cast(void**)p - pi.offset); 885 assert(o); 886 return o.toHash(); 867 887 } 868 888 869 889 override bool equals(in void *p1, in void *p2) 870 890 { 871 Interface* pi = **cast(Interface ***)*cast(void**)p1;872 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);873 pi = **cast(Interface ***)*cast(void**)p2;874 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);875 876 return o1 == o2 || (o1 && o1.opCmp(o2) == 0);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 896 return o1 == o2 || (o1 && o1.opCmp(o2) == 0); 877 897 } 878 898 879 899 override int compare(in void *p1, in void *p2) 880 900 { 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); 885 int c = 0; 886 887 // Regard null references as always being "less than" 888 if (o1 != o2) 889 { 890 if (o1) 891 { if (!o2) 892 c = 1; 893 else 894 c = o1.opCmp(o2); 895 } 896 else 897 c = -1; 898 } 899 return c; 901 Interface* pi = **cast(Interface ***)*cast(void**)p1; 902 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset); 903 pi = **cast(Interface ***)*cast(void**)p2; 904 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset); 905 int c = 0; 906 907 // Regard null references as always being "less than" 908 if (o1 != o2) 909 { 910 if (o1) 911 { 912 if (!o2) 913 c = 1; 914 else 915 c = o1.opCmp(o2); 916 } 917 else 918 c = -1; 919 } 920 return c; 900 921 } 901 922 902 923 override size_t tsize() 903 924 { 904 return Object.sizeof;925 return Object.sizeof; 905 926 } 906 927 … … 917 938 { TypeInfo_Struct s; 918 939 919 return this is o ||920 ((s = cast(TypeInfo_Struct)o) !is null &&921 this.name == s.name &&922 this.init.length == s.init.length);940 return this is o || 941 ((s = cast(TypeInfo_Struct)o) !is null && 942 this.name == s.name && 943 this.init.length == s.init.length); 923 944 } 924 945 925 946 override hash_t getHash(in void *p) 926 { hash_t h; 927 928 assert(p); 929 if (xtoHash) 930 { //printf("getHash() using xtoHash\n"); 931 h = (*xtoHash)(p); 932 } 933 else 934 { 935 //printf("getHash() using default hash\n"); 936 // A sorry hash algorithm. 937 // Should use the one for strings. 938 // BUG: relies on the GC not moving objects 939 auto q = cast(const(ubyte)*)p; 940 for (size_t i = 0; i < init.length; i++) 941 { h = h * 9 + *q; 942 q++; 943 } 944 } 945 return h; 947 { 948 hash_t h; 949 950 assert(p); 951 if (xtoHash) 952 { //printf("getHash() using xtoHash\n"); 953 h = (*xtoHash)(p); 954 } 955 else 956 { 957 //printf("getHash() using default hash\n"); 958 // A sorry hash algorithm. 959 // Should use the one for strings. 960 // BUG: relies on the GC not moving objects 961 auto q = cast(const(ubyte)*)p; 962 for (size_t i = 0; i < init.length; i++) 963 { 964 h = h * 9 + *q; 965 q++; 966 } 967 } 968 return h; 946 969 } 947 970 948 971 override bool equals(in void *p2, in void *p1) 949 { bool c; 950 951 if (p1 == p2) 952 c = 1; 953 else if (!p1 || !p2) 954 c = 0; 955 else if (xopEquals) 956 c = (*xopEquals)(p1, p2); 957 else 958 // BUG: relies on the GC not moving objects 959 c = (memcmp(p1, p2, init.length) == 0); 960 return c; 972 { 973 bool c; 974 975 if (p1 == p2) 976 c = 1; 977 else if (!p1 || !p2) 978 c = 0; 979 else if (xopEquals) 980 c = (*xopEquals)(p1, p2); 981 else 982 // BUG: relies on the GC not moving objects 983 c = (memcmp(p1, p2, init.length) == 0); 984 return c; 961 985 } 962 986 963 987 override int compare(in void *p2, in void *p1) 964 988 { 965 int c = 0; 966 967 // Regard null references as always being "less than" 968 &nbs
