diff --git a/src/include/ranges/index_base.cc.h b/src/include/ranges/index_base.cc.h index 6f45c16..91cd6de 100644 --- a/src/include/ranges/index_base.cc.h +++ b/src/include/ranges/index_base.cc.h @@ -130,6 +130,13 @@ namespace CNORXZ { return std::make_shared>( *i - n ); } + + template + decltype(auto) operator*(const IndexInterface& a, + const IndexInterface& b) + { + return MIndex(a.THIS(),b.THIS()); + } } #endif diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index de56d77..5746e9c 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -87,6 +87,9 @@ namespace CNORXZ template IndexPtr operator-(const IndexPtr& i, Int n); + template + decltype(auto) operator*(const IndexInterface& a, + const IndexInterface& b); } #endif diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 4f5664d..74aede4 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -42,6 +42,22 @@ namespace CNORXZ } } + template + inline void GMIndex::mkPos() + { + mLex = iter<0,NI> + ([&](auto i) { return std::get(mIPack)->lex() * std::get(mLexBlockSizes).val(); }, + [](const auto&... e) { return (e + ...); }); + if constexpr(not std::is_same::value){ + IB::mPos = iter<0,NI> + ([&](auto i) { return std::get(mIPack)->pos() * std::get(mBlockSizes).val(); }, + [](const auto&... e) { return (e + ...); }); + } + else { + IB::mPos = mLex; + } + } + template template constexpr decltype(auto) GMIndex::mkLexBlockSizes(const IndexPack& ipack, Isq is) @@ -120,12 +136,12 @@ namespace CNORXZ IndexInterface,Tuple>(0), mRange(rangeCast(i.range())), mIPack(mkIPack(Isqr<0,NI>{})), - mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})), + mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})), mBlockSizes(i.mBlockSizes), mLMax(mkLMax(mIPack)), mPMax(mkPMax(mIPack,mBlockSizes)) { - *this = i.pos(); + *this = i.lex(); } template @@ -134,11 +150,37 @@ namespace CNORXZ IndexInterface,Tuple>::operator=(0); mRange = rangeCast(i.range()); mIPack = mkIPack(Isqr<0,NI>{}); - mLexBlockSizes = mkLexBlockSizes(mIPack,Isqr<0,NI-1>{}); + mLexBlockSizes = mkLexBlockSizes(mIPack,Isqr<1,NI>{}); mBlockSizes = i.mBlockSizes; mLMax = mkLMax(mIPack); mPMax = mkPMax(mIPack,mBlockSizes); - return *this = i.pos(); + return *this = i.lex(); + } + + template + constexpr GMIndex::GMIndex(const Indices&... is) : + IndexInterface,Tuple>(0), + mRange(std::dynamic_pointer_cast(mrange(is.range()...))), + mIPack(std::make_shared(is)...), + mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})), + mBlockSizes(), + mLMax(mkLMax(mIPack)), + mPMax(mkPMax(mIPack,mBlockSizes)) + { + mkPos(); + } + + template + constexpr GMIndex::GMIndex(const Sptr&... is) : + IndexInterface,Tuple>(0), + mRange(std::dynamic_pointer_cast(mrange(is->range()...))), + mIPack(is...), + mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})), + mBlockSizes(), + mLMax(mkLMax(mIPack)), + mPMax(mkPMax(mIPack,mBlockSizes)) + { + mkPos(); } template @@ -146,7 +188,7 @@ namespace CNORXZ IndexInterface,Tuple>(0), mRange(rangeCast(range)), mIPack(mkIPack(Isqr<0,NI>{})), - mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})), + mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})), mBlockSizes(), mLMax(mkLMax(mIPack)), mPMax(mkPMax(mIPack,mBlockSizes)) @@ -159,7 +201,7 @@ namespace CNORXZ IndexInterface,Tuple>(0), mRange(rangeCast(range)), mIPack(mkIPack(Isqr<0,NI>{})), - mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})), + mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})), mBlockSizes(blockSizes), mLMax(mkLMax(mIPack)), mPMax(mkPMax(mIPack,mBlockSizes)) diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index 6c051b0..85d0787 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -33,6 +33,8 @@ namespace CNORXZ constexpr GMIndex(const GMIndex& i); constexpr GMIndex& operator=(const GMIndex& i); + constexpr GMIndex(const Indices&... is); + constexpr GMIndex(const Sptr&... is); constexpr GMIndex(const RangePtr& range, SizeT lexpos = 0); constexpr GMIndex(const RangePtr& range, const BlockType& blockSizes, SizeT lexpos = 0); @@ -79,6 +81,8 @@ namespace CNORXZ static constexpr decltype(auto) mkPMax(const IndexPack& ipack, const BlockType& blockSizes); + inline void mkPos(); + template constexpr decltype(auto) mkIPack(Isq is) const; diff --git a/src/lib/ranges/range_base.cc b/src/lib/ranges/range_base.cc index 6401637..8441e22 100644 --- a/src/lib/ranges/range_base.cc +++ b/src/lib/ranges/range_base.cc @@ -83,8 +83,35 @@ namespace CNORXZ RangePtr operator*(const RangePtr& a, const RangePtr& b) { - //assert(0); // check segfault + "flatten" yrange (no yrange of yranges etc) - return YRangeFactory({a,b}).create(); + CXZ_ASSERT(a != nullptr, "first operand not initialized"); + CXZ_ASSERT(b != nullptr, "second operand not initialized"); + + Vector rvec; + rvec.reserve(a->dim() + b->dim()); + + if(a->sub(0) != nullptr){ + for(SizeT i = 0; i != a->dim(); ++i){ + CXZ_ASSERT(a->sub(i) != nullptr, + "sub range " << i << " of first operand not available"); + rvec.push_back(a->sub(i)); + } + } + else { + rvec.push_back(a); + } + + if(b->sub(0) != nullptr){ + for(SizeT i = 0; i != b->dim(); ++i){ + CXZ_ASSERT(b->sub(i) != nullptr, + "sub range " << i << " of second operand not available"); + rvec.push_back(b->sub(i)); + } + } + else { + rvec.push_back(b); + } + + return YRangeFactory(rvec).create(); } } // end namespace CNORXZ diff --git a/src/tests/darray_unit_test.cc b/src/tests/darray_unit_test.cc index cf31d54..99bf5ca 100644 --- a/src/tests/darray_unit_test.cc +++ b/src/tests/darray_unit_test.cc @@ -26,11 +26,30 @@ namespace RangePtr mCR1; }; + class DA_2D_Test : public ::testing::Test + { + protected: + + DA_2D_Test() + { + mSize = 5; + mStrMeta = { "another", "test", "string", "vector", "for", "this", "Test" }; + mCR1 = CRangeFactory(mSize).create(); + mUR1 = URangeFactory(mStrMeta).create(); + } + + SizeT mSize; + Vector mStrMeta; + RangePtr mCR1; + RangePtr mUR1; + }; + TEST_F(DA_1D_Test, Basics) { - DArray a(mCR1, ::CNORXZ::Test::Numbers::get(0,mSize)); + const DArray a(mCR1, ::CNORXZ::Test::Numbers::get(0,mSize)); auto crx = std::dynamic_pointer_cast(mCR1); EXPECT_EQ(a.size(), mSize); + EXPECT_FALSE(a.isView()); auto ei = crx->end(); EXPECT_EQ(ei.lex(), mSize); @@ -42,6 +61,27 @@ namespace EXPECT_THROW({a.at(ei);}, std::runtime_error); } + TEST_F(DA_2D_Test, Basics) + { + const SizeT ssize = mStrMeta.size(); + const SizeT size = mSize * ssize; + const DArray a(mCR1*mUR1, ::CNORXZ::Test::Numbers::get(0,size)); + EXPECT_EQ(a.range()->dim(), 2u); + EXPECT_EQ(a.size(), size); + EXPECT_EQ(a.pmax(), size); + EXPECT_EQ(a.range()->sub(0), mCR1); + EXPECT_EQ(a.range()->sub(1), mUR1); + auto cr1x = std::dynamic_pointer_cast(mCR1); + auto ur1x = std::dynamic_pointer_cast>(mUR1); + for(auto ci = cr1x->begin(); ci != cr1x->end(); ++ci){ + for(auto ui = ur1x->begin(); ui != ur1x->end(); ++ui){ + const SizeT p = ci.lex()*ssize + ui.lex(); + EXPECT_EQ((ci*ui).lex(), p); // test this in rutest!!! + EXPECT_EQ( a[ci*ui], a.data()[p] ); + } + } + } + } // end namespace int main(int argc, char** argv)