diff --git a/src/include/multi_array_operation.cc.h b/src/include/multi_array_operation.cc.h index da2ecbb..e3f578a 100644 --- a/src/include/multi_array_operation.cc.h +++ b/src/include/multi_array_operation.cc.h @@ -245,9 +245,10 @@ namespace MultiArrayTools } template - auto MOp::rootSteps(std::intptr_t iPtrNum) const -> ExtType + auto MOp::rootSteps(std::intptr_t iPtrNum) const { - return RootSumN::rootSteps(mOps,iPtrNum); + return MA_SCFOR(i,0,sizeof...(Ops),i+1,std::get(mOps).rootSteps(iPtrNum),extend); + //return RootSumN::rootSteps(mOps,iPtrNum); } template @@ -1011,17 +1012,15 @@ namespace MultiArrayTools template auto Operation::rootSteps(std::intptr_t iPtrNum) const - -> decltype(PackNum::mkSteps(iPtrNum, mOps)) { - return PackNum::mkSteps(iPtrNum, mOps); + return MA_SCFOR(i,0,sizeof...(Ops),i+1,std::get(mOps).rootSteps(iPtrNum),extend); } template template auto Operation::loop(Expr exp) const - -> decltype(PackNum::mkLoop( mOps, exp )) { - return PackNum::mkLoop( mOps, exp ); + return MA_SCRAFOR(i,sizeof...(Ops),0,i-1,std::get(mOps),loop,exp); } diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h index 7837db6..e9ff90f 100644 --- a/src/include/multi_array_operation.h +++ b/src/include/multi_array_operation.h @@ -20,6 +20,8 @@ #include "xfor/xfor.h" #include "type_operations.h" +#include "statics/static_for.h" + namespace MultiArrayTools { @@ -105,11 +107,6 @@ namespace MultiArrayTools template struct RootSumN { - template - struct rs - { - static constexpr size_t SIZE = Op1::SIZE + RootSumN::template rs::SIZE; - }; template static inline auto rootSteps(const std::tuple& etp, std::intptr_t i) @@ -142,11 +139,6 @@ namespace MultiArrayTools template <> struct RootSumN<0> { - template - struct rs - { - static constexpr size_t SIZE = Op1::SIZE; - }; template static inline auto rootSteps(const std::tuple& etp, std::intptr_t i) @@ -175,14 +167,6 @@ namespace MultiArrayTools }; - template - struct RootSum - { - //static constexpr size_t SIZE = (... + Ops::SIZE); - static constexpr size_t SIZE = RootSumN::template rs::SIZE; - }; - - template struct SelfIdentity { @@ -271,46 +255,6 @@ namespace MultiArrayTools template using IVPlus = IVAccess>; - /* - struct IAssign - { - template - static inline void f(T*& t, size_t pos, const Op& op, ExtType e) - { - t[pos] = op.get(e); - } - }; - - template - struct IVAssign - { - template - static inline void f(T*& t, size_t pos, const Op& op, ExtType e) - { - reinterpret_cast(t)[pos] = op.template vget(e); - } - }; - - struct IPlus - { - template - static inline void f(T*& t, size_t pos, const Op& op, ExtType e) - { - t[pos] += op.get(e); - } - }; - - template - struct IVPlus - { - template - static inline void f(T*& t, size_t pos, const Op& op, ExtType e) - { - reinterpret_cast(t)[pos] += op.template vget(e); - } - }; - */ - template class AssignmentExpr : public ExpressionBase @@ -366,7 +310,7 @@ namespace MultiArrayTools public: static constexpr size_t LAYER = 0; static constexpr size_t NHLAYER = 0; - static constexpr size_t SIZE = RootSum::SIZE; + static constexpr size_t SIZE = (... + Ops::SIZE); typedef decltype(RootSumN::rootSteps(mOps,0) ) ExtType; MOp(const Ops&... exprs); @@ -382,7 +326,7 @@ namespace MultiArrayTools inline size_t vget(ExtType last) const { return get(last); } inline MOp& set(ExtType last); - auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType; + auto rootSteps(std::intptr_t iPtrNum = 0) const; template auto loop(Expr exp) const @@ -821,18 +765,6 @@ namespace MultiArrayTools T const** data() const { assert(0); return nullptr; } }; - - template - inline constexpr bool isVAble() - { - return Op::VABLE and std::is_same::value; - } - - template - inline constexpr bool isVAble() - { - return Op1::VABLE and std::is_same::value and isVAble(); - } template class Operation : public OperationTemplate > @@ -843,17 +775,17 @@ namespace MultiArrayTools typedef OperationBase > OT; typedef OpFunction F; - static constexpr size_t SIZE = RootSum::SIZE; + static constexpr size_t SIZE = (... + Ops::SIZE); static constexpr bool FISSTATIC = OpFunction::FISSTATIC; static constexpr bool CONT = false; - static constexpr bool VABLE = isVAble(); + static constexpr bool VABLE = + (... and (Ops::VABLE and std::is_same::value)); private: std::tuple mOps; std::shared_ptr mF; // only if non-static public: - typedef decltype(PackNum::template mkSteps(0, mOps)) ETuple; Operation(const Ops&... ops); Operation(std::shared_ptr ff, const Ops&... ops); @@ -867,49 +799,25 @@ namespace MultiArrayTools template inline Operation& set(ET pos); - auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype - -> decltype(PackNum::mkSteps(iPtrNum, mOps)); + auto rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype template - auto loop(Expr exp) const - -> decltype(PackNum::mkLoop( mOps, exp)); + auto loop(Expr exp) const; T* data() const { assert(0); return nullptr; } }; - - namespace - { - template - struct OpMaker - { - template - static inline auto mkOperation(const std::shared_ptr& f, const Ops&... ops) - -> Operation - { - return Operation(f,ops...); - } - }; - - template <> - struct OpMaker - { - template - static inline auto mkOperation(const std::shared_ptr& f, const Ops&... ops) - -> Operation - { - return Operation(ops...); - } - }; - - } template auto mkOperation(const std::shared_ptr& f, const Ops&... ops) -> Operation { - return OpMaker::mkOperation(f, ops...); + if constexpr(OpFunction::FISSTATIC){ + return Operation(ops...); + } + else { + return Operation(f,ops...); + } } - template class Contraction : public OperationTemplate > diff --git a/src/include/statics/static_for.h b/src/include/statics/static_for.h index abc0c87..a8c21a1 100644 --- a/src/include/statics/static_for.h +++ b/src/include/statics/static_for.h @@ -7,7 +7,7 @@ namespace MultiArrayTools { - template + template struct sfor { template @@ -15,25 +15,46 @@ namespace MultiArrayTools { constexpr auto idx = std::integral_constant{}; constexpr auto idxm = std::integral_constant{}; - static_assert(abs(idx.value - END) >= abs(incr(idx) - END), - "this turns out to be a static endless loop"); + //static_assert(abs(idx.value - END) >= abs(incr(idx) - END), + // "this turns out to be a static endless loop"); auto tmp = f(idxm); - return conc(tmp, static_for::exec(incr,f,conc)); + if constexpr(incr(idx) == END){ + return tmp; + } + else { + return conc(tmp, sfor::exec(incr,f,conc)); + } } - + + template + static inline auto exec(Incr incr, F f, Conc conc, const Arg& arg) + { + constexpr auto idx = std::integral_constant{}; + constexpr auto idxm = std::integral_constant{}; + //static_assert(abs(idx.value - END) >= abs(incr(idx) - END), + // "this turns out to be a static endless loop"); + auto tmp = f(idxm); + if constexpr(incr(idx) == END){ + return conc(tmp, arg); + } + else { + return conc(tmp, sfor::exec(incr,f,conc,arg)); + } + } + template static inline auto unpack(Incr incr, F f, Create create, const Args&... args) { constexpr auto idx = std::integral_constant{}; constexpr auto idxm = std::integral_constant{}; - static_assert(abs(idx.value - END) >= abs(incr(idx) - END), - "this turns out to be a static endless loop"); + //static_assert(abs(idx.value - END) >= abs(incr(idx) - END), + // "this turns out to be a static endless loop"); auto tmp = f(idxm); - return static_for::unpack(incr, f, create, args..., tmp); + return sfor::unpack(incr, f, create, args..., tmp); } }; - template + template struct sfor { template @@ -50,8 +71,11 @@ namespace MultiArrayTools }; } -#define MA_SFOR(i,beg,end,incr,expr) static_for::exec([&](auto i) constexpr { return incr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; }) -#define MA_SRFOR(i,beg,end,decr,expr) static_for::exec([&](auto i) constexpr { return decr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; }) -#define MA_CFOR(i,beg,end,incr,expr,cre) static_for::unpack([&](auto i) constexpr { return incr; }, [&](auto i){ expr }, [&](auto... args) { return cre(args...); }) +#define MA_SFOR(i,beg,end,incr,expr) sfor::exec([&](auto i) constexpr { return incr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; }) +#define MA_SCFOR(i,beg,end,incr,expr,conc) sfor::exec([&](auto i) constexpr { return incr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); }) +#define MA_SRFOR(i,beg,end,decr,expr) sfor::exec([&](auto i) constexpr { return decr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; }) +#define MA_SCRFOR(i,beg,end,decr,expr,conc) sfor::exec([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); }) +#define MA_SCRAFOR(i,beg,end,decr,expr,conc,arg) sfor::exec([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); }, arg) +#define MA_CFOR(i,beg,end,incr,expr,cre) sfor::unpack([&](auto i) constexpr { return incr; }, [&](auto i){ expr }, [&](auto... args) { return cre(args...); }) #endif