comparison d2/qt/core/QList.d @ 357:9784459f0750

An attempt (failed due to optlink) to improve locality of declarations exported from QtD executables Q_CLASSINFO implementation Now Qtd can be built on Windows
author Max Samukha <maxter@spambox.com>
date Wed, 02 Jun 2010 19:38:05 +0300
parents 970332a88b72
children a032df77b6ab
comparison
equal deleted inserted replaced
356:12cec2d14e1c 357:9784459f0750
96 Atomic!int ref_; 96 Atomic!int ref_;
97 int alloc, begin, end; 97 int alloc, begin, end;
98 uint sharable; 98 uint sharable;
99 void*[1] array; 99 void*[1] array;
100 } 100 }
101 101
102 enum { DataHeaderSize = Data.sizeof - (void*).sizeof } 102 enum { DataHeaderSize = Data.sizeof - (void*).sizeof }
103 103
104 static Data shared_null; 104 static Data shared_null;
105 Data *d; 105 Data *d;
106 106
107 static this() 107 static this()
108 { 108 {
109 shared_null = Data(Atomic!int(1), 0, 0, 0, true, [null]); 109 shared_null = Data(Atomic!int(1), 0, 0, 0, true, [null]);
110 } 110 }
111 111
112 112
113 // Data *detach(); // remove in 5.0 113 // Data *detach(); // remove in 5.0
114 114
115 Data* detach2() 115 Data* detach2()
116 { 116 {
126 if (!d.alloc) 126 if (!d.alloc)
127 d.begin = d.end = 0; 127 d.begin = d.end = 0;
128 128
129 return x; 129 return x;
130 } 130 }
131 131
132 void realloc(int alloc) 132 void realloc(int alloc)
133 { 133 {
134 // assert(d.ref_ == 1); 134 // assert(d.ref_ == 1);
135 Data* x = cast(Data*)(qRealloc(d, DataHeaderSize + alloc * (void*).sizeof)); 135 Data* x = cast(Data*)(qRealloc(d, DataHeaderSize + alloc * (void*).sizeof));
136 if (!x) 136 if (!x)
139 d = x; 139 d = x;
140 d.alloc = alloc; 140 d.alloc = alloc;
141 if (!alloc) 141 if (!alloc)
142 d.begin = d.end = 0; 142 d.begin = d.end = 0;
143 } 143 }
144 144
145 void** append() 145 void** append()
146 { 146 {
147 // #TODO Q_ASSERT(d.ref_ == 1); 147 // #TODO Q_ASSERT(d.ref_ == 1);
148 if (d.end == d.alloc) { 148 if (d.end == d.alloc) {
149 int n = d.end - d.begin; 149 int n = d.end - d.begin;
316 } 316 }
317 317
318 import std.stdio; 318 import std.stdio;
319 import std.conv; 319 import std.conv;
320 320
321 alias void Dummy; // DMD bug #3538 321 alias void Dummy; // DMD bug #3538
322 322
323 struct QList(T, alias Default = Dummy) 323 struct QList(T, alias Default = Dummy)
324 { 324 {
325 alias T ElementType;
326
325 static if (is(Default == Dummy)) 327 static if (is(Default == Dummy))
326 alias QTypeInfo!T TI; 328 alias QTypeInfo!T TI;
327 else 329 else
328 alias Default TI; 330 alias Default TI;
329 331
330 struct Node 332 struct Node
331 { 333 {
332 void *v; 334 void *v;
333 335
334 static if (isQObjectType!T || isObjectType!T || isValueType!T || is(T == string)) // binded Qt types 336 static if (isQObjectType!T || isObjectType!T || isValueType!T || is(T == string)) // binded Qt types
335 { 337 {
336 T t() 338 T t()
337 { 339 {
338 static if(is(T == string)) 340 static if(is(T == string))
350 return T.__getObject( *cast(void**)(&this) ); 352 return T.__getObject( *cast(void**)(&this) );
351 } 353 }
352 } 354 }
353 } 355 }
354 else // native types 356 else // native types
355 { 357 {
356 ref T t() 358 ref T t()
357 { 359 {
358 static if(TI.isLarge || TI.isStatic) 360 static if(TI.isLarge || TI.isStatic)
359 return *cast(T*)(this.v); 361 return *cast(T*)(this.v);
360 else 362 else
361 return *cast(T*)(&this); 363 return *cast(T*)(&this);
362 } 364 }
363 } 365 }
364 } 366 }
365 367
366 union { 368 union {
367 QListData p; 369 QListData p;
368 QListData.Data* d; 370 QListData.Data* d;
369 } 371 }
370 372
373 void output() 375 void output()
374 { 376 {
375 writeln("QList atomic ", d.ref_.load()); 377 writeln("QList atomic ", d.ref_.load());
376 } 378 }
377 */ 379 */
378 380
379 static QList!T opCall() 381 static QList!T opCall()
380 { 382 {
381 QList!T res; 383 QList!T res;
382 // writeln("QList opCall"); 384 // writeln("QList opCall");
383 385
384 res.d = &QListData.shared_null; 386 res.d = &QListData.shared_null;
385 res.d.ref_.increment(); 387 res.d.ref_.increment();
386 388
387 return res; 389 return res;
388 } 390 }
389 391
390 this(this) 392 this(this)
391 { 393 {
414 if (!d.sharable) 416 if (!d.sharable)
415 detach_helper(); 417 detach_helper();
416 } 418 }
417 return this; 419 return this;
418 } 420 }
419 421
420 int length() const { return p.size(); } 422 int length() const { return p.size(); }
421 int size() const { return length; } 423 int size() const { return length; }
422 424
423 void detach() { if (d.ref_.load() != 1) detach_helper(); } 425 void detach() { if (d.ref_.load() != 1) detach_helper(); }
424 426
425 private void detach_helper() 427 private void detach_helper()
426 { 428 {
427 Node *n = cast(Node*)(p.begin()); 429 Node *n = cast(Node*)(p.begin());
428 QListData.Data* x = p.detach2(); 430 QListData.Data* x = p.detach2();
429 node_copy(cast(Node*)(p.begin()), cast(Node*)(p.end()), n); 431 node_copy(cast(Node*)(p.begin()), cast(Node*)(p.end()), n);
430 if (!x.ref_.decrement()) 432 if (!x.ref_.decrement())
431 free(x); 433 free(x);
432 } 434 }
433 435
434 void append(const T t) // fix to const ref for complex types TODO 436 void append(const T t) // fix to const ref for complex types TODO
435 { 437 {
436 detach(); 438 detach();
437 static if (isQObjectType!T || isObjectType!T || isValueType!T) 439 static if (isQObjectType!T || isObjectType!T || isValueType!T)
438 { 440 {
442 { 444 {
443 const T cpy = t; 445 const T cpy = t;
444 node_construct(cast(Node*)(p.append()), cpy); 446 node_construct(cast(Node*)(p.append()), cpy);
445 } 447 }
446 } 448 }
447 449
448 alias append opCatAssign; 450 alias append opCatAssign;
449 451
450 static if (isQObjectType!T || isObjectType!T || isValueType!T || is(T == string)) 452 static if (isQObjectType!T || isObjectType!T || isValueType!T || is(T == string))
451 { 453 {
452 T at(int i) const 454 T at(int i) const
453 { 455 {
454 assert(i >= 0 && i < p.size(), "QList!T.at(): index out of range"); 456 assert(i >= 0 && i < p.size(), "QList!T.at(): index out of range");
470 ref T opIndex(int i) 472 ref T opIndex(int i)
471 { 473 {
472 assert(i >= 0 && i < p.size(), "QList!T.at(): index out of range"); 474 assert(i >= 0 && i < p.size(), "QList!T.at(): index out of range");
473 return (cast(Node*)(p.at(i))).t(); 475 return (cast(Node*)(p.at(i))).t();
474 } 476 }
475 } 477 }
476 478
477 static if (isQObjectType!T || isObjectType!T || isValueType!T) //binded types 479 static if (isQObjectType!T || isObjectType!T || isValueType!T) //binded types
478 void node_construct(Node *n, const T t) 480 void node_construct(Node *n, const T t)
479 { 481 {
480 static if (isValueType!T) 482 static if (isValueType!T)
481 { 483 {
504 else static if (TI.isComplex) 506 else static if (TI.isComplex)
505 q_new_at(n, t); // new (n) T(t); 507 q_new_at(n, t); // new (n) T(t);
506 else 508 else
507 *cast(T*)(n) = cast(T)(t); 509 *cast(T*)(n) = cast(T)(t);
508 } 510 }
509 511
510 void node_copy(Node *from, Node *to, Node *src) 512 void node_copy(Node *from, Node *to, Node *src)
511 { 513 {
512 // writeln("QList node_copy"); 514 // writeln("QList node_copy");
513 static if (isQObjectType!T || isObjectType!T) 515 static if (isQObjectType!T || isObjectType!T)
514 {} // ensure to do nothing. copying only a pointer 516 {} // ensure to do nothing. copying only a pointer
525 else if (TI.isComplex) 527 else if (TI.isComplex)
526 while(from != to) 528 while(from != to)
527 T.__constructPlacedNativeCopy(src++, from++); // new (from++) T(*reinterpret_cast<T*>(src++)); 529 T.__constructPlacedNativeCopy(src++, from++); // new (from++) T(*reinterpret_cast<T*>(src++));
528 } 530 }
529 else static if (TI.isLarge || TI.isStatic) 531 else static if (TI.isLarge || TI.isStatic)
530 while(from != to) 532 while(from != to)
531 (from++).v = q_new!T(*cast(T*)((src++).v)); 533 (from++).v = q_new!T(*cast(T*)((src++).v));
532 else static if (TI.isComplex) 534 else static if (TI.isComplex)
533 while(from != to) 535 while(from != to)
534 q_new_at(from++, *cast(T*)(src++)); 536 q_new_at(from++, *cast(T*)(src++));
535 } 537 }
536 538
537 T[] toArray() 539 T[] toArray()
538 { 540 {
539 T[] res; 541 T[] res;
540 res.length = this.length; 542 res.length = this.length;
541 for(int i = 0; i < res.length; ++i) 543 for(int i = 0; i < res.length; ++i)
545 else 547 else
546 res[i] = this.opIndex(i); 548 res[i] = this.opIndex(i);
547 } 549 }
548 return res; 550 return res;
549 } 551 }
550 552
551 void free(QListData.Data* data) 553 void free(QListData.Data* data)
552 { 554 {
553 // writeln("QList data destroyed"); 555 // writeln("QList data destroyed");
554 node_destruct(cast(Node*)(data.array.ptr + data.begin), 556 node_destruct(cast(Node*)(data.array.ptr + data.begin),
555 cast(Node*)(data.array.ptr + data.end)); 557 cast(Node*)(data.array.ptr + data.end));
556 if (data.ref_.load() == 0) 558 if (data.ref_.load() == 0)
557 qFree(data); 559 qFree(data);
558 } 560 }
559 561
560 void node_destruct(Node *from, Node *to) 562 void node_destruct(Node *from, Node *to)
561 { 563 {
562 static if (isQObjectType!T || isObjectType!T) //binded types 564 static if (isQObjectType!T || isObjectType!T) //binded types
563 {} // removing just pointers, do nothing 565 {} // removing just pointers, do nothing
564 else static if (is(T == string)) 566 else static if (is(T == string))
581 while (from != to) --to, q_delete(cast(T*)(to.v)); 583 while (from != to) --to, q_delete(cast(T*)(to.v));
582 else static if (TI.isComplex) 584 else static if (TI.isComplex)
583 while (from != to) --to, cast(T*)(to).__dtor(); 585 while (from != to) --to, cast(T*)(to).__dtor();
584 } 586 }
585 } 587 }
586 588
587 //iteration support 589 //iteration support
588 int opApply(int delegate(ref T) dg) 590 int opApply(int delegate(ref T) dg)
589 { 591 {
590 int result = 0; 592 int result = 0;
591 int sz = this.length; 593 int sz = this.length;