1 module witchcraft.mixins.base;
2 
3 import std.meta;
4 
5 template TypeOfMeta(T)
6 {
7     import witchcraft;
8     
9     static if(is(T == class))
10     {
11         alias TypeOfMeta = Class;
12     } 
13     else static if(is(T == struct)) 
14     {
15         alias TypeOfMeta = Struct;
16     }
17     else static if(is(T == interface))
18     {
19         alias TypeOfMeta = InterfaceType;
20     }
21     else static if(!is(T)) 
22     {
23         alias TypeOfMeta = Module;
24     }
25     else
26     {
27         static assert(false); //todo: proper error
28     }
29 }
30 
31 mixin template Witchcraft() {
32     mixin Witchcraft!(typeof(this));
33 }
34 
35 mixin template Witchcraft(T)
36 {
37     import witchcraft;
38 
39     // alias T = typeof(this);
40 
41     mixin WitchcraftClass!T;
42     mixin WitchcraftConstructor!T;
43     mixin WitchcraftField!T;
44     mixin WitchcraftInterface!T;
45     mixin WitchcraftMethod!T;
46     mixin WitchcraftStruct!T;
47 
48     static if(is(T == class))
49     {
50         alias ImplTypeOfMeta = ClassMixin!(T);
51     }
52     else static if(is(T == struct))
53     {
54         alias ImplTypeOfMeta = StructMixin!(T);
55     } 
56     else static if(is(T == interface))
57     {
58         alias ImplTypeOfMeta = InterfaceTypeMixin!(T);
59     }
60     else static if(!is(T))
61     {
62         alias ImplTypeOfMeta = ModuleImpl!(__traits(parent, T));
63     }
64     else
65     {
66         static assert(false); //todo: proper error
67     }
68 
69     private static TypeOfMeta!(T) __typeinfoext;
70 
71     @property
72     static typeof(__typeinfoext) metaof()
73     {
74         if(__typeinfoext is null)
75         {
76             __typeinfoext = new ImplTypeOfMeta();
77         }
78 
79         return __typeinfoext;
80     }
81 
82     static if(__traits(compiles, typeof(super).metaof))
83     {
84         override typeof(__typeinfoext) getMetaType()
85         {
86             return T.metaof;
87         }
88     }
89     else static if(is(T))
90     {
91         typeof(__typeinfoext) getMetaType()
92         {
93             return T.metaof;
94         }
95     }
96     else
97     {
98         typeof(__typeinfoext) getMetaType()
99         {
100             return metaof;
101         }
102     }
103 }