1 
2 module witchcraft.mixins.structs;
3 
4 mixin template WitchcraftStruct(T)
5 {
6     import witchcraft;
7 
8     import std.meta;
9     import std.traits;
10 
11     static class StructMixin(T) : Struct
12     if(is(T == struct))
13     {
14         this()
15         {
16             foreach(name; FieldNameTuple!T)
17             {
18                 _fields[name] = new FieldMixin!(T, name);
19             }
20 
21             foreach(name; __traits(derivedMembers, T))
22             {
23                 static if(is(typeof(__traits(getMember, T, name)) == function))
24                 {
25                     static if(name != "__ctor" && name != "__dtor")
26                     {
27                         foreach(index, overload; __traits(getOverloads, T, name))
28                         {
29                             _methods[name] ~= new MethodMixin!(T, name, index);
30                         }
31                     }
32                 }
33             }
34         }
35 
36         const(Attribute)[] getAttributes() const
37         {
38             alias attributes = AliasSeq!(__traits(getAttributes, T));
39             auto values = new Attribute[attributes.length];
40 
41             foreach(index, attribute; attributes)
42             {
43                 values[index] = new AttributeImpl!attribute;
44             }
45 
46             return values;
47         }
48 
49         override const(Constructor)[] getConstructors() const
50         {
51             static if(__traits(hasMember, T, "__ctor"))
52             {
53                 alias constructors = AliasSeq!(__traits(getOverloads, T, "__ctor"));
54                 auto values = new Constructor[constructors.length];
55 
56                 foreach(index, constructor; constructors)
57                 {
58                     values[index] = new ConstructorMixin!(T, index);
59                 }
60 
61                 return values;
62             }
63             else
64             {
65                 return [ ];
66             }
67         }
68 
69         const(Type) getDeclaringType() const
70         {
71             alias Parent = Alias!(__traits(parent, T));
72 
73             return inspect!Parent;
74         }
75 
76         const(TypeInfo) getDeclaringTypeInfo() const
77         {
78             alias Parent = Alias!(__traits(parent, T));
79 
80             static if(__traits(compiles, typeid(Parent)))
81             {
82                 return typeid(Parent);
83             }
84             else
85             {
86                 return null;
87             }
88         }
89 
90         string getFullName() const
91         {
92             return fullyQualifiedName!T;
93         }
94 
95         string getName() const
96         {
97             return T.stringof;
98         }
99 
100         string getProtection() const
101         {
102             return __traits(getProtection, T);
103         }
104 
105         override const(TypeInfo) getTypeInfo() const
106         {
107             return typeid(T);
108         }
109 
110         @property
111         final bool isAccessible() const
112         {
113             return true;
114         }
115     }
116 }