This commit is contained in:
Christian Zimmermann 2022-10-06 18:32:56 +02:00
parent 37dc3bf818
commit a142fdb466
2 changed files with 166 additions and 278 deletions

View file

@ -37,6 +37,13 @@ namespace CNORXZ
return SPos<N*N1>(); return SPos<N*N1>();
} }
template <SizeT N>
template <SizeT N1>
constexpr auto SPos<N>::operator()(const SPos<N1>& a) const
{
return SPos<N*N1>();
}
template <SizeT N> template <SizeT N>
constexpr auto SPos<N>::operator+(const UPos& a) const constexpr auto SPos<N>::operator+(const UPos& a) const
{ {
@ -49,9 +56,15 @@ namespace CNORXZ
return UPos(N*a.val()); return UPos(N*a.val());
} }
template <SizeT N>
constexpr auto SPos<N>::operator()(const UPos& a) const
{
return UPos(N*a.val());
}
template <SizeT N> template <SizeT N>
template <class PosT> template <class PosT>
constexpr auto SPos<N>::extend(const CPosInterface<PosT>& a) const constexpr auto SPos<N>::extend(const PosT& a) const
{ {
return MPos<SPos<N>,PosT>(*this,a); return MPos<SPos<N>,PosT>(*this,a);
} }
@ -73,19 +86,25 @@ namespace CNORXZ
} }
template <class PosT> template <class PosT>
constexpr UPos UPos::operator+(const CPosInterface<PosT>& in) const constexpr UPos UPos::operator+(const PosT& in) const
{ {
return UPos(mExt + in.val()); return UPos(mExt + in.val());
} }
template <class PosT> template <class PosT>
constexpr UPos UPos::operator*(const CPosInterface<PosT>& in) const constexpr UPos UPos::operator*(const PosT& in) const
{ {
return UPos(mExt * in.val()); return UPos(mExt * in.val());
} }
template <class PosT> template <class PosT>
constexpr auto UPos::extend(const CPosInterface<PosT>& p1) const constexpr UPos UPos::operator()(const PosT& in) const
{
return UPos(mExt * in.val());
}
template <class PosT>
constexpr auto UPos::extend(const PosT& p1) const
{ {
return MPos<UPos,PosT>(*this, p1); return MPos<UPos,PosT>(*this, p1);
} }
@ -107,19 +126,25 @@ namespace CNORXZ
} }
template <class PosT1> template <class PosT1>
constexpr UPos FPos::operator+(const CPosInterface<PosT1>& a) const constexpr UPos FPos::operator+(const PosT1& a) const
{ {
return UPos(mExt + a.val()); return UPos(mExt + a.val());
} }
template <class PosT>
constexpr FPos UPos::operator*(const PosT& in) const
{
return FPos(mExt * in.val(), mMap);
}
template <class PosT1> template <class PosT1>
constexpr UPos FPos::operator*(const CPosInterface<PosT1>& a) const constexpr UPos FPos::operator()(const PosT1& a) const
{ {
return UPos(mExt * mMap[a.val()]); return UPos(mExt * mMap[a.val()]);
} }
template <class PosT1> template <class PosT1>
constexpr auto FPos::extend(const CPosInterface<PosT1>& a) const constexpr auto FPos::extend(const PosT1& a) const
{ {
return MPos<FPos,PosT1>(*this,a); return MPos<FPos,PosT1>(*this,a);
} }
@ -150,6 +175,13 @@ namespace CNORXZ
template <SizeT N, SizeT... Ms> template <SizeT N, SizeT... Ms>
template <SizeT N1> template <SizeT N1>
constexpr auto SFPos<N,Ms...>::operator*(const SPos<N1>& a) const constexpr auto SFPos<N,Ms...>::operator*(const SPos<N1>& a) const
{
return SFPos<N*N1,Ms...>();
}
template <SizeT N, SizeT... Ms>
template <SizeT N1>
constexpr auto SFPos<N,Ms...>::operator()(const SPos<N1>& a) const
{ {
constexpr Arr<SizeT,sizeof...(Ms)> ms({ Ms... }); constexpr Arr<SizeT,sizeof...(Ms)> ms({ Ms... });
return SPos<N*std::get<a.val()>(ms)>(); return SPos<N*std::get<a.val()>(ms)>();
@ -162,7 +194,15 @@ namespace CNORXZ
} }
template <SizeT N, SizeT... Ms> template <SizeT N, SizeT... Ms>
template <SizeT N1>
constexpr auto SFPos<N,Ms...>::operator*(const UPos& a) const constexpr auto SFPos<N,Ms...>::operator*(const UPos& a) const
{
static const Arr<SizeT,sizeof...(Ms)> ms({ Ms... });
return FPos(N * a.val(), &ms[0]);
}
template <SizeT N, SizeT... Ms>
constexpr auto SFPos<N,Ms...>::operator()(const UPos& a) const
{ {
constexpr Arr<SizeT,sizeof...(Ms)> ms({ Ms... }); constexpr Arr<SizeT,sizeof...(Ms)> ms({ Ms... });
return UPos(N * ms[a.val()]); return UPos(N * ms[a.val()]);
@ -170,171 +210,84 @@ namespace CNORXZ
template <SizeT N, SizeT... Ms> template <SizeT N, SizeT... Ms>
template <class PosT> template <class PosT>
constexpr auto SFPos<N,Ms...>::extend(const CPosInterface<PosT>& a) const constexpr auto SFPos<N,Ms...>::extend(const PosT& a) const
{ {
return MPos<SFPos<N,Ms...>,PosT>(*this,a); return MPos<SFPos<N,Ms...>,PosT>(*this,a);
} }
/************
* DPos *
************/
inline DPos::DPos(Uptr<VPosBase>&& a) :
ObjHandle<VPosBase>(std::forward<Uptr<VPosBase>>(a))
{}
template <class PosT>
inline DPos::DPos(const CPosInterface<PosT>& a) :
ObjHandle<VPosBase>( std::make_unique<VPos<PosT>>(a) )
{}
inline SizeT DPos::size() const
{
return mC->vsize();
}
inline SizeT DPos::val() const
{
return mC->vval();
}
inline DPosRef DPos::first() const
{
return DPosRef(mC->vget());
}
inline DPosRef DPos::next() const
{
return DPosRef(mC->vnext());
}
template <class PosT1>
inline DPos DPos::operator+(const CPosInterface<PosT1>& a) const
{
VPosRef<PosT1> r(&a);
return DPos(mC->vplus(&r)); // check memory safety!!!
}
template <class PosT1>
inline DPos DPos::operator*(const CPosInterface<PosT1>& a) const
{
VPosRef<PosT1> r(&a);
return DPos(mC->vtimes(&r)); // check memory safety!!!
}
template <class PosT1>
inline DPos DPos::extend(const CPosInterface<PosT1>& a) const
{
return DPos(mC->vextend(a));
}
/***************
* DPosRef *
***************/
inline DPosRef::DPosRef(const VPosBase* c) :
mC(c)
{}
inline SizeT DPosRef::size() const
{
return mC->vsize();
}
inline SizeT DPosRef::val() const
{
return mC->vval();
}
inline DPosRef DPosRef::first() const
{
return DPosRef(mC->vget());
}
inline DPosRef DPosRef::next() const
{
return DPosRef(mC->vnext());
}
template <class PosT1>
inline DPos DPosRef::operator+(const CPosInterface<PosT1>& a) const
{
VPosRef<PosT1> r(&a);
return DPos(mC->vplus(&r)); // check memory safety!!!
}
template <class PosT1>
inline DPos DPosRef::operator*(const CPosInterface<PosT1>& a) const
{
VPosRef<PosT1> r(&a);
return DPos(mC->vtimes(&r)); // check memory safety!!!
}
template <class PosT1>
inline DPos DPosRef::extend(const CPosInterface<PosT1>& a) const
{
return DPos(mC->vextend(a));
}
/************ /************
* MPos * * MPos *
************/ ************/
template <class PosT1, class PosT2> template <class BPosT, class NPosT>
constexpr MPos<PosT1,PosT2>::MPos(const CPosInterface<PosT1>& first, constexpr MPos<BPosT,NPosT>::MPos()
const CPosInterface<PosT2>& next) :
mFirst(first.THIS()), mNext(next.THIS())
{}
template <class PosT1, class PosT2>
constexpr SizeT MPos<PosT1,PosT2>::size() const
{ {
return mFirst.size() + mNext.size(); static_assert(is_scalar_pos_type<BPosT>::value,
"MPos has to be derived from scalar pos type");
} }
template <class PosT1, class PosT2> template <class BPosT, class NPosT>
constexpr auto MPos<PosT1,PosT2>::val() const template <typename... Args>
constexpr MPos<BPosT,NPosT>::MPos(Args&&... args, const NPosT& next) :
BPosT(args...), mNext(next)
{ {
return mFirst.val(); static_assert(is_scalar_pos_type<BPosT>::value,
"MPos has to be derived from scalar pos type");
} }
template <class PosT1, class PosT2> template <class BPosT, class NPosT>
constexpr const PosT1& MPos<PosT1,PosT2>::first() const template <typename... Args>
constexpr MPos<BPosT,NPosT>::MPos(Args&&... args, NPosT&& next) :
BPosT(args...), mNext(next)
{ {
return mFirst; static_assert(is_scalar_pos_type<BPosT>::value,
"MPos has to be derived from scalar pos type");
} }
template <class PosT1, class PosT2> template <class BPosT, class NPosT>
constexpr const PosT2& MPos<PosT1,PosT2>::next() const constexpr SizeT MPos<BPosT,NPosT>::size() const
{
return BPosT::size() + mNext.size();
}
template <class BPosT, class NPosT>
constexpr const NPos& MPos<BPosT,NPosT>::next() const
{ {
return mNext; return mNext;
} }
template <class PosT1, class PosT2> template <class BPosT, class NPosT>
template <class PosT3, class PosT4> template <class PosT>
constexpr auto MPos<PosT1,PosT2>::operator+(const MPos<PosT3,PosT4>& a) const constexpr auto MPos<BPosT,NPosT>::operator+(const PosT& a) const
{ {
typedef decltype(first()+a.first()) PosT5; typedef decltype(BPosT::operator+(a)) OBPosT;
typedef decltype(next()+a.next()) PosT6; typedef decltype(mNext + a.next()) ONPosT;
return MPos<PosT5,PosT6>(first()+a.first(), next()+a.next()); return MPos<OBPosT,ONPosT>( BPosT::operator+(a), mNext + a.next() );
} }
template <class PosT1, class PosT2> template <class BPosT, class NPosT>
template <class PosT3> template <class PosT>
constexpr auto MPos<PosT1,PosT2>::operator*(const CPosInterface<PosT3>& a) const constexpr auto MPos<BPosT,NPosT>::operator*(const PosT& a) const
{ {
typedef decltype(first()*a.THIS()) PosT5; typedef decltype(BPosT::operator*(a)) OBPosT;
typedef decltype(next()*a.THIS()) PosT6; typedef decltype(mNext * a.next()) ONPosT;
return MPos<PosT5,PosT6>(first()*a.THIS(), next()*a.THIS()); return MPos<OBPosT,ONPosT>( BPosT::operator*(a), mNext * a.next() );
} }
template <class PosT1, class PosT2> template <class BPosT, class NPosT>
template <class PosT3> template <class PosT>
constexpr auto MPos<PosT1,PosT2>::extend(const CPosInterface<PosT3>& p) const constexpr auto MPos<BPosT,NPosT>::operator()(const PosT& a) const
{ {
return MPos<MPos<PosT1,PosT2>,PosT3>(*this,p); typedef decltype(BPosT::operator()(a)) OBPosT;
typedef decltype(mNext(a.next())) ONPosT;
return MPos<OBPosT,ONPosT>( BPosT::operator()(a), mNext(a.next()) );
}
template <class BPosT, class NPosT>
template <class PosT>
constexpr auto MPos<BPosT,NPosT>::extend(const PosT& a) const
{
return mNext.extend(a);
} }
} }

View file

@ -6,44 +6,20 @@
namespace CNORXZ namespace CNORXZ
{ {
// shift to base.h
#define CXZ_CVAL_FALSE static constexpr bool value = false
#define CXZ_CVAL_TRUE static constexpr bool value = true
template <class PosT> template <class T>
class CPosInterface struct is_pos_type { CXZ_CVAL_FALSE; };
{
public:
static constexpr bool MULTI = PosT::MULTI;
DEFAULT_MEMBERS(CPosInterface); template <class T>
struct is_scalar_pos_type { CXZ_CVAL_FALSE; };
PosT& THIS() { return static_cast<PosT&>(*this); }
const PosT& THIS() const { return static_cast<const PosT&>(*this); }
inline SizeT size() const { return THIS().size(); }
inline auto val() const { return THIS().val(); }
// template!!!
inline CPosInterface<PosT> operator+(const CPosInterface<PosT>& a) const
{ return THIS() + a.THIS(); }
// template!!!
inline CPosInterface<PosT> operator*(const CPosInterface<PosT>& a) const
{ 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>
inline auto extend(const CPosInterface<P>& a) const { return THIS().extend(a); }
};
template <SizeT N> template <SizeT N>
class SPos : public CPosInterface<SPos<N>> class SPos
{ {
public: public:
static constexpr bool MULTI = false;
constexpr SPos() = default; constexpr SPos() = default;
constexpr SizeT size() const; constexpr SizeT size() const;
@ -53,21 +29,22 @@ namespace CNORXZ
constexpr auto operator+(const SPos<N1>& a) const; constexpr auto operator+(const SPos<N1>& a) const;
template <SizeT N1> template <SizeT N1>
constexpr auto operator*(const SPos<N1>& a) const; constexpr auto operator*(const SPos<N1>& a) const;
template <SizeT N1>
constexpr auto operator()(const SPos<N1>& a) const;
constexpr auto operator+(const UPos& a) const; constexpr auto operator+(const UPos& a) const;
constexpr auto operator*(const UPos& a) const; constexpr auto operator*(const UPos& a) const;
constexpr auto operator()(const UPos& a) const;
template <class PosT> template <class PosT>
constexpr auto extend(const CPosInterface<PosT>& a) const; constexpr auto extend(const PosT& a) const;
}; };
class UPos : public CPosInterface<UPos> class UPos
{ {
private: private:
SizeT mExt = 0; SizeT mExt = 0;
public: public:
static constexpr bool MULTI = false;
DEFAULT_MEMBERS(UPos); DEFAULT_MEMBERS(UPos);
constexpr UPos(SizeT ext); constexpr UPos(SizeT ext);
@ -76,25 +53,26 @@ namespace CNORXZ
constexpr const SizeT& val() const; constexpr const SizeT& val() const;
template <class PosT> template <class PosT>
constexpr UPos operator+(const CPosInterface<PosT>& a) const; constexpr UPos operator+(const PosT& a) const;
template <class PosT> template <class PosT>
constexpr UPos operator*(const CPosInterface<PosT>& a) const; constexpr UPos operator*(const PosT& a) const;
template <class PosT> template <class PosT>
constexpr auto extend(const CPosInterface<PosT>& y) const; constexpr UPos operator()(const PosT& a) const;
template <class PosT>
constexpr auto extend(const PosT& a) const;
}; };
class FPos : public CPosInterface<FPos> class FPos
{ {
private: private:
SizeT mExt = 0; SizeT mExt = 0;
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);
@ -103,21 +81,22 @@ namespace CNORXZ
constexpr const SizeT& val() const; constexpr const SizeT& val() const;
template <class PosT1> template <class PosT1>
constexpr UPos operator+(const CPosInterface<PosT1>& a) const; constexpr UPos operator+(const PosT1& a) const;
template <class PosT1> template <class PosT1>
constexpr UPos operator*(const CPosInterface<PosT1>& a) const; constexpr FPos operator*(const PosT1& a) const;
template <class PosT>
constexpr UPos operator()(const PosT& a) const;
template <class PosT1> template <class PosT1>
constexpr auto extend(const CPosInterface<PosT1>& a) const; constexpr auto extend(const PosT1& a) const;
}; };
template <SizeT N, SizeT... Ms> template <SizeT N, SizeT... Ms>
class SFPos : public CPosInterface<SFPos<N,Ms...>> class SFPos
{ {
public: public:
static constexpr bool MULTI = false;
constexpr SFPos() = default; constexpr SFPos() = default;
constexpr SizeT size() const; constexpr SizeT size() const;
@ -127,101 +106,57 @@ namespace CNORXZ
constexpr auto operator+(const SPos<N1>& a) const; constexpr auto operator+(const SPos<N1>& a) const;
template <SizeT N1> template <SizeT N1>
constexpr auto operator*(const SPos<N1>& a) const; constexpr auto operator*(const SPos<N1>& a) const;
template <SizeT N1>
constexpr auto operator()(const SPos<N1>& a) const;
constexpr auto operator+(const UPos& a) const; constexpr auto operator+(const UPos& a) const;
constexpr auto operator*(const UPos& a) const; constexpr auto operator*(const UPos& a) const;
constexpr auto operator()(const UPos& a) const;
template <class PosT> template <class PosT>
constexpr auto extend(const CPosInterface<PosT>& a) const; constexpr auto extend(const PosT& a) const;
}; };
class DPos : public ObjHandle<VPosBase>, template <class BPosT, class NPosT>
public CPosInterface<DPos> class MPos : public BPosT // BPos should be a SCALAR PosT (NO MPos!)
{ {
protected:
NPosT mNext;
public: public:
static constexpr bool MULTI = true; constexpr MPos()
DEFAULT_MEMBERS(DPos); template <typename... Args>
inline DPos(Uptr<VPosBase>&& a); constexpr MPos(Args&&... args, const NPosT& next);
template <class PosT> template <typename... Args>
inline DPos(const CPosInterface<PosT>& a); constexpr MPos(Args&&... args, NPosT&& next);
inline SizeT size() const;
inline SizeT val() const;
inline DPosRef first() const;
inline DPosRef next() const;
template <class PosT1>
inline DPos operator+(const CPosInterface<PosT1>& a) const;
template <class PosT1>
inline DPos operator*(const CPosInterface<PosT1>& a) const;
template <class PosT1>
inline DPos extend(const CPosInterface<PosT1>& a) const;
};
class DPosRef : public CPosInterface<DPosRef>
{
private:
const VPosBase* mC;
public:
static constexpr bool MULTI = true;
DEFAULT_MEMBERS(DPosRef);
inline DPosRef(const VPosBase* c);
inline SizeT size() const;
inline SizeT val() const;
inline DPosRef first() const;
inline DPosRef next() const;
template <class PosT1>
inline DPos operator+(const CPosInterface<PosT1>& a) const;
template <class PosT1>
inline DPos operator*(const CPosInterface<PosT1>& a) const;
template <class PosT1>
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>
class MPos : public CPosInterface<MPos<PosT1,PosT2>>
{
private:
PosT1 mFirst;
PosT2 mNext;
public:
static constexpr bool MULTI = true;
DEFAULT_MEMBERS(MPos);
constexpr MPos(const CPosInterface<PosT1>& first,
const CPosInterface<PosT2>& next);
constexpr SizeT size() const; constexpr SizeT size() const;
constexpr auto val() const; constexpr const NPos& next() const;
constexpr const PosT1& first() const;
constexpr const PosT2& next() const;
template <class PosT3, class PosT4> template <class PosT>
constexpr auto operator+(const MPos<PosT3,PosT4>& a) const; constexpr auto operator+(const PosT& a) const;
template <class PosT3> template <class PosT>
constexpr auto operator*(const CPosInterface<PosT3>& a) const; constexpr auto operator*(const PosT& a) const;
template <class PosT3> // same as operator*, except for FPos/SFPos, where map is executed
constexpr auto extend(const CPosInterface<PosT3>& p) const; template <class PosT>
constexpr auto operator()(const PosT& a) const;
template <class PosT>
constexpr auto extend(const PosT& a) const;
}; };
template <SizeT N> struct is_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
template <SizeT N> struct is_scalar_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
template <> struct is_pos_type<UPos> { CXZ_CVAL_TRUE; };
template <> struct is_scalar_pos_type<UPos> { CXZ_CVAL_TRUE; };
template <> struct is_pos_type<FPos> { CXZ_CVAL_TRUE; };
template <> struct is_scalar_pos_type<FPos> { CXZ_CVAL_TRUE; };
template <SizeT N, SizeT... Ms> struct is_pos_type<SFPos<N,Ms...>> { CXZ_CVAL_TRUE; };
template <SizeT N, SizeT... Ms> struct is_scalar_pos_type<SFPos<N,Ms...>> { CXZ_CVAL_TRUE; };
template <class BPosT, class NPosT> struct is_pos_type<MPos<BPosT,NPosT>> { CXZ_CVAL_TRUE; };
} // end namespace CNORXZInternal } // end namespace CNORXZInternal