From cb2db9c80d3a3224171e518d38baebd14850e17d Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Tue, 24 Oct 2023 02:01:29 +0200 Subject: [PATCH] add first slice tests + corresp fixes --- src/include/array/aindex.cc.h | 9 ++++- src/include/array/aindex.h | 1 + src/include/array/array_base.cc.h | 12 +++---- src/include/array/array_base.h | 4 ++- src/include/array/slice.cc.h | 40 +++++++++++++++++---- src/include/array/slice.h | 16 ++++++--- src/include/ranges/index_pack.cc.h | 6 ++++ src/include/ranges/index_pack.h | 2 ++ src/include/ranges/mrange.cc.h | 2 +- src/lib/ranges/index_pack.cc | 5 +++ src/lib/ranges/yrange.cc | 8 ++--- src/tests/marray_unit_test.cc | 56 ++++++++++++++++++++++++++++-- 12 files changed, 134 insertions(+), 27 deletions(-) diff --git a/src/include/array/aindex.cc.h b/src/include/array/aindex.cc.h index cfd7d7d..201a51b 100644 --- a/src/include/array/aindex.cc.h +++ b/src/include/array/aindex.cc.h @@ -19,6 +19,13 @@ namespace CNORXZ mCData(data) {} + template + AIndex::AIndex(const T* data, const AIndex& aindex) : + AIndex(aindex) + { + mCData = data; + } + template AIndex AIndex::operator+(Int n) const { @@ -55,7 +62,7 @@ namespace CNORXZ template BIndex::BIndex(T* data, const AIndex& ai) : - AIndex(data, ai.range(), ai.lex()), + AIndex(data, ai), mData(data) {} diff --git a/src/include/array/aindex.h b/src/include/array/aindex.h index f4d94b0..8a1e2fb 100644 --- a/src/include/array/aindex.h +++ b/src/include/array/aindex.h @@ -21,6 +21,7 @@ namespace CNORXZ DEFAULT_MEMBERS(AIndex); AIndex(const T* data, const RangePtr& range, SizeT lexpos = 0); AIndex(const T* data, const YIndex& yindex); + AIndex(const T* data, const AIndex& aindex); AIndex operator+(Int n) const; AIndex operator-(Int n) const; diff --git a/src/include/array/array_base.cc.h b/src/include/array/array_base.cc.h index fd9f3f4..0f5a11d 100644 --- a/src/include/array/array_base.cc.h +++ b/src/include/array/array_base.cc.h @@ -69,7 +69,7 @@ namespace CNORXZ { auto ai = itLexSave(begin); auto aj = itLexSave(end); - return std::make_shared(ai.prange(aj), this, ai.format(), ai.pos()); + return std::make_shared>(ai.prange(aj), this, ai.format(), ai.pos()); } template @@ -231,12 +231,12 @@ namespace CNORXZ template template - Sptr> ArrayBase::sl(const IndexInterface& i) + Sptr> ArrayBase::sl(const IndexInterface& begin, + const IndexInterface& end) { - auto beg = std::make_shared(this->cbegin()); - auto si = i.slice(beg); - auto it = *beg + i.lex(); - return std::make_shared(this, *si, it.pos()); + auto ai = itLexSave(begin); + auto aj = itLexSave(end); + return std::make_shared>(ai.prange(aj), this, ai.format(), ai.pos()); } template diff --git a/src/include/array/array_base.h b/src/include/array/array_base.h index cdf3c75..971a08f 100644 --- a/src/include/array/array_base.h +++ b/src/include/array/array_base.h @@ -91,6 +91,7 @@ namespace CNORXZ using CAB::end; using CAB::cbegin; using CAB::cend; + using CAB::sl; //using CAB::operator(); ArrayBase(const RangePtr& range); @@ -120,7 +121,8 @@ namespace CNORXZ inline decltype(auto) operator()(const DPack& pack); template - Sptr> sl(const IndexInterface& i); + Sptr> sl(const IndexInterface& begin, + const IndexInterface& end); virtual T* data() = 0; diff --git a/src/include/array/slice.cc.h b/src/include/array/slice.cc.h index 667414a..53078f3 100644 --- a/src/include/array/slice.cc.h +++ b/src/include/array/slice.cc.h @@ -12,7 +12,7 @@ namespace CNORXZ template CSlice::CSlice(const RangePtr& range, const CArrayBase* parent, - const Vector& blockSizes, SizeT off) : + const YFormat& blockSizes, SizeT off) : CArrayBase(range), mCParent(parent), mBlockSizes(blockSizes), @@ -28,13 +28,13 @@ namespace CNORXZ template typename CSlice::const_iterator CSlice::cbegin() const { - return const_iterator(YIndex(AB::mRange, mBlockSizes, 0)); + return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, 0)); } template typename CSlice::const_iterator CSlice::cend() const { - return const_iterator(YIndex(AB::mRange, mBlockSizes, AB::mRange->size())); + return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, AB::mRange->size())); } template @@ -49,15 +49,41 @@ namespace CNORXZ template Slice::Slice(const RangePtr& range, ArrayBase* parent, - const Vector& blockSizes, SizeT off) : - CSlice(range, parent, blockSizes, off), - mParent(parent) + const YFormat& blockSizes, SizeT off) : + ArrayBase(range), + mParent(parent), + mBlockSizes(blockSizes), + mOff(off) {} template T* Slice::data() { - return mParent->data(); + return mParent->data() + mOff; + } + + template + const T* Slice::data() const + { + return mParent->data() + mOff; + } + + template + typename Slice::const_iterator Slice::cbegin() const + { + return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, 0)); + } + + template + typename Slice::const_iterator Slice::cend() const + { + return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, AB::mRange->size())); + } + + template + bool Slice::isView() const + { + return true; } } diff --git a/src/include/array/slice.h b/src/include/array/slice.h index 42da2ef..6be5f53 100644 --- a/src/include/array/slice.h +++ b/src/include/array/slice.h @@ -16,13 +16,13 @@ namespace CNORXZ protected: const CArrayBase* mCParent = nullptr; - Vector mBlockSizes; + YFormat mBlockSizes; SizeT mOff = 0; public: DEFAULT_MEMBERS(CSlice); CSlice(const RangePtr& range, const CArrayBase* parent, - const Vector& blockSizes, SizeT off); + const YFormat& blockSizes, SizeT off); virtual const T* data() const override; virtual const_iterator cbegin() const override; @@ -31,22 +31,28 @@ namespace CNORXZ }; template - class Slice : public virtual ArrayBase, - public virtual CSlice + class Slice : public ArrayBase { public: typedef CArrayBase AB; + //typedef CSlice CS; typedef typename AB::const_iterator const_iterator; private: ArrayBase* mParent = nullptr; + YFormat mBlockSizes; + SizeT mOff = 0; public: DEFAULT_MEMBERS(Slice); Slice(const RangePtr& range, ArrayBase* parent, - const Vector& blockSizes, SizeT off); + const YFormat& blockSizes, SizeT off); + virtual const T* data() const override; virtual T* data() override; + virtual const_iterator cbegin() const override; + virtual const_iterator cend() const override; + virtual bool isView() const override final; }; } diff --git a/src/include/ranges/index_pack.cc.h b/src/include/ranges/index_pack.cc.h index 854d995..ac644e5 100644 --- a/src/include/ranges/index_pack.cc.h +++ b/src/include/ranges/index_pack.cc.h @@ -79,6 +79,12 @@ namespace CNORXZ get(CSizeT{})->lex() ; } + template + SizeT SPack::pos() const + { + return lex(); + } + /************************** * SPack (non-member) * **************************/ diff --git a/src/include/ranges/index_pack.h b/src/include/ranges/index_pack.h index 618cd5d..61cbf21 100644 --- a/src/include/ranges/index_pack.h +++ b/src/include/ranges/index_pack.h @@ -37,6 +37,7 @@ namespace CNORXZ decltype(auto) mkRange() const; SizeT lex() const; + SizeT pos() const; private: Tuple...> mIs; @@ -67,6 +68,7 @@ namespace CNORXZ DPack mul(const DPack& p) const; RangePtr mkRange() const; SizeT lex() const; + SizeT pos() const; private: Vector mIs; diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 4278acc..ebad77d 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -512,7 +512,7 @@ namespace CNORXZ decltype(auto) replaceFormat(const BT1& bs1, const Sptr>& gmi) { return iter<0,sizeof...(Indices)> - ( [&](auto i) { return std::get(gmi->pack()); }, + ( [&](auto i) { return gmi->pack()[CSizeT{}]; }, [&](const auto&... e) { return std::make_shared> ( bs1, e... ); } ); } diff --git a/src/lib/ranges/index_pack.cc b/src/lib/ranges/index_pack.cc index 1782aac..5ed6bc2 100644 --- a/src/lib/ranges/index_pack.cc +++ b/src/lib/ranges/index_pack.cc @@ -77,4 +77,9 @@ namespace CNORXZ } return o; } + + SizeT DPack::pos() const + { + return lex(); + } } diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index 8927a44..176e600 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -129,8 +129,8 @@ namespace CNORXZ IndexInterface>(i), mRange(rangeCast(i.range())), mIs(mkIndices()), - mFormat(mkFormat()), - mLexFormat(mkLexFormat()), + mFormat(i.mFormat), + mLexFormat(i.mLexFormat), mPMax(mkPMax()), mLMax(mkLMax()) { @@ -142,8 +142,8 @@ namespace CNORXZ IndexInterface>::operator=(i); mRange = rangeCast(i.range()); mIs = mkIndices(); - mFormat = mkFormat(); - mLexFormat = mkLexFormat(); + mFormat = i.mFormat; + mLexFormat = i.mLexFormat; mPMax = mkPMax(); mLMax = mkLMax(); return *this = i.lex(); diff --git a/src/tests/marray_unit_test.cc b/src/tests/marray_unit_test.cc index d0b5f50..a565438 100644 --- a/src/tests/marray_unit_test.cc +++ b/src/tests/marray_unit_test.cc @@ -12,7 +12,7 @@ namespace { using namespace CNORXZ; using Test::Numbers; - + class MA_1D_Test : public ::testing::Test { protected: @@ -52,7 +52,7 @@ namespace MArray mA; MArray mA2; }; - + TEST_F(MA_1D_Test, Basics) { auto crx = std::dynamic_pointer_cast(mCR1); @@ -69,6 +69,28 @@ namespace EXPECT_THROW({mA.at(ei);}, std::runtime_error); } + TEST_F(MA_1D_Test, Slice) + { + auto crx = std::dynamic_pointer_cast(mCR1); + auto beg = crx->begin() + 2; + auto last = crx->begin() + 5; + + //const auto& a = mA; + auto sl = mA.sl(beg,last); + EXPECT_EQ(sl->size(), last.lex()-beg.lex()+1); + + SizeT c = 0; + auto ii = crx->begin(); + for(auto i = sl->begin() ; i != sl->end(); ++i, ++c, ++ii){ + EXPECT_EQ(i.lex(), c); + EXPECT_EQ(ii.lex(), c); + EXPECT_EQ((*sl)[i], mA.data()[i.lex()+beg.lex()]); + EXPECT_EQ((*sl)[ii], mA.data()[i.lex()+beg.lex()]); + EXPECT_EQ(sl->at(i), mA.data()[i.lex()+beg.lex()]); + EXPECT_EQ(sl->at(ii), mA.data()[i.lex()+beg.lex()]); + } + } + TEST_F(MA_2D_Test, Basics) { const SizeT ssize = mStrMeta.size(); @@ -99,6 +121,36 @@ namespace } } + TEST_F(MA_2D_Test, Slice) + { + auto crx = std::dynamic_pointer_cast(mCR1); + auto beg = crx->begin() + 2; + auto last = crx->begin() + 5; + + auto uip1 = std::make_shared>(mUR1); + auto cip1 = std::make_shared(mCR1); + auto beg1 = (*cip1)+1; + auto last1 = (*cip1)+3; + auto beg2 = (*uip1)+2; + auto last2 = (*uip1)+5; + + auto sl = mA.sl(mindex(beg1*beg2),mindex(last1*last2)); + EXPECT_EQ(sl->size(), (last1.lex()-beg1.lex()+1)*(last2.lex()-beg2.lex()+1)); + + MIndex,PIndex>> mi(sl->range()); + EXPECT_EQ(mi.lmax().val(), sl->size()); + auto i1 = *mi.pack()[CSizeT<0>{}]; + auto i2 = *mi.pack()[CSizeT<1>{}]; + EXPECT_EQ(i1.lmax().val(), last1.lex()-beg1.lex()+1); + EXPECT_EQ(i2.lmax().val(), last2.lex()-beg2.lex()+1); + for(i1 = 0; i1.lex() != i1.lmax().val(); ++ i1){ + for(i2 = 0; i2.lex() != i2.lmax().val(); ++i2){ + const SizeT p = (i1.lex()+beg1.lex())*uip1->lmax().val() + i2.lex()+beg2.lex(); + EXPECT_EQ((*sl)[i1*i2], mA.data()[p]); + } + } + } + } // end namespace int main(int argc, char** argv)