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(&timesMM!double), "times").Original.mixture);
71 // pragma(msg, Method!(typeof(&timesMM!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 }