From a142fdb466daa73e30f68d76a919fee05d2ff24f Mon Sep 17 00:00:00 2001 From: Christian Zimmermann <christian.zimmermann@ur.de> Date: Thu, 6 Oct 2022 18:32:56 +0200 Subject: [PATCH] im com --- src/include/ranges/xfor/pos_type.cc.h | 241 +++++++++++--------------- src/include/ranges/xfor/pos_type.h | 203 ++++++++-------------- 2 files changed, 166 insertions(+), 278 deletions(-) diff --git a/src/include/ranges/xfor/pos_type.cc.h b/src/include/ranges/xfor/pos_type.cc.h index 6d3a562..0a596e6 100644 --- a/src/include/ranges/xfor/pos_type.cc.h +++ b/src/include/ranges/xfor/pos_type.cc.h @@ -37,6 +37,13 @@ namespace CNORXZ 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> constexpr auto SPos<N>::operator+(const UPos& a) const { @@ -49,9 +56,15 @@ namespace CNORXZ 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 <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); } @@ -73,19 +86,25 @@ namespace CNORXZ } 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()); } 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()); } 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); } @@ -107,19 +126,25 @@ namespace CNORXZ } 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()); } + template <class PosT> + constexpr FPos UPos::operator*(const PosT& in) const + { + return FPos(mExt * in.val(), mMap); + } + 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()]); } 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); } @@ -150,6 +175,13 @@ namespace CNORXZ template <SizeT N, SizeT... Ms> template <SizeT N1> 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... }); return SPos<N*std::get<a.val()>(ms)>(); @@ -162,7 +194,15 @@ namespace CNORXZ } template <SizeT N, SizeT... Ms> + template <SizeT N1> 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... }); return UPos(N * ms[a.val()]); @@ -170,171 +210,84 @@ namespace CNORXZ template <SizeT N, SizeT... Ms> 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); } - - /************ - * 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 * ************/ - template <class PosT1, class PosT2> - constexpr MPos<PosT1,PosT2>::MPos(const CPosInterface<PosT1>& first, - const CPosInterface<PosT2>& next) : - mFirst(first.THIS()), mNext(next.THIS()) - {} - - template <class PosT1, class PosT2> - constexpr SizeT MPos<PosT1,PosT2>::size() const + template <class BPosT, class NPosT> + constexpr MPos<BPosT,NPosT>::MPos() { - 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> - constexpr auto MPos<PosT1,PosT2>::val() const + template <class BPosT, class NPosT> + 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> - constexpr const PosT1& MPos<PosT1,PosT2>::first() const + template <class BPosT, class NPosT> + 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> - constexpr const PosT2& MPos<PosT1,PosT2>::next() const + template <class BPosT, class NPosT> + 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; } - template <class PosT1, class PosT2> - template <class PosT3, class PosT4> - constexpr auto MPos<PosT1,PosT2>::operator+(const MPos<PosT3,PosT4>& a) const + template <class BPosT, class NPosT> + template <class PosT> + constexpr auto MPos<BPosT,NPosT>::operator+(const PosT& a) const { - typedef decltype(first()+a.first()) PosT5; - typedef decltype(next()+a.next()) PosT6; - return MPos<PosT5,PosT6>(first()+a.first(), next()+a.next()); + typedef decltype(BPosT::operator+(a)) OBPosT; + typedef decltype(mNext + a.next()) ONPosT; + return MPos<OBPosT,ONPosT>( BPosT::operator+(a), mNext + a.next() ); } - template <class PosT1, class PosT2> - template <class PosT3> - constexpr auto MPos<PosT1,PosT2>::operator*(const CPosInterface<PosT3>& a) const + template <class BPosT, class NPosT> + template <class PosT> + constexpr auto MPos<BPosT,NPosT>::operator*(const PosT& a) const { - typedef decltype(first()*a.THIS()) PosT5; - typedef decltype(next()*a.THIS()) PosT6; - return MPos<PosT5,PosT6>(first()*a.THIS(), next()*a.THIS()); + typedef decltype(BPosT::operator*(a)) OBPosT; + typedef decltype(mNext * a.next()) ONPosT; + return MPos<OBPosT,ONPosT>( BPosT::operator*(a), mNext * a.next() ); } - template <class PosT1, class PosT2> - template <class PosT3> - constexpr auto MPos<PosT1,PosT2>::extend(const CPosInterface<PosT3>& p) const + template <class BPosT, class NPosT> + template <class PosT> + 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); } } diff --git a/src/include/ranges/xfor/pos_type.h b/src/include/ranges/xfor/pos_type.h index 5365bc6..827c45a 100644 --- a/src/include/ranges/xfor/pos_type.h +++ b/src/include/ranges/xfor/pos_type.h @@ -6,68 +6,45 @@ 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 T> + struct is_pos_type { CXZ_CVAL_FALSE; }; - template <class PosT> - class CPosInterface - { - public: - static constexpr bool MULTI = PosT::MULTI; - - DEFAULT_MEMBERS(CPosInterface); - - 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 <class T> + struct is_scalar_pos_type { CXZ_CVAL_FALSE; }; + template <SizeT N> - class SPos : public CPosInterface<SPos<N>> + class SPos { public: - static constexpr bool MULTI = false; - constexpr SPos() = default; constexpr SizeT size() const; constexpr SizeT val() const; - + template <SizeT N1> constexpr auto operator+(const SPos<N1>& a) const; template <SizeT N1> 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; + 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: SizeT mExt = 0; public: - static constexpr bool MULTI = false; - DEFAULT_MEMBERS(UPos); constexpr UPos(SizeT ext); @@ -76,25 +53,26 @@ namespace CNORXZ constexpr const SizeT& val() const; template <class PosT> - constexpr UPos operator+(const CPosInterface<PosT>& a) const; + constexpr UPos operator+(const PosT& a) const; template <class PosT> - constexpr UPos operator*(const CPosInterface<PosT>& a) const; - + constexpr UPos operator*(const PosT& a) const; + + template <class PosT> + constexpr UPos operator()(const PosT& a) const; + template <class PosT> - constexpr auto extend(const CPosInterface<PosT>& y) const; + constexpr auto extend(const PosT& a) const; }; - - class FPos : public CPosInterface<FPos> + + class FPos { private: SizeT mExt = 0; const SizeT* mMap = nullptr; public: - static constexpr bool MULTI = false; - DEFAULT_MEMBERS(FPos); inline FPos(SizeT ext, const SizeT* map); @@ -103,21 +81,22 @@ namespace CNORXZ constexpr const SizeT& val() const; template <class PosT1> - constexpr UPos operator+(const CPosInterface<PosT1>& a) const; + constexpr UPos operator+(const PosT1& a) const; 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> - constexpr auto extend(const CPosInterface<PosT1>& a) const; + constexpr auto extend(const PosT1& a) const; }; template <SizeT N, SizeT... Ms> - class SFPos : public CPosInterface<SFPos<N,Ms...>> + class SFPos { public: - static constexpr bool MULTI = false; - constexpr SFPos() = default; constexpr SizeT size() const; @@ -127,101 +106,57 @@ namespace CNORXZ constexpr auto operator+(const SPos<N1>& a) const; template <SizeT N1> 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; template <class PosT> - constexpr auto extend(const CPosInterface<PosT>& a) const; - }; - - class DPos : public ObjHandle<VPosBase>, - public CPosInterface<DPos> - { - public: - static constexpr bool MULTI = true; - - DEFAULT_MEMBERS(DPos); - inline DPos(Uptr<VPosBase>&& a); - - template <class PosT> - inline DPos(const CPosInterface<PosT>& a); - - 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; + constexpr auto extend(const PosT& 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>> + template <class BPosT, class NPosT> + class MPos : public BPosT // BPos should be a SCALAR PosT (NO MPos!) { - private: - - PosT1 mFirst; - PosT2 mNext; - + protected: + NPosT mNext; public: - static constexpr bool MULTI = true; + constexpr MPos() - DEFAULT_MEMBERS(MPos); - - constexpr MPos(const CPosInterface<PosT1>& first, - const CPosInterface<PosT2>& next); + template <typename... Args> + constexpr MPos(Args&&... args, const NPosT& next); + + template <typename... Args> + constexpr MPos(Args&&... args, NPosT&& next); constexpr SizeT size() const; - constexpr auto val() const; - constexpr const PosT1& first() const; - constexpr const PosT2& next() const; + constexpr const NPos& next() const; - template <class PosT3, class PosT4> - constexpr auto operator+(const MPos<PosT3,PosT4>& a) const; + template <class PosT> + constexpr auto operator+(const PosT& a) const; - template <class PosT3> - constexpr auto operator*(const CPosInterface<PosT3>& a) const; + template <class PosT> + constexpr auto operator*(const PosT& a) const; - template <class PosT3> - constexpr auto extend(const CPosInterface<PosT3>& p) const; + // same as operator*, except for FPos/SFPos, where map is executed + 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