diff --git a/src/include/ranges/xfor/pos_type.cc.h b/src/include/ranges/xfor/pos_type.cc.h index ff36b24..a3cf4d3 100644 --- a/src/include/ranges/xfor/pos_type.cc.h +++ b/src/include/ranges/xfor/pos_type.cc.h @@ -238,6 +238,8 @@ namespace CNORXZ { static_assert(is_scalar_pos_type::value, "MPos has to be derived from scalar pos type"); + static_assert(pos_depth::value < MAX_VMPOS_DEPTH, + "preliminary..."); } template @@ -246,6 +248,8 @@ namespace CNORXZ { static_assert(is_scalar_pos_type::value, "MPos has to be derived from scalar pos type"); + static_assert(pos_depth::value < MAX_VMPOS_DEPTH, + "preliminary..."); } template @@ -255,6 +259,8 @@ namespace CNORXZ { static_assert(is_scalar_pos_type::value, "MPos has to be derived from scalar pos type"); + static_assert(pos_depth::value < MAX_VMPOS_DEPTH, + "preliminary..."); } template @@ -264,6 +270,8 @@ namespace CNORXZ { static_assert(is_scalar_pos_type::value, "MPos has to be derived from scalar pos type"); + static_assert(pos_depth::value < MAX_VMPOS_DEPTH, + "preliminary..."); } template @@ -309,7 +317,8 @@ namespace CNORXZ template constexpr auto MPos::extend(const PosT& a) const { - return mNext.extend(a); + typedef decltype(mNext.extend(a)) ONPosT; + return MPos(*this, mNext.extend(a)); } /************ diff --git a/src/include/ranges/xfor/pos_type.h b/src/include/ranges/xfor/pos_type.h index 041eff9..e9b8b39 100644 --- a/src/include/ranges/xfor/pos_type.h +++ b/src/include/ranges/xfor/pos_type.h @@ -16,6 +16,18 @@ namespace CNORXZ template struct is_static_pos_type { CXZ_CVAL_FALSE; }; + template + struct pos_depth + { + pos_depth() + { + static_assert(is_pos_type::value, + "pos_depth is only defined for pos types"); + } + + static constexpr SizeT value = 1; + }; + template class SPos { @@ -237,6 +249,12 @@ namespace CNORXZ template struct is_pos_type> { CXZ_CVAL_TRUE; }; template <> struct is_pos_type { CXZ_CVAL_TRUE; }; template <> struct is_pos_type { CXZ_CVAL_TRUE; }; + + template + struct pos_depth> + { + static constexpr SizeT value = pos_depth::value + 1; + }; } // end namespace CNORXZInternal diff --git a/src/include/ranges/xfor/vpos_type.cc.h b/src/include/ranges/xfor/vpos_type.cc.h index 5332973..e4216a8 100644 --- a/src/include/ranges/xfor/vpos_type.cc.h +++ b/src/include/ranges/xfor/vpos_type.cc.h @@ -156,7 +156,7 @@ namespace CNORXZ template VPos>::VPos(const MPos& a) : MPos(a), - mTRef(this), + mTRef(static_cast(this)), mNRef(&this->next()) {} @@ -225,15 +225,27 @@ namespace CNORXZ template Uptr VPos>::vextend(const UPos& a) const { - typedef decltype(this->extend(a)) OPosT; - return std::make_unique>(this->extend(a)); + if constexpr(pos_depth::value < MAX_VMPOS_DEPTH-1){ + typedef decltype(this->extend(a)) OPosT; + return std::make_unique>(this->extend(a)); + } + else { + CXZ_ERROR("preliminary..."); + return nullptr; + } } template Uptr VPos>::vextend(const FPos& a) const { - typedef decltype(this->extend(a)) OPosT; - return std::make_unique>(this->extend(a)); + if constexpr(pos_depth::value < MAX_VMPOS_DEPTH-1){ + typedef decltype(this->extend(a)) OPosT; + return std::make_unique>(this->extend(a)); + } + else { + CXZ_ERROR("preliminary..."); + return nullptr; + } } /*************** @@ -327,7 +339,9 @@ namespace CNORXZ template VPosRef>::VPosRef(const MPos* c) : - mC(c), mTRef(this), mNRef(c->vnext()) + mC(c), + mTRef(static_cast(mC)), + mNRef(&c->next()) {} template @@ -368,7 +382,7 @@ namespace CNORXZ template const VPosBase* VPosRef>::vnext() const { - return mNRef; + return &mNRef; } template @@ -395,15 +409,27 @@ namespace CNORXZ template Uptr VPosRef>::vextend(const UPos& a) const { - typedef decltype(mC->extend(a)) OPosT; - return std::make_unique>(mC->extend(a)); + if constexpr(pos_depth::value < MAX_VMPOS_DEPTH-1){ + typedef decltype(mC->extend(a)) OPosT; + return std::make_unique>(mC->extend(a)); + } + else { + CXZ_ERROR("preliminary..."); + return nullptr; + } } template Uptr VPosRef>::vextend(const FPos& a) const { - typedef decltype(mC->extend(a)) OPosT; - return std::make_unique>(mC->extend(a)); + if constexpr(pos_depth::value < MAX_VMPOS_DEPTH-1){ + typedef decltype(mC->extend(a)) OPosT; + return std::make_unique>(mC->extend(a)); + } + else { + CXZ_ERROR("preliminary..."); + return nullptr; + } } } diff --git a/src/include/ranges/xfor/vpos_type.h b/src/include/ranges/xfor/vpos_type.h index 1cf36cf..c217ba0 100644 --- a/src/include/ranges/xfor/vpos_type.h +++ b/src/include/ranges/xfor/vpos_type.h @@ -4,6 +4,8 @@ #include "base/base.h" +#define MAX_VMPOS_DEPTH 10 + namespace CNORXZ { class VPosBase @@ -126,8 +128,6 @@ namespace CNORXZ virtual Uptr vplus(const VPosBase* a) const override final; virtual Uptr vtimes(const VPosBase* a) const override final; virtual Uptr vexec(const VPosBase* a) const override final; - virtual Uptr vextend(const DPos& a) const override final; - virtual Uptr vextend(const DPosRef& a) const override final; virtual Uptr vextend(const UPos& a) const override final; virtual Uptr vextend(const FPos& a) const override final; }; diff --git a/src/tests/xfor_unit_test.cc b/src/tests/xfor_unit_test.cc index fa45cf3..6095c8a 100644 --- a/src/tests/xfor_unit_test.cc +++ b/src/tests/xfor_unit_test.cc @@ -97,6 +97,25 @@ namespace EXPECT_EQ(mp5.val(), mUp2.val() * mUp1.val()); EXPECT_EQ(mp5.next().val(), mS4p.val() * mUp1.val()); } + + TEST_F(Pos_Test, Extend) + { + auto mp1 = mkMPos(mS2p, mUp1); + auto mp2 = mkMPos(mUp2, mS4p); + auto mp3 = mp1.extend(mUp2); + auto mp4 = mp2.extend(mS2p); + + EXPECT_EQ( mp3.size(), 3u ); + EXPECT_EQ( mp4.size(), 3u ); + + EXPECT_EQ( mp3.val(), mS2p.val() ); + EXPECT_EQ( mp3.next().val(), mUp1.val() ); + EXPECT_EQ( mp3.next().next().val(), mUp2.val() ); + + EXPECT_EQ( mp4.val(), mUp2.val() ); + EXPECT_EQ( mp4.next().val(), mS4p.val() ); + EXPECT_EQ( mp4.next().next().val(), mS2p.val() ); + } TEST_F(Pos_Test, Dyn) {