謎's キッチン

謎のひとりごと。Amazon欲しい物リストはこちら: https://www.amazon.co.jp/hz/wishlist/ls/CCPOV7C6JTD2

Expression Template

d:id:niha経由。前回のパッチ(opcast_r2.diff)が必須。コメントアウトしてあるところはテンプレートでコンフリクトしてしまう所。もしdmdが通るように変更されたらうまく動くはず。定数が入れられないのは仕様。正確には静的オペレータオーバーロードが無いから。テンプレート挟めばできるけどそれじゃ意味ない(ぇ。

private import std.stdio;
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 func(TL...)(TL tl){
    return T.func!(TL)(tl) + U.func!(TL)(tl);
  }
}

class Sub(T,U):Exp!(T,U,Sub!(T,U)){
  static int func(TL...)(TL tl){
    return T.func!(TL)(tl) - U.func!(TL)(tl);
  }
}

class Mul(T,U):Exp!(T,U,Mul!(T,U)){
  static int func(TL...)(TL tl){
    return T.func!(TL)(tl) * U.func!(TL)(tl);
  }
}

class Div(T,U):Exp!(T,U,Div!(T,U)){
  static int func(TL...)(TL tl){
    return T.func!(TL)(tl) / U.func!(TL)(tl);
  }
}

class Mod(T,U):Exp!(T,U,Mod!(T,U)){
  static int func(TL...)(TL tl){
    return T.func!(TL)(tl) % U.func!(TL)(tl);
  }
}

class Base(T){
  static Optimize!(Add!(T,U)) opAdd(U)(){
    return null;
  }
/*  static Optimize!(Add!(T,U)) opAdd(U)(U u){
    return null;
  }*/
  static Optimize!(Sub!(T,U)) opSub(U)(){
    return null;
  }
/*  static Optimize!(Sub!(T,U)) opSub(U)(U u){
    return null;
  }*/
  static Optimize!(Mul!(T,U)) opMul(U)(){
    return null;
  }
/*  static Optimize!(Mul!(T,U)) opMul(U)(U u){
    return null;
  }*/
  static Optimize!(Div!(T,U)) opDiv(U)(){
    return null;
  }
/*  static Optimize!(Div!(T,U)) opDiv(U)(U u){
    return null;
  }*/
  static Optimize!(Mod!(T,U)) opMod(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 int func(TL...)(TL tl){
    return tl[t];
  }
}
alias _N!(0) _0;
alias _N!(1) _1;
alias _N!(2) _2;
alias _N!(3) _3;
alias _N!(4) _4;
alias _N!(5) _5;

void main(){
  writefln((_0*_1/_2).func(100,20,10));
//  writefln((_0*(_1/_2)).func(100,20,10));
  writefln((_0*typeof(_1/_2)).func(100,20,10));
}


優先順位はgdc側で勝手に調節してくれる。けどそれだと型じゃ無くて式になるからエラーになる…と。静的オペレータオーバーロードがあれば型で返せるから面倒な事にはならない…と。パッチを改良してみるかな。