diff --git a/src/include/allocator.h b/src/include/allocator.h index 2cfdd2c..aaff744 100644 --- a/src/include/allocator.h +++ b/src/include/allocator.h @@ -68,7 +68,7 @@ namespace MultiArrayTools { template using vector = std::vector>; - + } // namespace MultiArrayTools #endif diff --git a/src/include/map_range.h b/src/include/map_range.h index 2bc9642..a67f350 100644 --- a/src/include/map_range.h +++ b/src/include/map_range.h @@ -38,10 +38,11 @@ namespace MultiArrayTools class OpExpr { public: + typedef decltype(mkMapOp(std::declval(), std::declval())) Op; typedef SingleIndex OIType; //typedef typename MapF::IndexPack IndexPack; static constexpr size_t LAYER = Expr::LAYER + 1; - static constexpr size_t SIZE = Expr::SIZE; + static constexpr size_t SIZE = Expr::SIZE + Op::SIZE; private: OpExpr() = default; @@ -51,8 +52,6 @@ namespace MultiArrayTools size_t mMax; size_t mStep; Expr mExpr; - - typedef decltype(mkMapOp(std::declval(), std::declval())) Op; Op mOp; typedef decltype(mOp.rootSteps(std::declval()).extend( mExpr.rootSteps(std::declval()) )) ExtType; diff --git a/src/include/multi_array_operation.cc.h b/src/include/multi_array_operation.cc.h index e69f66e..cee7635 100644 --- a/src/include/multi_array_operation.cc.h +++ b/src/include/multi_array_operation.cc.h @@ -346,6 +346,7 @@ namespace MultiArrayTools auto OperationRoot::assign(const OpClass& in) -> decltype(mIndex.ifor(1,in.loop(AssignmentExpr(mOrigDataPtr,in)))) { + static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" ); return mIndex.ifor(1,in.loop(AssignmentExpr(mOrigDataPtr,in))); } @@ -354,6 +355,7 @@ namespace MultiArrayTools auto OperationRoot::plus(const OpClass& in) -> decltype(mIndex.ifor(1,in.loop(AddExpr(mOrigDataPtr,in)))) { + static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" ); return mIndex.ifor(1,in.loop(AddExpr(mOrigDataPtr,in))); } @@ -556,9 +558,9 @@ namespace MultiArrayTools } template - MExt OperationValue::rootSteps(std::intptr_t iPtrNum) const + None OperationValue::rootSteps(std::intptr_t iPtrNum) const { - return MExt(0); + return None(); } template diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h index 0cd01ad..9691b82 100644 --- a/src/include/multi_array_operation.h +++ b/src/include/multi_array_operation.h @@ -388,7 +388,7 @@ namespace MultiArrayTools typedef ContainerRange CRange; typedef ContainerIndex IndexType; - static constexpr size_t SIZE = 1; + static constexpr size_t SIZE = 0; static constexpr bool CONT = true; OperationValue(const T& val); @@ -399,7 +399,7 @@ namespace MultiArrayTools template inline OperationValue& set(ET pos); - MExt rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype + None rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype template Expr loop(Expr exp) const; diff --git a/src/include/pack_num.h b/src/include/pack_num.h index d369b17..590246c 100644 --- a/src/include/pack_num.h +++ b/src/include/pack_num.h @@ -74,7 +74,7 @@ namespace MultiArrayHelper static inline T mkOpExpr(std::shared_ptr f, const ETuple& pos, const OpTuple& ops, Args... args) { typedef typename std::remove_reference(ops))>::type NextOpType; - static_assert(LAST > NextOpType::SIZE, "inconsistent array positions"); + static_assert(LAST >= NextOpType::SIZE, "inconsistent array positions"); static constexpr size_t NEXT = LAST - NextOpType::SIZE; typedef decltype(std::get(ops).get(Getter::template getX( pos ))) ArgT; return PackNum::template mkOpExpr diff --git a/src/include/xfor/exttype.h b/src/include/xfor/exttype.h index 918ed6c..31dbcdd 100644 --- a/src/include/xfor/exttype.h +++ b/src/include/xfor/exttype.h @@ -52,7 +52,8 @@ namespace MultiArrayHelper public: - static constexpr size_t NUM = X::NUM + 1; + static constexpr size_t NUM = X::SIZE; + static constexpr size_t SIZE = NUM + 1; MExt() = default; MExt(const MExt& in) = default; @@ -71,6 +72,9 @@ namespace MultiArrayHelper template inline MExt(const std::array& arr); + template + inline MExt(const MExt& y); + inline const size_t& val() const; inline const X& next() const; @@ -88,6 +92,27 @@ namespace MultiArrayHelper }; + struct None + { + None() = default; + None(const None& in) = default; + None(None&& in) = default; + None& operator=(const None& in) = default; + None& operator=(None&& in) = default; + + template + None(const Y& y) {} + + static constexpr size_t SIZE = 0; + + inline None operator+(const None& in) const { return None(); } + inline None operator*(size_t in) const { return None(); } + + template + Y extend(const Y& y) const + { return y; } + }; + template <> class MExt { @@ -98,7 +123,8 @@ namespace MultiArrayHelper public: static constexpr size_t NUM = 0; - + static constexpr size_t SIZE = NUM + 1; + MExt() = default; MExt(const MExt& in) = default; MExt& operator=(const MExt& in) = default; @@ -107,17 +133,24 @@ namespace MultiArrayHelper inline MExt(size_t ext); + inline MExt(size_t y, const None& z) : mExt(y) {} + template inline MExt(size_t y, const Z& z); - + + + template inline MExt(const Y& y, const Z& z); template inline MExt(const std::array& arr); + template + inline MExt(const MExt& y); + inline const size_t& val() const; - inline size_t next() const { return 0; } + inline None next() const { return None(); } template inline auto nn() const @@ -161,7 +194,12 @@ namespace MultiArrayHelper template inline MExt::MExt(const Y& y, const Z& z) : mExt(y.val()), mNext(y.next(), z) {} - + + template + template + inline MExt::MExt(const MExt& y) : + mExt(y.val()), mNext(y.next()) {} + template inline const size_t& MExt::val() const { @@ -207,6 +245,10 @@ namespace MultiArrayHelper inline MExt::MExt(const std::array& arr) : mExt(std::get(arr)) {} + template + inline MExt::MExt(const MExt& y) : + mExt(y.val()) {} + //template <> inline const size_t& MExt::val() const {