diff --git a/src/include/base/types.h b/src/include/base/types.h index 5f3e658..616a652 100644 --- a/src/include/base/types.h +++ b/src/include/base/types.h @@ -215,7 +215,14 @@ namespace CNORXZ template using Vector = std::vector>; - + + template + struct Container + { typedef Vector type; }; + + template + struct Container + { typedef Arr type; }; } #endif diff --git a/src/include/operation/op_types.cc.h b/src/include/operation/op_types.cc.h index eb07e85..01a1ac9 100644 --- a/src/include/operation/op_types.cc.h +++ b/src/include/operation/op_types.cc.h @@ -18,7 +18,7 @@ namespace CNORXZ template constexpr decltype(auto) COpInterface::c(F&& f, const Sptr& ind) const { - return mkContraction(std::forward(f), THIS(), ind); + return mkContraction(std::forward(f), THIS().r(), ind); } template @@ -33,7 +33,7 @@ namespace CNORXZ template constexpr decltype(auto) COpInterface::o(F&& f, Args&&... args) const { - return Operation(std::forward(f), THIS(), args...); + return mkOperation(std::forward(f), THIS().r(), args...); } @@ -45,7 +45,7 @@ namespace CNORXZ template constexpr decltype(auto) OpInterface::ax(const Sptr& ind, F&& f, const Args&... args) { - return ind->ifor( Operation(f, THIS(), args...), NoF {} ); + return ind->ifor( mkOperation(f, OI::THIS().r(), args...), NoF {} ); } template @@ -126,11 +126,8 @@ namespace CNORXZ constexpr OpCont& OpCont::init(const Sptr& ind) { mIndex = ind; - if(not mC){ - mC = std::make_shared>(mIndex->pmax().val()); - } - else if(mC->size() != mIndex->pmax().val()){ - mC->resize(mIndex->pmax().val()); + if(mC.size() != mIndex->pmax().val()){ + mC.resize(mIndex->pmax().val()); } return *this; } @@ -140,12 +137,24 @@ namespace CNORXZ const Vector& c) { init(ind); - CXZ_ASSERT(c.size() == mC->size(), - "size-mismatch: expected " << mC->size() << ", got " << c.size()); - std::transform(c.begin(), c.end(), mC->begin(), [](const auto& x) { return x; } ); + CXZ_ASSERT(c.size() == mC.size(), + "size-mismatch: expected " << mC.size() << ", got " << c.size()); + std::transform(c.begin(), c.end(), mC.begin(), [](const auto& x) { return x; } ); return *this; } + template + constexpr decltype(auto) OpCont::r() + { + return OpRoot(data(), mIndex); + } + + template + constexpr decltype(auto) OpCont::r() const + { + return COpRoot(data(), mIndex); + } + template template constexpr OpCont& OpCont::operator=(const Op& o) @@ -175,23 +184,23 @@ namespace CNORXZ { if constexpr(is_epos_type::value){ if constexpr(pos_type_is_consecutive::value){ - return vreg(mC->data(),pos); + return vreg(mC.data(),pos); } else { // non-consecutive data cannot be directly accessed // so there is no non-const (write) access! - return vreg(const_cast(mC->data()),pos); + return vreg(const_cast(mC.data()),pos); } } else { - return (*mC)[pos.val()]; + return mC[pos.val()]; } } template constexpr decltype(auto) OpCont::operator()() const { - return (*mC)[0]; + return mC[0]; } template @@ -204,13 +213,13 @@ namespace CNORXZ template T* OpCont::data() { - return mC->data(); + return mC.data(); } template const T* OpCont::data() const { - return mC->data(); + return mC.data(); } /**************** @@ -343,6 +352,12 @@ namespace CNORXZ return ( std::get(mOps).rootSteps(id) << ... ); } + template + constexpr decltype(auto) mkOperation(F&& f, const Ops&... ops) + { + return Operation(std::forward(f), ops...); + } + /********************* * Contraction * diff --git a/src/include/operation/op_types.h b/src/include/operation/op_types.h index 57967f5..b622c80 100644 --- a/src/include/operation/op_types.h +++ b/src/include/operation/op_types.h @@ -20,6 +20,9 @@ namespace CNORXZ OpT& THIS() { return static_cast(*this); } const OpT& THIS() const { return static_cast(*this); } + constexpr decltype(auto) r() { return THIS(); } + constexpr decltype(auto) r() const { return THIS(); } + template constexpr decltype(auto) c(F&& f, const Sptr& ind) const; @@ -93,13 +96,18 @@ namespace CNORXZ { public: typedef OpInterface> OI; - + typedef typename Container::value, + index_has_const_size::value>::type CT; + constexpr OpCont() = default; constexpr OpCont(const Sptr& ind); constexpr OpCont& init(const Sptr& ind); constexpr OpCont& init(const Sptr& ind, const Vector& c); + constexpr decltype(auto) r(); + constexpr decltype(auto) r() const; + template constexpr OpCont& operator=(const Op& in); @@ -121,7 +129,7 @@ namespace CNORXZ private: Sptr mIndex; - Sptr> mC; + CT mC; }; @@ -193,6 +201,9 @@ namespace CNORXZ }; + template + constexpr decltype(auto) mkOperation(F&& f, const Ops&... ops); + template struct op_size> { static constexpr SizeT value = sizeof...(Ops); }; diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index 5746e9c..a8e02c4 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -74,6 +74,14 @@ namespace CNORXZ PtrId mPtrId = 0; }; + template + struct index_has_const_size + { static constexpr bool value = false; }; + + template + struct index_const_size + { static constexpr SizeT value = 0; }; + template IndexPtr& operator++(const IndexPtr& i); diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index 20249fe..bb57bd3 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -110,6 +110,13 @@ namespace CNORXZ //template //using MIndex = GMIndex; + template + struct index_has_const_size> + { static constexpr bool value = (index_has_const_size::value and ...); }; + + template + struct index_const_size> + { static constexpr SizeT value = (index_const_size::value * ...); }; template class MRangeFactory : public RangeFactoryBase diff --git a/src/tests/operation_unit_test.cc b/src/tests/operation_unit_test.cc index e80fbcb..39d3396 100644 --- a/src/tests/operation_unit_test.cc +++ b/src/tests/operation_unit_test.cc @@ -43,6 +43,35 @@ namespace COpRoot mOp4; }; + class OpCont_CR_CR_Test : public ::testing::Test + { + protected: + + OpCont_CR_CR_Test() + { + mSize1 = 7; + mSize2 = 11; + const SizeT off = 20; + mData1 = Numbers::get(off, mSize1); + mData2 = Numbers::get(off+mSize1, mSize2); + mData12 = Numbers::get(off+mSize1+mSize2, mSize1*mSize2); + auto cra = CRangeFactory(mSize1).create(); + auto crb = CRangeFactory(mSize2).create(); + } + + SizeT mSize1; + SizeT mSize2; + Vector mData1; + Vector mData2; + Vector mData12; + Sptr mCI1; + Sptr mCI2; + OpCont mOp1; + COpRoot mOp2; + OpCont mOp3; + COpRoot mOp4; + }; + TEST_F(OpCont_CR_Test, Basics) { EXPECT_EQ(mOp2.data(), mData1.data());