diff --git a/src/include/ranges/index_base.cc.h b/src/include/ranges/index_base.cc.h index 52c4b4c..6f45c16 100644 --- a/src/include/ranges/index_base.cc.h +++ b/src/include/ranges/index_base.cc.h @@ -54,37 +54,37 @@ namespace CNORXZ template bool IndexInterface::operator==(const IndexInterface& in) const { - return in.mPos == mPos and *in.range() == *range(); + return in.lex() == lex() and *in.range() == *range(); } template bool IndexInterface::operator!=(const IndexInterface& in) const { - return in.mPos != mPos or *in.range() != *range(); + return in.lex() != lex() or *in.range() != *range(); } template bool IndexInterface::operator<(const IndexInterface& in) const { - return mPos < in.mPos; + return lex() < in.lex(); } template bool IndexInterface::operator>(const IndexInterface& in) const { - return mPos > in.mPos; + return lex() > in.lex(); } template bool IndexInterface::operator<=(const IndexInterface& in) const { - return mPos <= in.mPos; + return lex() <= in.lex(); } template bool IndexInterface::operator>=(const IndexInterface& in) const { - return mPos >= in.mPos; + return lex() >= in.lex(); } template diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index d505051..dde2762 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -49,11 +49,13 @@ namespace CNORXZ // is one less than the max position (=end) if(i != 0 and idx->lex() == idx->lmax()-1){ IB::mPos -= mBlockSizes[i] * idx->pos(); + mLex -= mLexBlockSizes[i] * idx->lex(); (*idx) = 0; up(i-1); return; } IB::mPos += mBlockSizes[i]; + mLex += mLexBlockSizes[i]; ++(*idx); } @@ -63,10 +65,12 @@ namespace CNORXZ if(i != 0 and idx->pos() == 0){ (*idx) = idx->lmax()-1; IB::mPos += mBlockSizes[i] * idx->pos(); + mLex += mLexBlockSizes[i] * idx->lex(); down(i-1); return; } - IB::mPos += mBlockSizes[i]; + IB::mPos -= mBlockSizes[i]; + mLex -= mLexBlockSizes[i]; --(*idx); } @@ -139,11 +143,12 @@ namespace CNORXZ YIndex& YIndex::operator=(SizeT lexpos) { - mLex = lexpos; - if(lexpos == lmax()){ + if(lexpos >= lmax()){ + mLex = lmax(); IB::mPos = pmax(); return *this; } + mLex = lexpos; IB::mPos = 0; for(SizeT i = 0; i != mIs.size(); ++i){ *mIs[i] = (lex() / mLexBlockSizes[i]) % mIs[i]->lmax(); @@ -191,13 +196,18 @@ namespace CNORXZ YIndex& YIndex::operator+=(Int n) { - return *this = lex() + n; + if(static_cast(lex()) + n < 0){ + return *this = 0; + } + return *this = static_cast(lex()) + n; } YIndex& YIndex::operator-=(Int n) { - - return *this = lex() - n; + if(static_cast(lex()) - n < 0){ + return *this = 0; + } + return *this = static_cast(lex()) - n; } SizeT YIndex::lex() const @@ -336,18 +346,20 @@ namespace CNORXZ String YRange::stringMeta(SizeT pos) const { - String out = "["; + const String blim = "["; + const String elim = "]"; + const String dlim = ","; + String out = elim; for(auto rit = mRVec.end()-1;;--rit){ const SizeT cursize = (*rit)->size(); const SizeT curpos = pos % cursize; - out += (*rit)->stringMeta(curpos); - pos -= curpos; + out = (*rit)->stringMeta(curpos) + out; pos /= cursize; if(rit == mRVec.begin()){ - out += "]"; + out = blim + out; break; } - out += ","; + out = dlim + out; } return out; } diff --git a/src/tests/range_unit_test.cc b/src/tests/range_unit_test.cc index c8008d5..0f68311 100644 --- a/src/tests/range_unit_test.cc +++ b/src/tests/range_unit_test.cc @@ -171,6 +171,7 @@ namespace auto endxi = mr->end(); for(auto xi = mr->begin(); xi != endxi; ++xi){ EXPECT_EQ(xi.pos(), cnt); + EXPECT_EQ(xi.lex(), cnt); auto meta = mkm(cnt); EXPECT_TRUE(*xi == DType(meta)); EXPECT_EQ((*xi).str(), toString(meta)); @@ -181,6 +182,7 @@ namespace auto endxxi = mrx->end(); for(auto xxi = mrx->begin(); xxi != endxxi; ++xxi){ EXPECT_EQ(xxi.pos(), cnt); + EXPECT_EQ(xxi.lex(), cnt); auto ci = std::get<0>(xxi.pack()); auto ui = std::get<1>(xxi.pack()); Tuple meta(*(*ci),*(*ui)); @@ -218,10 +220,51 @@ namespace EXPECT_EQ(xi.pos(), cnt); auto meta = mkm(cnt); EXPECT_TRUE(*xi == DType(meta)); + EXPECT_EQ(yr->stringMeta(cnt), toString(meta)); EXPECT_EQ((*xi).str(), toString(meta)); ++cnt; } + } + + TEST_F(YR_Test, Index) + { + auto yrx = std::dynamic_pointer_cast(yr); + auto yi = yrx->begin(); + + EXPECT_EQ(yi.pmax(), yr->size()); + EXPECT_EQ(yi.lmax(), yr->size()); + EXPECT_EQ(yi.range(), yr); + EXPECT_EQ(yi.range(), yrx); + EXPECT_EQ(yi.dim(), 2u); + const SizeT mmsize = mMeta.size(); + auto mkm = [&](SizeT i) { return Vector({DType(i/mmsize),DType(mMeta[i % mmsize])}); }; + for(SizeT i = 0; i != yr->size(); ++i){ + auto a = yi + i; + EXPECT_EQ(a.lex(), i); + EXPECT_EQ(a.pos(), i); + auto mmi = DType(mkm(i)); + EXPECT_TRUE(a.meta() == mmi); + EXPECT_TRUE(*a == mmi); + EXPECT_EQ(a.stringMeta(), toString(mmi)); + + for(SizeT j = 0; j != yr->size(); ++j){ + const Int jj = static_cast(j) - static_cast(i); + auto b = a + jj; + auto mmj = DType(mkm(j)); + EXPECT_EQ(b.lex(), j); + EXPECT_EQ(b.pos(), j); + EXPECT_TRUE(*b == mmj); + EXPECT_EQ(b.stringMeta(), toString(mmj)); + } + } + yi += yi.lmax() + 10; + EXPECT_EQ(yi.lex(), yi.lmax()); + EXPECT_EQ(yi.pos(), yi.pmax()); + + yi -= yi.lmax() + 20; + EXPECT_EQ(yi.lex(), 0); + EXPECT_EQ(yi.pos(), 0); } // RCast_Test }