1 /+ 2 dub.sdl: 3 name "methodtemplates" 4 dependency "openmethods" path="../" 5 buildType "x" { 6 buildOptions "debugMode" "debugInfo" "unittests" 7 debugVersions "explain" 8 } 9 10 buildType "xtc" { 11 buildOptions "debugMode" "debugInfo" "unittests" 12 debugVersions "explain" "traceCalls" 13 } 14 +/ 15 16 // -*- compile-command: "dub run --single --compiler ~/dev/d/dmd/generated/linux/release/64/dmd experimental/methodtemplates.d" -*- 17 18 19 module methodtemplates; 20 21 import openmethods; 22 mixin(registerMethods); 23 24 import bolts.experimental.refraction; 25 26 class Matrix(T) {} 27 class DenseMatrix(T) : Matrix!(T) {} 28 class DiagonalMatrix(T) : Matrix!(T) {} 29 30 template declareMatrixClasses(T) 31 { 32 mixin registerClasses!(Matrix!T); 33 mixin registerClasses!(DenseMatrix!T); 34 mixin registerClasses!(DiagonalMatrix!T); 35 } 36 37 mixin declareMatrixClasses!double; 38 39 import std.meta; 40 import std.traits; 41 42 void foo(virtual!Object); 43 //pragma(msg, typeof(&foo)); 44 45 Matrix!T times(T)(virtual!(Matrix!T), virtual!(Matrix!T)); 46 47 template InstantiateTemplateAt(alias Module, string name, int index, T...) { 48 alias TemplateAt = __traits(getOverloads, Module, name, true)[index]; 49 //pragma(msg, TemplateAt.stringof); 50 alias InstantiateTemplateAt = TemplateAt!(T); 51 } 52 53 Matrix!T times(T)(Matrix!T a, Matrix!T b) 54 { 55 return Method!( 56 InstantiateTemplateAt!(methodtemplates, "times", 0, T), 57 "times") 58 .dispatcher(a, b); 59 } 60 61 Method!( 62 InstantiateTemplateAt!(methodtemplates, "times", 0, T), 63 "times") 64 times(T)(MethodTag, Matrix!T a, Matrix!T b); 65 66 alias M = Method!( 67 InstantiateTemplateAt!(methodtemplates, "times", 0, int), 68 "times"); 69 70 // pragma(msg, Method!(typeof(×MM!double), "times").Original.mixture); 71 // pragma(msg, Method!(typeof(×MM!double), "times").Declaration); 72 73 //alias times(T) = methodLocator!(timesMM!T); 74 75 @method DenseMatrix!double _times(Matrix!double m1, Matrix!double m2) 76 { 77 return new DenseMatrix!double; 78 } 79 80 void main() 81 { 82 updateMethods; 83 { 84 Matrix!double m = new DenseMatrix!double(); 85 double s = 1; 86 // assert(typeid(times(m, s)) == typeid(DenseMatrix!double)); 87 // assert(typeid(times(s, m)) == typeid(DenseMatrix!double)); 88 assert(typeid(times(m, m)) == typeid(DenseMatrix!double)); 89 } 90 91 // { 92 // Matrix!double m = new DiagonalMatrix!double(); 93 // double s = 1; 94 // assert(typeid(times(m, s)) == typeid(DiagonalMatrix!double)); 95 // assert(typeid(times(s, m)) == typeid(DiagonalMatrix!double)); 96 // } 97 98 // Matrix!int m = new DenseMatrix!int(); 99 // int s = 1; 100 // assert(typeid(times(m, s)) == typeid(DenseMatrix!int)); 101 // assert(typeid(times(s, m)) == typeid(DenseMatrix!int)); 102 // } 103 }