diff --git a/src/base_def.h b/src/base_def.h index b79e4d2..590b89e 100644 --- a/src/base_def.h +++ b/src/base_def.h @@ -3,6 +3,8 @@ #ifndef __base_def_h__ #define __base_def_h__ +#include + #define DEFAULT_MEMBERS(__class_name__) __class_name__() = default; \ __class_name__(const __class_name__& in) = default; \ __class_name__& operator=(const __class_name__& in) = default; \ diff --git a/src/index_base.cc b/src/index_base.cc index f52aa3d..45159a0 100644 --- a/src/index_base.cc +++ b/src/index_base.cc @@ -66,8 +66,11 @@ namespace MultiArrayTools void IndefinitIndexBase::setPos(size_t pos) { mPos = pos; + //VCHECK(mName); if(linked()){ mLinked->setPos(pos); + mLinked->evalMajor(); + //VCHECK(mLinked->name()); } } @@ -78,7 +81,7 @@ namespace MultiArrayTools size_t IndefinitIndexBase::outOfRange() const { - int res = pos() - max(); + int res = pos() - max() + 1; return res > 0 ? static_cast(res) : 0; } @@ -86,6 +89,23 @@ namespace MultiArrayTools { return true; } + + void IndefinitIndexBase::evalMajor() + { + if(not master()){ + mMajor->eval(); + } + } + + bool IndefinitIndexBase::master() + { + return mMajor == nullptr; + } + + void IndefinitIndexBase::subOrd(IndefinitIndexBase* major) + { + mMajor = major; + } /************** * IndexBase * @@ -113,4 +133,10 @@ namespace MultiArrayTools mRange = range; } } + + template + void IndexBase::eval() + { + setPos( evaluate(*dynamic_cast( this )) ); + } } diff --git a/src/index_base.h b/src/index_base.h index 09d2181..75008fe 100644 --- a/src/index_base.h +++ b/src/index_base.h @@ -50,6 +50,12 @@ namespace MultiArrayTools virtual size_t outOfRange() const; virtual bool toNull() const; + + virtual void eval() = 0; + virtual void evalMajor(); + virtual bool master(); + + virtual void subOrd(IndefinitIndexBase* major); protected: @@ -57,6 +63,7 @@ namespace MultiArrayTools size_t mPos; IndefinitIndexBase* mLinked = nullptr; + IndefinitIndexBase* mMajor = nullptr; }; template @@ -72,6 +79,8 @@ namespace MultiArrayTools virtual bool toNull() const override; virtual void assignRange(RangeBase const* range); + + virtual void eval() override; protected: diff --git a/src/multi_range.cc b/src/multi_range.cc index 5109549..86883cf 100644 --- a/src/multi_range.cc +++ b/src/multi_range.cc @@ -81,7 +81,7 @@ namespace MultiArrayTools size_t oor = si.outOfRange(); if(oor and digit != 0){ plus(index, digit - 1, 1); - plus(index, digit, oor - si.max() - 1); + plus(index, digit, -si.max()); } } @@ -105,6 +105,27 @@ namespace MultiArrayTools std::get<0>(iPack).name(name.get(0)); } }; + + template + struct IndexSubOrder + { + template + static void subOrd(IndexPack& iPack, IndefinitIndexBase* major) + { + std::get(iPack).subOrd(major); + IndexSubOrder::subOrd(iPack, major); + } + }; + + template <> + struct IndexSubOrder<0> + { + template + static void subOrd(IndexPack& iPack, IndefinitIndexBase* major) + { + std::get<0>(iPack).subOrd(major); + } + }; } template @@ -112,6 +133,7 @@ namespace MultiArrayTools Indices&&... inds) : IndexBase >(range), mIPack(std::make_tuple(inds...)) { + IndexSubOrder::subOrd(mIPack, this); IIB::mPos = evaluate(*this); } @@ -120,10 +142,10 @@ namespace MultiArrayTools const IndexPack& ipack) : IndexBase >(range), mIPack(ipack) { + IndexSubOrder::subOrd(mIPack, this); IIB::mPos = evaluate(*this); } - - + template MultiIndex& MultiIndex::operator++() { @@ -143,8 +165,8 @@ namespace MultiArrayTools template MultiIndex& MultiIndex::operator+=(int n) { - IIB::setPos( IIB::pos() + n ); - plus(*this, 0, n); + plus(*this, sizeof...(Indices)-1, 1); + IIB::setPos( evaluate(*this) ); return *this; } @@ -207,6 +229,7 @@ namespace MultiArrayTools MultiIndex& MultiIndex::operator()(Indices&&... inds) { mIPack = std::make_tuple(inds...); + IndexSubOrder::subOrd(mIPack, this); IIB::mPos = evaluate(*this); return *this; } @@ -215,6 +238,7 @@ namespace MultiArrayTools MultiIndex& MultiIndex::operator()(const Indices&... inds) { mIPack = std::make_tuple(Indices(inds)...); + IndexSubOrder::subOrd(mIPack, this); IIB::mPos = evaluate(*this); return *this; } @@ -234,6 +258,7 @@ namespace MultiArrayTools { if(toLink->rangeType() != rangeType() and toLink->name() == IIB::name()){ // throw !! + assert(0); } if(toLink->rangeType() == rangeType() and toLink->name() == IIB::name()){ @@ -249,7 +274,13 @@ namespace MultiArrayTools } } else { - return linkLower(toLink); + if(linkLower(toLink)){ + IIB::mLinked = nullptr; + return true; + } + else { + return false; + } } } diff --git a/src/single_range.h b/src/single_range.h index 4077892..9d5d81e 100644 --- a/src/single_range.h +++ b/src/single_range.h @@ -47,7 +47,7 @@ namespace MultiArrayTools virtual size_t dim() const override; // = 1 virtual void linkTo(IndefinitIndexBase* target) override; - + protected: virtual size_t evaluate(const SingleIndex& in) const override; }; diff --git a/src/unit_test.cc b/src/unit_test.cc index c9572ac..9737aaa 100644 --- a/src/unit_test.cc +++ b/src/unit_test.cc @@ -56,9 +56,9 @@ namespace { typedef MAT::MultiRange Range2dAny; typedef MAT::MultiArray MultiArray2dAny; - ReorderTest() : r1({'a','b','c'}), r2({'a','b'}), + ReorderTest() : r1({'a','b','c'}), r2({'a','b','c','d'}), ra(r1,r2), rb(r2,r1), - ma(ra, {-5,6,2,1,9,54}) {} + ma(ra, {-5,6,2,1,9,54,27,-7,-13,32,90,-67}) {} Range1dAny r1; Range1dAny r2; @@ -117,23 +117,22 @@ namespace { auto i2 = i.template getIndex<1>(); CHECK; ma2("alpha","beta") = ma("beta","alpha"); - VCHECK(i(i1 = 0,i2 = 0).pos()); + EXPECT_EQ(ma2[i(i1 = 0,i2 = 0)],-5); - - VCHECK(i(i1 = 1,i2 = 0).pos()); EXPECT_EQ(ma2[i(i1 = 1,i2 = 0)],6); + EXPECT_EQ(ma2[i(i1 = 2,i2 = 0)],2); + EXPECT_EQ(ma2[i(i1 = 3,i2 = 0)],1); + - VCHECK(i(i1 = 0,i2 = 1).pos()); - EXPECT_EQ(ma2[i(i1 = 0,i2 = 1)],2); + EXPECT_EQ(ma2[i(i1 = 0,i2 = 1)],9); + EXPECT_EQ(ma2[i(i1 = 1,i2 = 1)],54); + EXPECT_EQ(ma2[i(i1 = 2,i2 = 1)],27); + EXPECT_EQ(ma2[i(i1 = 3,i2 = 1)],-7); - VCHECK(i(i1 = 1,i2 = 1).pos()); - EXPECT_EQ(ma2[i(i1 = 1,i2 = 1)],1); - - VCHECK(i(i1 = 0,i2 = 2).pos()); - EXPECT_EQ(ma2[i(i1 = 0,i2 = 2)],9); - - VCHECK(i(i1 = 1,i2 = 2).pos()); - EXPECT_EQ(ma2[i(i1 = 1,i2 = 2)],54); + EXPECT_EQ(ma2[i(i1 = 0,i2 = 2)],-13); + EXPECT_EQ(ma2[i(i1 = 1,i2 = 2)],32); + EXPECT_EQ(ma2[i(i1 = 2,i2 = 2)],90); + EXPECT_EQ(ma2[i(i1 = 3,i2 = 2)],-67); } } // end namespace