Mercurial > projects > qtd
comparison d2/qtd/meta/Runtime.d @ 372:a032df77b6ab
Simple debug helper. Unittests. Meta-object for polymorphic non-QObjects
author | Max Samukha <maxter@spambox.com> |
---|---|
date | Thu, 08 Jul 2010 17:19:05 +0300 |
parents | 185df9220ea7 |
children |
comparison
equal
deleted
inserted
replaced
370:7fd4b69378bf | 372:a032df77b6ab |
---|---|
89 { | 89 { |
90 super(msg); | 90 super(msg); |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 /** | |
95 All meta-object classes inherit from this base class. | |
96 */ | |
94 abstract class MetaBase | 97 abstract class MetaBase |
95 { | 98 { |
96 alias typeof(this) This; | 99 alias typeof(this) This; |
97 | 100 |
98 string name; | 101 string name; |
121 // use that to create the attribute instance. | 124 // use that to create the attribute instance. |
122 static if (attr.length > 2 && (is(attr[2] : MetaAttribute))) | 125 static if (attr.length > 2 && (is(attr[2] : MetaAttribute))) |
123 { | 126 { |
124 alias attr[2] MA; | 127 alias attr[2] MA; |
125 alias TypeTuple!(attr[0..2], attr[3..$]) args; | 128 alias TypeTuple!(attr[0..2], attr[3..$]) args; |
126 attributes ~= MA /*COMPILER BUG: tuple element as tuple*/[0].create!args(); | 129 attributes ~= MA /*COMPILER BUG: tuple element as tuple*/[0].create(args); |
127 } | 130 } |
128 } | 131 } |
129 } | 132 } |
130 | 133 |
131 protected void construct(alias symbol)() | 134 protected void construct(alias symbol)() |
236 | 239 |
237 alias createImpl!This create; | 240 alias createImpl!This create; |
238 | 241 |
239 static struct AllMembersRange | 242 static struct AllMembersRange |
240 { | 243 { |
241 public //private | 244 private |
242 { | 245 { |
243 This metaClass_; | 246 This metaClass_; |
244 MetaBase[] members_; | 247 MetaBase[] members_; |
245 | 248 |
246 void skipEmpty() | 249 void skipEmpty() |
247 { | 250 { |
248 while (!metaClass_.members_.length) | 251 while (!metaClass_.members_.length) |
249 { | 252 { |
250 metaClass_ = metaClass_.base_; | 253 metaClass_ = metaClass_.base_; |
251 if (!metaClass_) | 254 if (!metaClass_) |
252 { | |
253 members_ = null; | |
254 return; | 255 return; |
255 } | |
256 } | 256 } |
257 | 257 |
258 members_ = metaClass_.members_; | 258 members_ = metaClass_.members_; |
259 } | 259 } |
260 } | 260 } |
343 | 343 |
344 | 344 |
345 /* internal */ void construct(T : Object)() | 345 /* internal */ void construct(T : Object)() |
346 { | 346 { |
347 super.construct!T(); | 347 super.construct!T(); |
348 classInfo_ = T.classinfo; | |
348 static if (!is(T == Object)) | 349 static if (!is(T == Object)) |
349 { | 350 { |
350 alias BaseClassesTuple!(T)[0] Base; | 351 alias BaseClassesTuple!(T)[0] Base; |
351 base_ = meta!Base; | 352 base_ = meta!Base; |
352 | 353 |
353 next_ = base_.firstDerived_; | 354 next_ = base_.firstDerived_; |
354 base_.firstDerived_ = this; | 355 base_.firstDerived_ = this; |
355 } | 356 } |
356 classInfo_ = T.classinfo; | |
357 } | 357 } |
358 | 358 |
359 /** | 359 /** |
360 */ | 360 */ |
361 override string toString() const | 361 override string toString() const |
391 sharedM = M.create!symbol; | 391 sharedM = M.create!symbol; |
392 } | 392 } |
393 m = sharedM; | 393 m = sharedM; |
394 } | 394 } |
395 | 395 |
396 assert (m is sharedM); | |
397 return m; | 396 return m; |
398 } | |
399 | |
400 version (QtdUnittest) unittest | |
401 { | |
402 class A | |
403 { | |
404 } | |
405 | |
406 auto m = meta!A; | |
407 assert(m is meta!A); | |
408 } | 397 } |
409 | 398 |
410 /** | 399 /** |
411 */ | 400 */ |
412 // only classes and structs for now | 401 // only classes and structs for now |
436 private this(string name, AttributeOptions opts) | 425 private this(string name, AttributeOptions opts) |
437 { | 426 { |
438 super(name, opts); | 427 super(name, opts); |
439 } | 428 } |
440 | 429 |
441 static MetaVariantAttribute create(string name, AttributeOptions opts, A...)() | 430 static MetaVariantAttribute create(A...)(string name, AttributeOptions opts, A args) |
431 { | |
432 auto ret = new This(name, opts); | |
433 | |
434 foreach(i, _; A) | |
435 ret.values ~= Variant(args[i]); | |
436 | |
437 return ret; | |
438 } | |
439 } | |
440 | |
441 /** | |
442 A run-time attribute implementation that stores the attribute data in an | |
443 assiciative array of variants. | |
444 */ | |
445 class MetaVariantDictAttribute : MetaAttribute | |
446 { | |
447 Variant[string] values; | |
448 alias typeof(this) This; | |
449 | |
450 private this(string name, AttributeOptions opts) | |
451 { | |
452 super(name, opts); | |
453 } | |
454 | |
455 static This create(A...)(string name, AttributeOptions opts, A args) | |
442 { | 456 { |
443 auto ret = new This(name, opts); | 457 auto ret = new This(name, opts); |
444 foreach(i, _; A) | 458 foreach(i, _; A) |
445 { | 459 ret.values[args[i]] = Variant(args[i + 1]); // PHOBOS BUG: phobos asserts on this |
446 static if (__traits(compiles, { ret.values ~= Variant(A[i]); } )) | 460 |
447 ret.values ~= Variant(A[i]); | |
448 } | |
449 return ret; | 461 return ret; |
450 } | 462 } |
451 } | 463 } |
452 | 464 |
453 /** | |
454 A run-time attribute implementation that stores the attribute data in an | |
455 assiciative array of variants. | |
456 */ | |
457 class MetaVariantDictAttribute : MetaAttribute | |
458 { | |
459 Variant[string] values; | |
460 alias typeof(this) This; | |
461 | |
462 private this(string name, AttributeOptions opts) | |
463 { | |
464 super(name, opts); | |
465 } | |
466 | |
467 static This create(string name, AttributeOptions opts, A...)() | |
468 { | |
469 auto ret = new This(name, opts); | |
470 foreach(i, _; A) | |
471 { | |
472 static if (i % 2 == 0 && __traits(compiles, { ret.values[A[i]] = Variant(A[i + 1]); } )) | |
473 ret.values[A[i]] = Variant(A[i + 1]); // PHOBOS BUG: phobos asserts on this | |
474 } | |
475 return ret; | |
476 } | |
477 } | |
478 | |
479 version(QtdUnittest) unittest | 465 version(QtdUnittest) unittest |
480 { | 466 { |
467 enum x = 42; | |
481 static void foo() {} | 468 static void foo() {} |
482 | 469 |
483 static class C | 470 static class C |
484 { | 471 { |
485 mixin InnerAttribute!("variantAttribute", MetaVariantAttribute, "22", foo, 33); | 472 |
473 mixin InnerAttribute!("variantAttribute", MetaVariantAttribute, "22", x, 33); | |
474 | |
475 /+ PHOBOS BUG: variant is unusable with AAs | |
486 mixin InnerAttribute!("variantDictAttribute", MetaVariantDictAttribute, | 476 mixin InnerAttribute!("variantDictAttribute", MetaVariantDictAttribute, |
487 //"a", "33", // PHOBOS BUG: variant is unusable with AAs | 477 "a", "33", |
488 "b", foo | 478 "b", 44, |
489 //"c", 44 | 479 "c", x |
490 ); | 480 ); |
481 +/ | |
491 } | 482 } |
492 | 483 |
493 auto attrs = meta!(C).attributes; | 484 auto attrs = meta!(C).attributes; |
494 assert(attrs.length == 2); | 485 assert(attrs.length == 1); |
495 auto attr = cast(MetaVariantAttribute)attrs[0]; | 486 auto attr = cast(MetaVariantAttribute)attrs[0]; |
496 | 487 |
497 assert(attr.name == "variantAttribute"); | 488 assert(attr.name == "variantAttribute"); |
498 assert(attr.values[0] == "22"); | 489 assert(attr.values[0] == "22"); |
499 assert(attr.values[1] == 33); | 490 assert(attr.values[1] == x); |
491 assert(attr.values[2] == 33); | |
492 | |
493 /+ | |
500 | 494 |
501 auto attr2 = cast(MetaVariantDictAttribute) attrs[1]; | 495 auto attr2 = cast(MetaVariantDictAttribute) attrs[1]; |
502 assert(attr2.name == "variantDictAttribute"); | 496 assert(attr2.name == "variantDictAttribute"); |
503 //assert(attr2.values["a"] == "33"); | 497 //assert(attr2.values["a"] == "33"); |
504 //assert(attr2.values["c"] == 44); | 498 //assert(attr2.values["b"] == 44); |
505 } | 499 //assert(attr2.values["c"] == x); |
500 +/ | |
501 } |