#ifndef __cxz_arith_h__ #define __cxz_arith_h__ #include namespace CNORXZ { //template template struct StaticFunctionBase { static constexpr bool FISSTATIC = true; typedef F function; //typedef typename F::value_type value_type; template static auto mk(const Ops&... ops); template static inline auto xapply(const Tuple& tp, As... as); template static inline auto apply(const std::tuple& arg); }; // OPERATIONS (STATIC) template struct identity : public StaticFunctionBase> { //static constexpr bool FISSTATIC = true; using StaticFunctionBase>::apply; typedef T value_type; static inline T apply(T a) { return a; } static inline T selfApply(T& a1, const T& a2) { return a1 = a2; } }; template using plusv = decltype(std::declval()+std::declval()); template using minusv = decltype(std::declval()-std::declval()); template using multipliesv = decltype(std::declval()*std::declval()); template using dividesv = decltype(std::declval()/std::declval()); template struct plusx : public StaticFunctionBase> { static constexpr bool FISSTATIC = true; using StaticFunctionBase>::apply; typedef plusv value_type; static inline value_type apply(T a1, U a2) { return a1 + a2; } static inline T& selfApply(T& a1, const T& a2) { return a1 += a2; } }; template struct minusx : public StaticFunctionBase> { static constexpr bool FISSTATIC = true; using StaticFunctionBase>::apply; typedef minusv value_type; static inline value_type apply(T a1, U a2) { return a1 - a2; } }; template struct multipliesx : public StaticFunctionBase> { static constexpr bool FISSTATIC = true; using StaticFunctionBase>::apply; typedef multipliesv value_type; static inline value_type apply(T a1, U a2) { return a1 * a2; } }; template struct dividesx : public StaticFunctionBase> { static constexpr bool FISSTATIC = true; using StaticFunctionBase>::apply; typedef dividesv value_type; static inline value_type apply(T a1, U a2) { return a1 / a2; } }; template struct negate : public StaticFunctionBase> { static constexpr bool FISSTATIC = true; using StaticFunctionBase>::apply; typedef T value_type; static inline T apply(T a) { return -a; } }; template using plus = plusx; template using minus = minusx; template using multiplies = multipliesx; template using divides = dividesx; // OPERATIONS (STATIC) template class function { public: static constexpr bool FISSTATIC = false; private: std::function mF; public: function() = default; function(const std::function& in) : mF(in) {} inline R operator()(const Args&... args) { return mF(args...); } template static inline auto xapply(const std::function& ff, const Tuple& tp, As... as) { if constexpr(N > 0){ return xapply(ff, tp, std::get(tp), as...); } else { return ff(std::get<0>(tp), as...); } } inline R operator()(const std::tuple& args) { return xapply(mF, args); } }; #include #define regFunc1(fff) template \ struct x_##fff : public StaticFunctionBase> {\ static constexpr bool FISSTATIC = true;\ typedef T value_type; \ static inline T apply(T a){\ return fff(a); } }; #include "extensions/math.h" #undef regFunc1 template struct x_ipow { static constexpr bool FISSTATIC = true; template static inline T apply(T a) { if constexpr(N > 0){ return a * x_ipow::apply(a); } else { return a; } } }; } // end namespace CNORXZInternal #include "arith.cc.h" #endif