#ifndef __arith_h__ #define __arith_h__ #include namespace MultiArrayTools { template struct ArgPack { template static inline auto mk(const Tuple& tp, As... as) -> decltype(ArgPack::template mk(tp)),As...>(tp, std::get(tp), as...)) { return ArgPack::template mk(tp)),As...>(tp, std::get(tp), as...); } template static inline auto mkd(const F& ff, const Tuple& tp, As... as) -> decltype(ArgPack::template mkd(tp)),As...>(ff, tp, std::get(tp), as...)) { return ArgPack::template mkd(tp)),As...>(ff, tp, std::get(tp), as...); } }; template <> struct ArgPack<0> { template static inline auto mk(const Tuple& tp, As... as) -> decltype(F::apply(std::get<0>(tp), as...)) { return F::apply(std::get<0>(tp), as...); } template static inline auto mkd(const F& ff, const Tuple& tp, As... as) -> decltype(ff(std::get<0>(tp), as...)) { return ff(std::get<0>(tp), as...); } }; template struct StaticFunctionBase { static constexpr bool FISSTATIC = true; typedef T value_type; template static auto mk(const Ops&... ops) -> Operation { return Operation(ops...); } static inline T apply(const std::tuple& arg) { return ArgPack::template mk >(arg); } }; // OPERATIONS (STATIC) template struct identity : public StaticFunctionBase, T> { //static constexpr bool FISSTATIC = true; using StaticFunctionBase, T>::apply; static inline T apply(T a) { return a; } }; 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, plusx, T, U> { static constexpr bool FISSTATIC = true; using StaticFunctionBase, plusx, T, U>::apply; static inline plusv 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, minusx, T, U> { static constexpr bool FISSTATIC = true; using StaticFunctionBase, minusx, T, U>::apply; static inline plusv apply(T a1, U a2) { return a1 - a2; } }; template struct multipliesx : public StaticFunctionBase, multipliesx, T, U> { static constexpr bool FISSTATIC = true; using StaticFunctionBase, multipliesx, T, U>::apply; static inline multipliesv apply(T a1, U a2) { return a1 * a2; } }; template struct dividesx : public StaticFunctionBase, dividesx, T, U> { static constexpr bool FISSTATIC = true; using StaticFunctionBase, dividesx, T, U>::apply; static inline dividesv apply(T a1, U a2) { return a1 / a2; } }; template using plus = plusx; template using minus = minusx; template using multiplies = multipliesx; template using divides = dividesx; /* template struct plus : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; using StaticFunctionBase, T, T>::apply; static inline T apply(T a1, T a2) { return a1 + a2; } static inline T& selfApply(T& a1, const T& a2) { return a1 += a2; } }; template struct minus : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; using StaticFunctionBase, T, T>::apply; static inline T apply(T a1, T a2) { return a1 - a2; } }; template struct multiplies : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; using StaticFunctionBase, T, T>::apply; static inline T apply(T a1, T a2) { return a1 * a2; } }; template struct divides : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; using StaticFunctionBase, T, T>::apply; static inline T apply(T a1, T a2) { return a1 / a2; } }; */ // 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...); } inline R operator()(const std::tuple& args) { return ArgPack::template mkd,std::tuple>>(mF, args); } }; #include #define regFunc1(fff) template \ struct x_##fff : public StaticFunctionBase, T> {\ static constexpr bool FISSTATIC = true;\ 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) { return a * x_ipow::apply(a); } }; template <> struct x_ipow<0> { static constexpr bool FISSTATIC = true; template static inline T apply(T a) { return a; } }; /* template struct dynamic_function { static constexpr bool FISSTATIC = false; template inline T apply(Us... args) { return f(args...); } }; */ } // end namespace MultiArrayHelper #endif