1 2 module witchcraft.aggregates; 3 4 import witchcraft; 5 6 import std.algorithm; 7 import std.array; 8 import std.range; 9 10 abstract class Aggregate : Type 11 { 12 /++ 13 + Looks up and returns a constructor with a parameter list that exactly 14 + matches the given array of types. 15 + 16 + Params: 17 + parameterTypes = A parameter list the constructor must exactly match. 18 + 19 + Returns: 20 + The constructor object, or null if no such constructor exists. 21 ++/ 22 final const(Constructor) getConstructor(Type[] parameterTypes...) const 23 { 24 // Iterate up the inheritance tree. 25 return getConstructors.retro 26 .filter!(c => c.getParameterTypes == parameterTypes) 27 .takeOne 28 .chain(null.only) 29 .front; 30 } 31 32 /++ 33 + Looks up and returns a constructor with a parameter list that exactly 34 + matches the given array of types. 35 + 36 + Params: 37 + parameterTypeInfos = A parameter list the constructor must exactly match. 38 + 39 + Returns: 40 + The constructor object, or null if no such constructor exists. 41 ++/ 42 final const(Constructor) getConstructor(TypeInfo[] parameterTypeInfos) const 43 { 44 // Iterate up the inheritance tree. 45 return getConstructors.retro 46 .filter!(c => c.getParameterTypeInfos == parameterTypeInfos) 47 .takeOne 48 .chain(null.only) 49 .front; 50 } 51 52 /++ 53 + Ditto, but accepts types given by variadic template arguments. 54 + 55 + Params: 56 + TList = A list of types the constructor must exactly match. 57 + 58 + Returns: 59 + The constructor object, or null if no such constructor exists. 60 ++/ 61 final const(Constructor) getConstructor(TList...)() const 62 { 63 auto types = new TypeInfo[TList.length]; 64 65 foreach(index, type; TList) 66 { 67 types[index] = typeid(type); 68 } 69 70 return this.getConstructor(types); 71 } 72 73 /++ 74 + Returns an array of all constructors defined by this type. 75 + This does not include the default constructor. 76 + 77 + If a type declares no constructors, this method will return an empty 78 + array. 79 + 80 + Returns: 81 + And array of all constructors on the aggregate type. 82 ++/ 83 abstract const(Constructor)[] getConstructors() const; 84 85 @property 86 final override bool isAggregate() const 87 { 88 return true; 89 } 90 }