Pos_Test Multi works; change some things in near future

This commit is contained in:
Christian Zimmermann 2022-09-28 23:28:07 +02:00
parent 872d8f0d4a
commit 37dc3bf818
5 changed files with 164 additions and 34 deletions

View file

@ -186,7 +186,7 @@ namespace CNORXZ
template <class PosT> template <class PosT>
inline DPos::DPos(const CPosInterface<PosT>& a) : inline DPos::DPos(const CPosInterface<PosT>& a) :
ObjHandle<VPosBase>( std::make_unique<PosT>(a) ) ObjHandle<VPosBase>( std::make_unique<VPos<PosT>>(a) )
{} {}
inline SizeT DPos::size() const inline SizeT DPos::size() const
@ -199,6 +199,11 @@ namespace CNORXZ
return mC->vval(); return mC->vval();
} }
inline DPosRef DPos::first() const
{
return DPosRef(mC->vget());
}
inline DPosRef DPos::next() const inline DPosRef DPos::next() const
{ {
return DPosRef(mC->vnext()); return DPosRef(mC->vnext());
@ -207,13 +212,15 @@ namespace CNORXZ
template <class PosT1> template <class PosT1>
inline DPos DPos::operator+(const CPosInterface<PosT1>& a) const inline DPos DPos::operator+(const CPosInterface<PosT1>& a) const
{ {
return DPos(mC->vplus(VPosRef<PosT1>(&a))); // check memory safety!!! VPosRef<PosT1> r(&a);
return DPos(mC->vplus(&r)); // check memory safety!!!
} }
template <class PosT1> template <class PosT1>
inline DPos DPos::operator*(const CPosInterface<PosT1>& a) const inline DPos DPos::operator*(const CPosInterface<PosT1>& a) const
{ {
return DPos(mC->vtimes(VPosRef<PosT1>(&a))); // check memory safety!!! VPosRef<PosT1> r(&a);
return DPos(mC->vtimes(&r)); // check memory safety!!!
} }
template <class PosT1> template <class PosT1>
@ -240,6 +247,11 @@ namespace CNORXZ
return mC->vval(); return mC->vval();
} }
inline DPosRef DPosRef::first() const
{
return DPosRef(mC->vget());
}
inline DPosRef DPosRef::next() const inline DPosRef DPosRef::next() const
{ {
return DPosRef(mC->vnext()); return DPosRef(mC->vnext());
@ -248,13 +260,15 @@ namespace CNORXZ
template <class PosT1> template <class PosT1>
inline DPos DPosRef::operator+(const CPosInterface<PosT1>& a) const inline DPos DPosRef::operator+(const CPosInterface<PosT1>& a) const
{ {
return DPos(mC->vplus(VPosRef<PosT1>(&a))); // check memory safety!!! VPosRef<PosT1> r(&a);
return DPos(mC->vplus(&r)); // check memory safety!!!
} }
template <class PosT1> template <class PosT1>
inline DPos DPosRef::operator*(const CPosInterface<PosT1>& a) const inline DPos DPosRef::operator*(const CPosInterface<PosT1>& a) const
{ {
return DPos(mC->vtimes(VPosRef<PosT1>(&a))); // check memory safety!!! VPosRef<PosT1> r(&a);
return DPos(mC->vtimes(&r)); // check memory safety!!!
} }
template <class PosT1> template <class PosT1>
@ -271,7 +285,7 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
constexpr MPos<PosT1,PosT2>::MPos(const CPosInterface<PosT1>& first, constexpr MPos<PosT1,PosT2>::MPos(const CPosInterface<PosT1>& first,
const CPosInterface<PosT2>& next) : const CPosInterface<PosT2>& next) :
mFirst(first), mNext(next) mFirst(first.THIS()), mNext(next.THIS())
{} {}
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
@ -311,9 +325,9 @@ namespace CNORXZ
template <class PosT3> template <class PosT3>
constexpr auto MPos<PosT1,PosT2>::operator*(const CPosInterface<PosT3>& a) const constexpr auto MPos<PosT1,PosT2>::operator*(const CPosInterface<PosT3>& a) const
{ {
typedef decltype(first()*a) PosT5; typedef decltype(first()*a.THIS()) PosT5;
typedef decltype(next()*a) PosT6; typedef decltype(next()*a.THIS()) PosT6;
return MPos<PosT5,PosT6>(first()*a, next()*a); return MPos<PosT5,PosT6>(first()*a.THIS(), next()*a.THIS());
} }
template <class PosT1, class PosT2> template <class PosT1, class PosT2>

View file

@ -11,6 +11,8 @@ namespace CNORXZ
class CPosInterface class CPosInterface
{ {
public: public:
static constexpr bool MULTI = PosT::MULTI;
DEFAULT_MEMBERS(CPosInterface); DEFAULT_MEMBERS(CPosInterface);
PosT& THIS() { return static_cast<PosT&>(*this); } PosT& THIS() { return static_cast<PosT&>(*this); }
@ -18,11 +20,20 @@ namespace CNORXZ
inline SizeT size() const { return THIS().size(); } inline SizeT size() const { return THIS().size(); }
inline auto val() const { return THIS().val(); } inline auto val() const { return THIS().val(); }
// template!!!
inline CPosInterface<PosT> operator+(const CPosInterface<PosT>& a) const inline CPosInterface<PosT> operator+(const CPosInterface<PosT>& a) const
{ return THIS() + a.THIS(); } { return THIS() + a.THIS(); }
// template!!!
inline CPosInterface<PosT> operator*(const CPosInterface<PosT>& a) const inline CPosInterface<PosT> operator*(const CPosInterface<PosT>& a) const
{ return THIS() * a.THIS(); } { return THIS() * a.THIS(); }
// template!!!
// inline CPosInterface<PosT> execute(const CPosInterface<PosT>& a,
// const CPosInterface<PosT>& b, const CPosInterface<PosT>& c) const
// => a+b*c; only this executes also the FPos/SFPos-Map!!!
// for each class implement +/* for each argument type EXPLICITLY (NO templates, except for MPos)
// *: only UPos/SPos as Arguments, for DPos only UPos as Args
template <class P> template <class P>
inline auto extend(const CPosInterface<P>& a) const { return THIS().extend(a); } inline auto extend(const CPosInterface<P>& a) const { return THIS().extend(a); }
}; };
@ -31,6 +42,8 @@ namespace CNORXZ
class SPos : public CPosInterface<SPos<N>> class SPos : public CPosInterface<SPos<N>>
{ {
public: public:
static constexpr bool MULTI = false;
constexpr SPos() = default; constexpr SPos() = default;
constexpr SizeT size() const; constexpr SizeT size() const;
@ -53,6 +66,7 @@ namespace CNORXZ
private: private:
SizeT mExt = 0; SizeT mExt = 0;
public: public:
static constexpr bool MULTI = false;
DEFAULT_MEMBERS(UPos); DEFAULT_MEMBERS(UPos);
@ -79,6 +93,8 @@ namespace CNORXZ
const SizeT* mMap = nullptr; const SizeT* mMap = nullptr;
public: public:
static constexpr bool MULTI = false;
DEFAULT_MEMBERS(FPos); DEFAULT_MEMBERS(FPos);
inline FPos(SizeT ext, const SizeT* map); inline FPos(SizeT ext, const SizeT* map);
@ -100,6 +116,8 @@ namespace CNORXZ
class SFPos : public CPosInterface<SFPos<N,Ms...>> class SFPos : public CPosInterface<SFPos<N,Ms...>>
{ {
public: public:
static constexpr bool MULTI = false;
constexpr SFPos() = default; constexpr SFPos() = default;
constexpr SizeT size() const; constexpr SizeT size() const;
@ -121,6 +139,8 @@ namespace CNORXZ
public CPosInterface<DPos> public CPosInterface<DPos>
{ {
public: public:
static constexpr bool MULTI = true;
DEFAULT_MEMBERS(DPos); DEFAULT_MEMBERS(DPos);
inline DPos(Uptr<VPosBase>&& a); inline DPos(Uptr<VPosBase>&& a);
@ -129,6 +149,7 @@ namespace CNORXZ
inline SizeT size() const; inline SizeT size() const;
inline SizeT val() const; inline SizeT val() const;
inline DPosRef first() const;
inline DPosRef next() const; inline DPosRef next() const;
template <class PosT1> template <class PosT1>
@ -147,11 +168,14 @@ namespace CNORXZ
private: private:
const VPosBase* mC; const VPosBase* mC;
public: public:
static constexpr bool MULTI = true;
DEFAULT_MEMBERS(DPosRef); DEFAULT_MEMBERS(DPosRef);
inline DPosRef(const VPosBase* c); inline DPosRef(const VPosBase* c);
inline SizeT size() const; inline SizeT size() const;
inline SizeT val() const; inline SizeT val() const;
inline DPosRef first() const;
inline DPosRef next() const; inline DPosRef next() const;
template <class PosT1> template <class PosT1>
@ -164,6 +188,8 @@ namespace CNORXZ
inline DPos extend(const CPosInterface<PosT1>& a) const; inline DPos extend(const CPosInterface<PosT1>& a) const;
}; };
// go to original pattern (-> LINEAR template chain)
// first: just cast by constructor
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
class MPos : public CPosInterface<MPos<PosT1,PosT2>> class MPos : public CPosInterface<MPos<PosT1,PosT2>>
{ {
@ -173,6 +199,8 @@ namespace CNORXZ
PosT2 mNext; PosT2 mNext;
public: public:
static constexpr bool MULTI = true;
DEFAULT_MEMBERS(MPos); DEFAULT_MEMBERS(MPos);
constexpr MPos(const CPosInterface<PosT1>& first, constexpr MPos(const CPosInterface<PosT1>& first,

View file

@ -28,7 +28,7 @@ namespace CNORXZ
template <class PosT> template <class PosT>
Uptr<VPosBase> VPos<PosT>::copy() const Uptr<VPosBase> VPos<PosT>::copy() const
{ {
return std::make_unique<VPos>(*this); return std::make_unique<VPos<PosT>>(*this);
} }
template <class PosT> template <class PosT>
@ -99,13 +99,13 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
VPos<MPos<PosT1,PosT2>>::VPos(const CPosInterface<MPos<PosT1,PosT2>>& a) : VPos<MPos<PosT1,PosT2>>::VPos(const CPosInterface<MPos<PosT1,PosT2>>& a) :
MPos<PosT1,PosT2>(a.THIS()), MPos<PosT1,PosT2>(a.THIS()),
mFRef(&MPosT::mFirst), mNRef(&MPosT::mNext) mFRef(&this->first()), mNRef(&this->next())
{} {}
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
Uptr<VPosBase> VPos<MPos<PosT1,PosT2>>::copy() const Uptr<VPosBase> VPos<MPos<PosT1,PosT2>>::copy() const
{ {
return std::make_unique<MPos<PosT1,PosT2>>(*this); return std::make_unique<VPos<MPos<PosT1,PosT2>>>(*this);
} }
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
@ -123,13 +123,13 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
const VPosBase* VPos<MPos<PosT1,PosT2>>::vget() const const VPosBase* VPos<MPos<PosT1,PosT2>>::vget() const
{ {
return mFRef; return &mFRef;
} }
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
const VPosBase* VPos<MPos<PosT1,PosT2>>::vnext() const const VPosBase* VPos<MPos<PosT1,PosT2>>::vnext() const
{ {
return mNRef; return &mNRef;
} }
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
@ -174,7 +174,7 @@ namespace CNORXZ
template <class PosT> template <class PosT>
VPosRef<PosT>::VPosRef(const CPosInterface<PosT>* c) : VPosRef<PosT>::VPosRef(const CPosInterface<PosT>* c) :
mC(c) mC(&c->THIS())
{} {}
template <class PosT> template <class PosT>
@ -255,7 +255,7 @@ namespace CNORXZ
template <class PosT1, class PosT2> template <class PosT1, class PosT2>
Uptr<VPosBase> VPosRef<MPos<PosT1,PosT2>>::copy() const Uptr<VPosBase> VPosRef<MPos<PosT1,PosT2>>::copy() const
{ {
return std::make_unique<MPos<PosT1,PosT2>>(*mFRef,*mNRef); return std::make_unique<VPos<MPos<PosT1,PosT2>>>(*mFRef,*mNRef);
} }
template <class PosT1, class PosT2> template <class PosT1, class PosT2>

View file

@ -32,11 +32,13 @@ namespace
EXPECT_EQ(cr->size(), mSize); EXPECT_EQ(cr->size(), mSize);
EXPECT_EQ(crx->size(), mSize); EXPECT_EQ(crx->size(), mSize);
EXPECT_EQ(crx->begin() != crx->end(), true); EXPECT_TRUE(crx->begin() != crx->end());
EXPECT_FALSE(crx->begin() == crx->end());
EXPECT_EQ(crx->begin().pos(), 0u); EXPECT_EQ(crx->begin().pos(), 0u);
EXPECT_EQ(crx->end().pos(), mSize); EXPECT_EQ(crx->end().pos(), mSize);
EXPECT_EQ(cr->begin() != cr->end(), true); EXPECT_TRUE(cr->begin() != cr->end());
EXPECT_FALSE(cr->begin() == cr->end());
EXPECT_EQ(cr->begin().pos(), 0u); EXPECT_EQ(cr->begin().pos(), 0u);
EXPECT_EQ(cr->end().pos(), mSize); EXPECT_EQ(cr->end().pos(), mSize);

View file

@ -7,19 +7,31 @@ namespace
{ {
using namespace CNORXZ; using namespace CNORXZ;
template <class PosT1, class PosT2>
constexpr auto mkMPos(const CPosInterface<PosT1>& a, const CPosInterface<PosT2>& b)
{
return MPos<PosT1,PosT2>(a,b);
}
class Pos_Test : public ::testing::Test class Pos_Test : public ::testing::Test
{ {
protected: protected:
static constexpr SizeT s1 = 7;
static constexpr SizeT s2 = 3;
static constexpr SizeT ss1 = 4;
static constexpr SizeT ss2 = 2;
Pos_Test() Pos_Test()
{ {
mUp1 = UPos(7); mUp1 = UPos(s1);
mUp2 = UPos(3); mUp2 = UPos(s2);
} }
UPos mUp1; UPos mUp1;
UPos mUp2; UPos mUp2;
SPos<4> mS4p; SPos<ss1> mS4p;
SPos<2> mS2p; SPos<ss2> mS2p;
}; };
TEST_F(Pos_Test, Basics) TEST_F(Pos_Test, Basics)
@ -29,10 +41,10 @@ namespace
EXPECT_EQ( mS4p.size(), 1 ); EXPECT_EQ( mS4p.size(), 1 );
EXPECT_EQ( mS2p.size(), 1 ); EXPECT_EQ( mS2p.size(), 1 );
EXPECT_EQ( mUp1.val(), 7 ); EXPECT_EQ( mUp1.val(), s1 );
EXPECT_EQ( mUp2.val(), 3 ); EXPECT_EQ( mUp2.val(), s2 );
EXPECT_EQ( mS4p.val(), 4 ); EXPECT_EQ( mS4p.val(), ss1 );
EXPECT_EQ( mS2p.val(), 2 ); EXPECT_EQ( mS2p.val(), ss2 );
auto s6p = mS4p + mS2p; auto s6p = mS4p + mS2p;
auto s8p = mS4p * mS2p; auto s8p = mS4p * mS2p;
@ -48,13 +60,87 @@ namespace
EXPECT_EQ( up5.size(), 1 ); EXPECT_EQ( up5.size(), 1 );
EXPECT_EQ( up6.size(), 1 ); EXPECT_EQ( up6.size(), 1 );
EXPECT_EQ( s6p.val(), 6 ); EXPECT_EQ( s6p.val(), ss1+ss2 );
EXPECT_EQ( s8p.val(), 8 ); EXPECT_EQ( s8p.val(), ss1*ss2 );
EXPECT_EQ( up3.val(), 4*7 ); EXPECT_EQ( up3.val(), ss1*s1 );
EXPECT_EQ( up4.val(), 7*2 ); EXPECT_EQ( up4.val(), s1*ss2 );
EXPECT_EQ( up5.val(), 4+7 ); EXPECT_EQ( up5.val(), ss1+s1 );
EXPECT_EQ( up6.val(), 7+2 ); EXPECT_EQ( up6.val(), s1+ss2 );
} }
TEST_F(Pos_Test, Multi)
{
auto mp1 = mkMPos(mS2p, mUp1);
auto mp2 = mkMPos(mUp2, mS4p);
auto mp3a = mp1 + mp2;
auto mp3b = mp2 + mp1;
auto mp4 = mp1 * mS2p;
auto mp5 = mp2 * mUp1;
EXPECT_EQ(mp1.size(), 2);
EXPECT_EQ(mp2.size(), 2);
EXPECT_EQ(mp3a.size(), 2);
EXPECT_EQ(mp3b.size(), 2);
EXPECT_EQ(mp4.size(), 2);
EXPECT_EQ(mp5.size(), 2);
EXPECT_EQ(mp1.first().val(), mS2p.val());
EXPECT_EQ(mp1.next().val(), mUp1.val());
EXPECT_EQ(mp2.first().val(), mUp2.val());
EXPECT_EQ(mp2.next().val(), mS4p.val());
EXPECT_EQ(mp3a.first().val(), mS2p.val() + mUp2.val());
EXPECT_EQ(mp3a.next().val(), mUp1.val() + mS4p.val());
EXPECT_EQ(mp3b.first().val(), mS2p.val() + mUp2.val());
EXPECT_EQ(mp3b.next().val(), mUp1.val() + mS4p.val());
EXPECT_EQ(mp4.first().val(), mS2p.val() * mS2p.val());
EXPECT_EQ(mp4.next().val(), mUp1.val() * mS2p.val());
EXPECT_EQ(mp5.first().val(), mUp2.val() * mUp1.val());
EXPECT_EQ(mp5.next().val(), mS4p.val() * mUp1.val());
}
/*
TEST_F(Pos_Test, Dyn)
{
DPos dp01(mS2p);
DPos dp02(mUp1);
DPos dp1(mkMPos(mS2p, mUp1));
DPos dp2(mkMPos(mUp2, mS4p));
auto dp3a = dp1 + dp2;
auto dp3b = dp2 + dp1;
auto dp4 = dp1 * dp01;
auto dp5 = dp2 * dp02;
EXPECT_EQ(dp01.size(), 1);
EXPECT_EQ(dp02.size(), 1);
EXPECT_EQ(dp01.val(), mS2p.val());
EXPECT_EQ(dp02.val(), mUp1.val());
EXPECT_EQ(dp1.size(), 2);
EXPECT_EQ(dp2.size(), 2);
EXPECT_EQ(dp3a.size(), 2);
EXPECT_EQ(dp3b.size(), 2);
EXPECT_EQ(dp4.size(), 2);
EXPECT_EQ(dp5.size(), 2);
EXPECT_EQ(dp1.first().val(), mS2p.val());
EXPECT_EQ(dp1.next().val(), mUp1.val());
EXPECT_EQ(dp2.first().val(), mUp2.val());
EXPECT_EQ(dp2.next().val(), mS4p.val());
EXPECT_EQ(dp3a.first().val(), mS2p.val() + mUp2.val());
EXPECT_EQ(dp3a.next().val(), mUp1.val() + mS4p.val());
EXPECT_EQ(dp3b.first().val(), mS2p.val() + mUp2.val());
EXPECT_EQ(dp3b.next().val(), mUp1.val() + mS4p.val());
EXPECT_EQ(dp4.first().val(), mS2p.val() * mS2p.val());
EXPECT_EQ(dp4.next().val(), mUp1.val() * mS2p.val());
EXPECT_EQ(dp5.first().val(), mUp2.val() * mUp1.val());
EXPECT_EQ(dp5.next().val(), mS4p.val() * mUp1.val());
}
*/
} }
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}