Mercurial > projects > qtd
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; |