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 }