From 18748a651a2d63c7b1dbd8038373e40034daaa28 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Wed, 24 Jul 2024 19:06:43 +0200 Subject: [PATCH] WIP: correct / improve epos operations --- src/include/xpr/pos_type.cc.h | 81 ++++++++++++++++++++++++----------- src/include/xpr/pos_type.h | 6 ++- 2 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/include/xpr/pos_type.cc.h b/src/include/xpr/pos_type.cc.h index a4ff1a0..b1fec7b 100644 --- a/src/include/xpr/pos_type.cc.h +++ b/src/include/xpr/pos_type.cc.h @@ -46,7 +46,7 @@ namespace CNORXZ constexpr decltype(auto) SPos::operator+(const PosT& a) const { if constexpr(is_epos_type::value){ - a+(*this); + return mkEPos::value>(*this,SPos<0>{}) + a; } else if constexpr(is_static_pos_type::value){ return SPos{}; @@ -132,7 +132,7 @@ namespace CNORXZ constexpr UPos UPos::operator+(const PosT& in) const { if constexpr(is_epos_type::value){ - return in+(*this); + return mkEPos::value>(*this,SPos<0>{}) + in; } else { return UPos(mExt + in.val()); @@ -149,7 +149,7 @@ namespace CNORXZ constexpr decltype(auto) UPos::operator*(const PosT& in) const { if constexpr(is_epos_type::value){ - return in*(*this); + return mkEPos::value>(*this,SPos<0>{}) * in; } else { if constexpr(std::is_same>::value){ @@ -165,7 +165,8 @@ namespace CNORXZ constexpr decltype(auto) UPos::operator()(const PosT& in) const { if constexpr(is_epos_type::value){ - return in*(*this); + return mkEPos::value>(*this,SPos<0>{}) * in; + //return in*(*this); } else { if constexpr(std::is_same>::value){ @@ -686,33 +687,68 @@ namespace CNORXZ constexpr EPos::EPos(const BPosT& b, const OPosTs&... os) : BPosT(b), mP(os...) - {} + { + static_assert(static_pos_size::value == 1, "only single pos types allowed"); + static_assert(((static_pos_size::value == 1) and ...), "only single pos types allowed"); + } template constexpr EPos::EPos(BPosT&& b, OPosTs&&... os) : BPosT(b), mP(os...) - {} + { + static_assert(static_pos_size::value == 1, "only single pos types allowed"); + static_assert(((static_pos_size::value == 1) and ...), "only single pos types allowed"); + } + // TODO: transform to trivial epos if not epos!!! template template constexpr decltype(auto) EPos::operator+(const PosT& a) const { - return iter<0,sizeof...(OPosTs)> - ( [&](auto i) { return std::get(mP); }, - [&](const auto&... e) { return EPos - (BPosT::operator+(a),e...); } ); + static_assert(static_pos_size::value == 1, "only single pos types allowed"); + static_assert(((static_pos_size::value == 1) and ...), "only single pos types allowed"); + if constexpr(is_epos_type::value){ + return iter<0,sizeof...(OPosTs)> + ( [&](auto i) { return std::get(mP)+a.template get(); }, + [&](const auto&... e) { return epos(BPosT::operator+(a),e...); } ); + } + else { + auto ax = mkEPos(a,a*SPos<0>{}); + return iter<0,sizeof...(OPosTs)> + ( [&](auto i) { return std::get(mP)+ax.template get(); }, + [&](const auto&... e) { return epos(BPosT::operator+(ax),e...); } ); + } } template template constexpr decltype(auto) EPos::operator*(const PosT& a) const { + static_assert(static_pos_size::value == 1, "only single pos types allowed"); + static_assert(((static_pos_size::value == 1) and ...), "only single pos types allowed"); + if constexpr(is_epos_type::value){ + return iter<0,sizeof...(OPosTs)> + ( [&](auto i) { auto x = scal(); auto y = a.scal(); + auto q = std::get(mP); auto p = a.template get(); + return x*p+q*(y+p); }, + [&](const auto&... e) { return epos(BPosT::operator*(a.scal()),e...); } ); + } + else { + auto ax = mkEPos(a,a*SPos<0>{}); + return iter<0,sizeof...(OPosTs)> + ( [&](auto i) { auto x = scal(); auto y = ax.scal(); + auto q = std::get(mP); auto p = ax.template get(); + return x*p+q*(y+p); }, + [&](const auto&... e) { return epos(BPosT::operator*(a),e...); } ); + } + /* return iter<0,sizeof...(OPosTs)> ( [&](auto i) { return std::get(mP); }, [&](const auto&... e) { return EPos (BPosT::operator*(a),e*a...); } ); + */ } template @@ -733,13 +769,6 @@ namespace CNORXZ return ival(std::index_sequence_for{}); } - /* - template - constexpr decltype(auto) EPos::next() const - { - return inext(std::index_sequence_for{}); - } - */ template constexpr decltype(auto) EPos::scal() const { @@ -764,15 +793,14 @@ namespace CNORXZ return Arr { (BPosT::val()+std::get(mP).val())... }; } } - /* + template - template - constexpr decltype(auto) EPos::inext(std::index_sequence is) const + constexpr decltype(auto) epos(const BPosT& b, const OPosTs&... os) { - typedef EPos(mP).next())...> OEPosT; - return OEPosT(BPosT::next(), std::get(mP).next()...); + return EPos(b,os...); } - */ + + /*===============================+ | Traits and Helper-Classes | +===============================*/ @@ -780,6 +808,8 @@ namespace CNORXZ template decltype(auto) MkEPos::mk(const BPosT& a, const OPosT& b) { + static_assert(static_pos_size::value == 1, "only single pos types allowed"); + static_assert(static_pos_size::value == 1, "only single pos types allowed"); return mkiEPos(a, b, std::make_index_sequence{}); } @@ -788,8 +818,9 @@ namespace CNORXZ { const BPosT& ax = static_cast(a); const OPosT& bx = static_cast(b); - return MPos(ax,bx)),decltype(mkEPos(a.next(),b.next()))> - (mkEPos(ax,bx), mkEPos(a.next(),b.next())); + typedef decltype(mkEPos(ax,bx)) T1; + typedef decltype(mkEPos(a.next(),b.next())) T2; + return MPos(mkEPos(ax,bx), mkEPos(a.next(),b.next())); } template diff --git a/src/include/xpr/pos_type.h b/src/include/xpr/pos_type.h index e07a61b..d9a9a56 100644 --- a/src/include/xpr/pos_type.h +++ b/src/include/xpr/pos_type.h @@ -307,14 +307,16 @@ namespace CNORXZ constexpr decltype(auto) operator()(const PosT& a) const; constexpr decltype(auto) val() const; - //constexpr decltype(auto) next() const; - constexpr decltype(auto) scal() const; template constexpr decltype(auto) get() const; }; + template + constexpr decltype(auto) epos(const BPosT& b, const OPosTs&... os); + + /*===============================+ | Traits and Helper-Classes | +===============================*/