// // とりあえず入出力は全てint系 // マクロ化すれば3分の1くらいの長さには出来そうだけど保留 // namespace lmd { // int型を関数オブジェクトに直すためのフィルタ template struct val { val(V v) : v_(v) {} int operator()(int t) const { return v_; } const V v_; }; template struct tr { typedef V typ; }; template<> struct tr { typedef val typ; }; // 変数Xを表す struct var { int operator()(int t) const { return t; } }; // 足し算の実装 template struct plus { plus(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t)+b_(t); } typename A a_; typename B b_; }; template plus::typ,tr::typ> operator+( A a, B b ) { return plus::typ,tr::typ>(tr::typ(a),tr::typ(b)); } // 引き算の実装 template struct minus { minus(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t)-b_(t); } typename A a_; typename B b_; }; template minus::typ,tr::typ> operator-( A a, B b ) { return minus::typ,tr::typ>(tr::typ(a),tr::typ(b)); } // 掛け算の実装 template struct mult { mult(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t)*b_(t); } typename A a_; typename B b_; }; template mult::typ,tr::typ> operator*( A a, B b ) { return mult::typ,tr::typ>(tr::typ(a),tr::typ(b)); } // わり算の実装 template struct divi { divi(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t)/b_(t); } typename A a_; typename B b_; }; template divi::typ,tr::typ> operator/( A a, B b ) { return divi::typ,tr::typ>(tr::typ(a),tr::typ(b)); } // 剰余の実装 template struct modu { modu(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t)%b_(t); } typename A a_; typename B b_; }; template modu::typ,tr::typ> operator%( A a, B b ) { return modu::typ,tr::typ>(tr::typ(a),tr::typ(b)); } // !の実装 template struct not { not(A a) : a_(a) {} int operator()(int t) { return !a_(t); } typename A a_; }; template not::typ> operator!( A a ) { return not::typ>(tr::typ(a)); } // ==比較の実装 template struct eq { eq(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t)==b_(t); } typename A a_; typename B b_; }; template eq::typ,tr::typ> operator==( A a, B b ) { return eq::typ,tr::typ>(tr::typ(a),tr::typ(b)); } // !=の実装 template not< eq::typ,tr::typ> > operator!=( A a, B b ) { return !(a==b); } // < 比較の実装 template struct ls { ls(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t) ls::typ,tr::typ> operator<( A a, B b ) { return ls::typ,tr::typ>(tr::typ(a),tr::typ(b)); } // > 比較の実装 template ls::typ,tr::typ> operator>( A a, B b ) { return b < a; } // <= 比較の実装 template not::typ,tr::typ> > operator<=( A a, B b ) { return !(b < a); } // >= 比較の実装 template not::typ,tr::typ> > operator>=( A a, B b ) { return !(a < b); } // && の実装 template struct andand { andand(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t)&&b_(t); } typename A a_; typename B b_; }; template andand::typ,tr::typ> operator&&( A a, B b ) { return andand::typ,tr::typ>(tr::typ(a),tr::typ(b)); } // || の実装 template struct oror { oror(A a, B b) : a_(a), b_(b) {} int operator()(int t) { return a_(t)||b_(t); } typename A a_; typename B b_; }; template oror::typ,tr::typ> operator||( A a, B b ) { return oror::typ,tr::typ>(tr::typ(a),tr::typ(b)); } } namespace { static lmd::var X; }