diff --git a/src/container_range.cc b/src/container_range.cc index b124652..8e48c59 100644 --- a/src/container_range.cc +++ b/src/container_range.cc @@ -34,7 +34,8 @@ namespace MultiArrayTools template template - ContainerIndex::ContainerIndex(const std::shared_ptr& range) + ContainerIndex::ContainerIndex(const std::shared_ptr& range) : + IndexInterface >(range, 0) { PackNum::construct(mIPack, *range); IB::mPos = PackNum::makePos(mIPack); @@ -93,24 +94,31 @@ namespace MultiArrayTools } template - size_t ContainerIndex::pos() const + ContainerIndex& ContainerIndex::sync() { if(mExternControl){ IB::mPos = PackNum::makePos(mIPack); } - return IB::mPos; + return *this; } - + + template + template + auto ContainerIndex::get() const -> decltype( *std::get( mIPack ) )& + { + return *std::get( mIPack ); + } + template bool ContainerIndex::first() const { - return pos() == 0; + return IB::pos() == 0; } template bool ContainerIndex::last() const { - return pos() == IB::mRangePtr->size() - 1; + return IB::pos() == IB::mRangePtr->size() - 1; } @@ -119,8 +127,14 @@ namespace MultiArrayTools { PackNum::swapIndices(mIPack, inds...); mExternControl = true; - return *this; + return sync(); } + + template + ContainerIndex& ContainerIndex::operator()() + { + return sync(); + } /***************************** * ContainerRangeFactory * @@ -169,6 +183,20 @@ namespace MultiArrayTools return PackNum::getSize(mSpace); } + template + template + auto ContainerRange::get() const -> decltype( *std::get( mSpace ) )& + { + return *std::get( mSpace ); + } + + template + template + auto ContainerRange::getPtr() const -> decltype( std::get( mSpace ) )& + { + return std::get( mSpace ); + } + template typename ContainerRange::IndexType ContainerRange::begin() const { @@ -188,7 +216,7 @@ namespace MultiArrayTools i = size(); return i; } - + template std::shared_ptr ContainerRange::index() const { diff --git a/src/container_range.h b/src/container_range.h index 820d26b..473231d 100644 --- a/src/container_range.h +++ b/src/container_range.h @@ -48,10 +48,16 @@ namespace MultiArrayTools virtual bool last() const override; virtual size_t dim() const override; - virtual size_t pos() const override; // recalculate when externalControl == true + + ContainerIndex& sync(); // recalculate 'IB::mPos' when externalControl == true + + template + auto get() const -> decltype( *std::get( mIPack ) )&; ContainerIndex& operator()(const std::shared_ptr&... inds); // control via external indices - + + ContainerIndex& operator()(); // -> sync; just to shorten the code + }; @@ -97,9 +103,15 @@ namespace MultiArrayTools virtual size_t dim() const override; virtual size_t size() const override; + template + auto get() const -> decltype( *std::get( mSpace ) )&; + + template + auto getPtr() const -> decltype( std::get( mSpace ) )&; + virtual IndexType begin() const override; virtual IndexType end() const override; - + virtual std::shared_ptr index() const override; friend ContainerRangeFactory; diff --git a/src/index_unit_test.cc b/src/index_unit_test.cc index 308c393..206846c 100644 --- a/src/index_unit_test.cc +++ b/src/index_unit_test.cc @@ -26,6 +26,12 @@ namespace { auto nptr = std::make_shared( rs... ); fptr = nptr; } + + template + auto mkt(Ts&&... ts) -> decltype(std::make_tuple(ts...)) + { + return std::make_tuple(ts...); + } class IndexTest : public ::testing::Test { @@ -60,12 +66,24 @@ namespace { swapMFactory(rfbptr, temp1, temp2, temp3 ); m3rptr = std::dynamic_pointer_cast( rfbptr->create() ); + + swapMFactory(rfbptr, sr1ptr, m3rptr, sr2ptr); + mstrptr = std::dynamic_pointer_cast( rfbptr->create() ); + + swapMFactory(rfbptr, m3rptr, sr2ptr); + cr1ptr = std::dynamic_pointer_cast( rfbptr->create() ); + + swapMFactory(rfbptr, m3rptr, sr1ptr); + cr2ptr = std::dynamic_pointer_cast( rfbptr->create() ); } std::shared_ptr rfbptr; std::shared_ptr sr1ptr; std::shared_ptr sr2ptr; std::shared_ptr m3rptr; + std::shared_ptr mstrptr; + std::shared_ptr cr1ptr; + std::shared_ptr cr2ptr; }; TEST_F(IndexTest, SingleIndex_SimpleCall) @@ -101,15 +119,15 @@ namespace { EXPECT_EQ(mi.pos(), 0); EXPECT_EQ(mi.first(), true); EXPECT_EQ(mi.last(), false); - EXPECT_EQ(mi.meta() == std::make_tuple('a','1','0'), true); - mi.at(std::make_tuple('b','1','7')); + EXPECT_EQ(mi.meta() == mkt('a','1','0'), true); + mi.at( mkt('b','1','7') ); EXPECT_EQ(mi.pos(), mi.max()-1); EXPECT_EQ(mi.first(), false); EXPECT_EQ(mi.last(), true); mi = 1; - EXPECT_EQ(mi.meta() == std::make_tuple('a','1','7'), true); + EXPECT_EQ(mi.meta() == mkt('a','1','7'), true); ++mi; - EXPECT_EQ(mi.meta() == std::make_tuple('b','1','0'), true); + EXPECT_EQ(mi.meta() == mkt('b','1','0'), true); ++mi; auto mi2 = m3rptr->end(); --mi2; @@ -118,8 +136,75 @@ namespace { --mi2; EXPECT_EQ(mi == mi2, false); EXPECT_EQ(mi != mi2, true); + auto si = sr1ptr->begin(); + EXPECT_EQ(si == mi, false); + EXPECT_EQ(si != mi, true); } + TEST_F(IndexTest, MasterRange_Check) + { + EXPECT_EQ(mstrptr->size(), 48); + EXPECT_EQ(mstrptr->template get<0>().size(), 3); + EXPECT_EQ(mstrptr->template get<1>().size(), 4); + EXPECT_EQ(mstrptr->template get<2>().size(), 4); + EXPECT_EQ(mstrptr->dim(), 3); + EXPECT_EQ(mstrptr->template get<0>().dim(), 1); + EXPECT_EQ(mstrptr->template get<1>().dim(), 3); + + auto mi = mstrptr->begin(); + EXPECT_EQ(mi.meta() == mkt( 'e' , mkt('a', '1', '0') , 'x' ), true); + mi = mi.max()-1; + EXPECT_EQ(mi.meta() == mkt( 'n' , mkt('b', '1', '7') , 'f' ), true); + mi.template down<1>(); + EXPECT_EQ(mi.meta() == mkt( 'n' , mkt('b', '1', '0') , 'f' ), true); + mi.template down<0>(); + EXPECT_EQ(mi.meta() == mkt( 'b' , mkt('b', '1', '0') , 'f' ), true); + mi.template down<2>(); + EXPECT_EQ(mi.meta() == mkt( 'b' , mkt('b', '1', '0') , 'l' ), true); + mi.template up<1>(); + EXPECT_EQ(mi.meta() == mkt( 'b' , mkt('b', '1', '7') , 'l' ), true); + + auto& subI = mi.template get<0>(); + EXPECT_EQ(subI.meta(), 'b'); + mi.template up<0>(); + EXPECT_EQ(subI.meta(), 'n'); + auto& subI2 = mi.template get<1>(); + EXPECT_EQ(subI2.meta() == mkt('b', '1', '7'), true); + mi.template down<1>(); + EXPECT_EQ(subI2.meta() == mkt('b', '1', '0'), true); + } + + TEST_F(IndexTest, ContainerRange_Check) + { + EXPECT_EQ(cr1ptr->size(), 16); + EXPECT_EQ(cr2ptr->size(), 12); + + auto mi = mstrptr->begin(); + auto ci1 = cr1ptr->begin(); + auto ci2 = cr2ptr->begin(); + + EXPECT_EQ(ci1.max(), 16); + EXPECT_EQ(ci2.max(), 12); + + ci1(mi.template getPtr<1>(), mi.template getPtr<2>()); + ci2(mi.template getPtr<1>(), mi.template getPtr<0>()); + + EXPECT_EQ(ci1.pos(), 0); + EXPECT_EQ(ci2.pos(), 0); + ++mi; + EXPECT_EQ(ci1().pos(), 1); + EXPECT_EQ(ci2().pos(), 0); + mi.template up<1>(); + EXPECT_EQ(ci1().pos(), 5); + EXPECT_EQ(ci2().pos(), 3); + mi.template up<0>(); + EXPECT_EQ(ci1().pos(), 5); + EXPECT_EQ(ci2().pos(), 4); + mi = mi.max()-1; + EXPECT_EQ(ci1().pos(), ci1.max()-1); + EXPECT_EQ(ci2().pos(), ci2.max()-1); + } + } // end namespace int main(int argc, char** argv) diff --git a/src/multi_range.cc b/src/multi_range.cc index 05b04e8..55cf433 100644 --- a/src/multi_range.cc +++ b/src/multi_range.cc @@ -96,6 +96,13 @@ namespace MultiArrayTools { return *std::get(mIPack); } + + template + template + auto MultiIndex::getPtr() const -> decltype( std::get( mIPack ) )& + { + return std::get(mIPack); + } template const IndexBase& MultiIndex::get(size_t n) const diff --git a/src/multi_range.h b/src/multi_range.h index c4042a5..ea8b1a5 100644 --- a/src/multi_range.h +++ b/src/multi_range.h @@ -49,7 +49,10 @@ namespace MultiArrayTools template auto get() const -> decltype( *std::get( mIPack ) )&; - + + template + auto getPtr() const -> decltype( std::get( mIPack ) )&; + const IndexBase& get(size_t n) const; virtual MetaType meta() const override; diff --git a/src/pack_num.h b/src/pack_num.h index 20d5a7c..2ba40ef 100644 --- a/src/pack_num.h +++ b/src/pack_num.h @@ -92,9 +92,7 @@ namespace MultiArrayHelper auto& i = *std::get(iPack).get(); const size_t ownPos = pos % i.max(); i = ownPos; - if(ownPos == pos){ - PackNum::setIndexPack(iPack, (pos - ownPos) / i.max() ); - } + PackNum::setIndexPack(iPack, (pos - ownPos) / i.max() ); } template @@ -125,21 +123,21 @@ namespace MultiArrayHelper static size_t makePos(const std::tuple...>& iPtrTup) { return std::get(iPtrTup)->pos() + - PackNum::makePos(iPtrTup) * std::get(iPtrTup)->max(); + PackNum::makePos(iPtrTup) * std::get(iPtrTup)->max(); } template - static void swapIndices(Pack& ipack, const std::shared_ptr&... ninds, - const std::shared_ptr& nind) + static void swapIndices(Pack& ipack, const std::shared_ptr& nind, + const std::shared_ptr&... ninds) { - std::get(ipack).swap( nind ); + std::get::value-N-1>(ipack) = nind; PackNum::swapIndices(ipack, ninds...); } template static size_t blockSize(const std::tuple...>& pack) { - return std::get(pack)->size() * PackNum::blockSize(pack); + return std::get(pack)->max() * PackNum::blockSize(pack); } }; @@ -231,13 +229,13 @@ namespace MultiArrayHelper template static void swapIndices(Pack& ipack, const std::shared_ptr& nind) { - std::get<0>(ipack).swap( nind ); + std::get::value-1>(ipack) = nind; } template static size_t blockSize(const std::tuple...>& pack) { - return std::get(pack)->size(); + return std::get(pack)->max(); } };