This commit is contained in:
Christian Zimmermann 2022-10-12 23:03:44 +02:00
parent 73ded8c9a8
commit c7e66f081c
5 changed files with 86 additions and 14 deletions

View file

@ -238,6 +238,8 @@ namespace CNORXZ
{ {
static_assert(is_scalar_pos_type<BPosT>::value, static_assert(is_scalar_pos_type<BPosT>::value,
"MPos has to be derived from scalar pos type"); "MPos has to be derived from scalar pos type");
static_assert(pos_depth<NPosT>::value < MAX_VMPOS_DEPTH,
"preliminary...");
} }
template <class BPosT, class NPosT> template <class BPosT, class NPosT>
@ -246,6 +248,8 @@ namespace CNORXZ
{ {
static_assert(is_scalar_pos_type<BPosT>::value, static_assert(is_scalar_pos_type<BPosT>::value,
"MPos has to be derived from scalar pos type"); "MPos has to be derived from scalar pos type");
static_assert(pos_depth<NPosT>::value < MAX_VMPOS_DEPTH,
"preliminary...");
} }
template <class BPosT, class NPosT> template <class BPosT, class NPosT>
@ -255,6 +259,8 @@ namespace CNORXZ
{ {
static_assert(is_scalar_pos_type<BPosT>::value, static_assert(is_scalar_pos_type<BPosT>::value,
"MPos has to be derived from scalar pos type"); "MPos has to be derived from scalar pos type");
static_assert(pos_depth<NPosT>::value < MAX_VMPOS_DEPTH,
"preliminary...");
} }
template <class BPosT, class NPosT> template <class BPosT, class NPosT>
@ -264,6 +270,8 @@ namespace CNORXZ
{ {
static_assert(is_scalar_pos_type<BPosT>::value, static_assert(is_scalar_pos_type<BPosT>::value,
"MPos has to be derived from scalar pos type"); "MPos has to be derived from scalar pos type");
static_assert(pos_depth<NPosT>::value < MAX_VMPOS_DEPTH,
"preliminary...");
} }
template <class BPosT, class NPosT> template <class BPosT, class NPosT>
@ -309,7 +317,8 @@ namespace CNORXZ
template <class PosT> template <class PosT>
constexpr auto MPos<BPosT,NPosT>::extend(const PosT& a) const constexpr auto MPos<BPosT,NPosT>::extend(const PosT& a) const
{ {
return mNext.extend(a); typedef decltype(mNext.extend(a)) ONPosT;
return MPos<BPosT,ONPosT>(*this, mNext.extend(a));
} }
/************ /************

View file

@ -16,6 +16,18 @@ namespace CNORXZ
template <class T> template <class T>
struct is_static_pos_type { CXZ_CVAL_FALSE; }; struct is_static_pos_type { CXZ_CVAL_FALSE; };
template <class PosT>
struct pos_depth
{
pos_depth()
{
static_assert(is_pos_type<PosT>::value,
"pos_depth is only defined for pos types");
}
static constexpr SizeT value = 1;
};
template <SizeT N> template <SizeT N>
class SPos class SPos
{ {
@ -238,6 +250,12 @@ namespace CNORXZ
template <> struct is_pos_type<DPos> { CXZ_CVAL_TRUE; }; template <> struct is_pos_type<DPos> { CXZ_CVAL_TRUE; };
template <> struct is_pos_type<DPosRef> { CXZ_CVAL_TRUE; }; template <> struct is_pos_type<DPosRef> { CXZ_CVAL_TRUE; };
template <class BPosT, class NPosT>
struct pos_depth<MPos<BPosT,NPosT>>
{
static constexpr SizeT value = pos_depth<NPosT>::value + 1;
};
} // end namespace CNORXZInternal } // end namespace CNORXZInternal

View file

@ -156,7 +156,7 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
VPos<MPos<PosT1,PosT2>>::VPos(const MPos<PosT1,PosT2>& a) : VPos<MPos<PosT1,PosT2>>::VPos(const MPos<PosT1,PosT2>& a) :
MPos<PosT1,PosT2>(a), MPos<PosT1,PosT2>(a),
mTRef(this), mTRef(static_cast<const PosT1*>(this)),
mNRef(&this->next()) mNRef(&this->next())
{} {}
@ -225,15 +225,27 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
Uptr<VPosBase> VPos<MPos<PosT1,PosT2>>::vextend(const UPos& a) const Uptr<VPosBase> VPos<MPos<PosT1,PosT2>>::vextend(const UPos& a) const
{ {
typedef decltype(this->extend(a)) OPosT; if constexpr(pos_depth<PosT2>::value < MAX_VMPOS_DEPTH-1){
return std::make_unique<VPos<OPosT>>(this->extend(a)); typedef decltype(this->extend(a)) OPosT;
return std::make_unique<VPos<OPosT>>(this->extend(a));
}
else {
CXZ_ERROR("preliminary...");
return nullptr;
}
} }
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
Uptr<VPosBase> VPos<MPos<PosT1,PosT2>>::vextend(const FPos& a) const Uptr<VPosBase> VPos<MPos<PosT1,PosT2>>::vextend(const FPos& a) const
{ {
typedef decltype(this->extend(a)) OPosT; if constexpr(pos_depth<PosT2>::value < MAX_VMPOS_DEPTH-1){
return std::make_unique<VPos<OPosT>>(this->extend(a)); typedef decltype(this->extend(a)) OPosT;
return std::make_unique<VPos<OPosT>>(this->extend(a));
}
else {
CXZ_ERROR("preliminary...");
return nullptr;
}
} }
/*************** /***************
@ -327,7 +339,9 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
VPosRef<MPos<PosT1,PosT2>>::VPosRef(const MPos<PosT1,PosT2>* c) : VPosRef<MPos<PosT1,PosT2>>::VPosRef(const MPos<PosT1,PosT2>* c) :
mC(c), mTRef(this), mNRef(c->vnext()) mC(c),
mTRef(static_cast<const PosT1*>(mC)),
mNRef(&c->next())
{} {}
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
@ -368,7 +382,7 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
const VPosBase* VPosRef<MPos<PosT1,PosT2>>::vnext() const const VPosBase* VPosRef<MPos<PosT1,PosT2>>::vnext() const
{ {
return mNRef; return &mNRef;
} }
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
@ -395,15 +409,27 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
Uptr<VPosBase> VPosRef<MPos<PosT1,PosT2>>::vextend(const UPos& a) const Uptr<VPosBase> VPosRef<MPos<PosT1,PosT2>>::vextend(const UPos& a) const
{ {
typedef decltype(mC->extend(a)) OPosT; if constexpr(pos_depth<PosT2>::value < MAX_VMPOS_DEPTH-1){
return std::make_unique<VPos<OPosT>>(mC->extend(a)); typedef decltype(mC->extend(a)) OPosT;
return std::make_unique<VPos<OPosT>>(mC->extend(a));
}
else {
CXZ_ERROR("preliminary...");
return nullptr;
}
} }
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
Uptr<VPosBase> VPosRef<MPos<PosT1,PosT2>>::vextend(const FPos& a) const Uptr<VPosBase> VPosRef<MPos<PosT1,PosT2>>::vextend(const FPos& a) const
{ {
typedef decltype(mC->extend(a)) OPosT; if constexpr(pos_depth<PosT2>::value < MAX_VMPOS_DEPTH-1){
return std::make_unique<VPos<OPosT>>(mC->extend(a)); typedef decltype(mC->extend(a)) OPosT;
return std::make_unique<VPos<OPosT>>(mC->extend(a));
}
else {
CXZ_ERROR("preliminary...");
return nullptr;
}
} }
} }

View file

@ -4,6 +4,8 @@
#include "base/base.h" #include "base/base.h"
#define MAX_VMPOS_DEPTH 10
namespace CNORXZ namespace CNORXZ
{ {
class VPosBase class VPosBase
@ -126,8 +128,6 @@ namespace CNORXZ
virtual Uptr<VPosBase> vplus(const VPosBase* a) const override final; virtual Uptr<VPosBase> vplus(const VPosBase* a) const override final;
virtual Uptr<VPosBase> vtimes(const VPosBase* a) const override final; virtual Uptr<VPosBase> vtimes(const VPosBase* a) const override final;
virtual Uptr<VPosBase> vexec(const VPosBase* a) const override final; virtual Uptr<VPosBase> vexec(const VPosBase* a) const override final;
virtual Uptr<VPosBase> vextend(const DPos& a) const override final;
virtual Uptr<VPosBase> vextend(const DPosRef& a) const override final;
virtual Uptr<VPosBase> vextend(const UPos& a) const override final; virtual Uptr<VPosBase> vextend(const UPos& a) const override final;
virtual Uptr<VPosBase> vextend(const FPos& a) const override final; virtual Uptr<VPosBase> vextend(const FPos& a) const override final;
}; };

View file

@ -98,6 +98,25 @@ namespace
EXPECT_EQ(mp5.next().val(), mS4p.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) TEST_F(Pos_Test, Dyn)
{ {
DPos dp01(static_cast<UPos>(mS2p)); DPos dp01(static_cast<UPos>(mS2p));