静的演算オーバーロードに対応させてみた(opcast_r3.diff)が、templateが型を返すとうまく動かない。まぁ想定外な状況になるので当り前っていったら当り前だけどちょっと残念。
まぁ逆に全部インスタンスすれば問題ないのだろうけど、もともとopcast_rのパッチで何ができるか…っていうことだったので拘ってたんだけど。取り合えずインスタンスver
private import std.stdio,std.traits; class Exp(T,U,V):Base!(V){ alias U current;//currentにExpがくる事もあり alias T before; } class Add(T,U):Exp!(T,U,Add!(T,U)){ static int opCall(TL...)(TL tl){//戻り値の部分の段階ではtlが定義されてない return T.opCall!(TL)(tl) + U.opCall!(TL)(tl); } } class Sub(T,U):Exp!(T,U,Sub!(T,U)){ static int opCall(TL...)(TL tl){ return T.opCall!(TL)(tl) - U.opCall!(TL)(tl); } } class Mul(T,U):Exp!(T,U,Mul!(T,U)){ static int opCall(TL...)(TL tl){ return T.opCall!(TL)(tl) * U.opCall!(TL)(tl); } } class Div(T,U):Exp!(T,U,Div!(T,U)){ static int opCall(TL...)(TL tl){ return T.opCall!(TL)(tl) / U.opCall!(TL)(tl); } } class Mod(T,U):Exp!(T,U,Mod!(T,U)){ static int opCall(TL...)(TL tl){ return T.opCall!(TL)(tl) % U.opCall!(TL)(tl); } } class Base(T){ static Optimize!(Add!(T,U)) opAdd(U)(U u){ return null; } static Optimize!(Sub!(T,U)) opSub(U)(U u){ return null; } static Optimize!(Mul!(T,U)) opMul(U)(U u){ return null; } static Optimize!(Div!(T,U)) opDiv(U)(U u){ return null; } static Optimize!(Mod!(T,U)) opMod(U)(U u){ return null; } } template Optimize(T){ //todo: 最適化するべき alias T Optimize; } class __N(int t):Base!(__N!(t)){ static TL[t] opCall(TL...)(TL tl){ return tl[t]; } } template _N(int i){ __N!(i) _N; } alias _N!(0) _0; alias _N!(1) _1; alias _N!(2) _2; alias _N!(3) _3; alias _N!(4) _4; alias _N!(5) _5; class value(T...):Base!(value!(T)){ static typeof(T[0]) opCall(TL...)(TL tl){ return T[0]; } } template _(T...){ value!(T) _; } class _func(alias F,UL...):Base!(_func!(F,UL)){ static ReturnType!(F) opCall(TL...)(TL tl){ ParameterTypeTuple!(F) ul; foreach(i,U;UL){ ul[i]=UL[i].opCall!(TL)(tl); } return F(ul); } } class f(alias F){ static _func!(F,UL) opCall(UL...)(UL ul){ return null; } } int func(int a, int b, int c){ return a+b*c; } void main(){ auto test=_0*_1/_2; writefln(test(100,20,10)); writefln((test*test+_!(18))(100,20,10)); // writefln((test*test+f!(func)(_!(10),_0))(100,20,10));//何故かコンパイラがクラッシュ writefln(f!(func)(_1,_0,_!(2))(2,3)); }