diff --git a/src/include/operation/extensions/math.h b/src/include/operation/extensions/math.h deleted file mode 100644 index b1f9183..0000000 --- a/src/include/operation/extensions/math.h +++ /dev/null @@ -1,6 +0,0 @@ - -#ifdef regFunc1 - -regFunc1(exp) - -#endif diff --git a/src/include/operation/extensions/reg.cc.h b/src/include/operation/extensions/reg.cc.h new file mode 100644 index 0000000..fc240c8 --- /dev/null +++ b/src/include/operation/extensions/reg.cc.h @@ -0,0 +1,48 @@ + +#ifndef __cxz_reg_cc_h__ +#define __cxz_reg_cc_h__ + +#include "reg.h" +#include "xpr/pos_type.h" + +namespace CNORXZ +{ + template + decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence is) + { + constexpr SizeT N = epos_size::value; + static_assert(N == sizeof...(Is), "got inconsistent index sequence"); + return PseudoReg { d[pos.val()+pos.template get().val()]... }; + } + + template + decltype(auto) vreg(const T* d, const EPosT& pos) + { + constexpr SizeT N = epos_size::value; + static_assert(is_epos_type::value, "got non-epos-type"); + if constexpr(pos_type_is_consecutive::value){ + return *reinterpret_cast*> + (d+pos.val()+pos.template get<0>().val()); + } + else { + return vregi(d, pos, std::make_index_sequence{}); + } + } + + template + decltype(auto) vreg(T* d, const EPosT& pos) + { + constexpr SizeT N = epos_size::value; + static_assert(is_epos_type::value, "got non-epos-type"); + if constexpr(pos_type_is_consecutive::value){ + return *reinterpret_cast*> + (d+pos.val()+pos.template get<0>().val()); + } + else { + return vregi(d, pos, std::make_index_sequence{}); + } + } + +} + +#endif diff --git a/src/include/operation/extensions/reg.h b/src/include/operation/extensions/reg.h new file mode 100644 index 0000000..8a84f71 --- /dev/null +++ b/src/include/operation/extensions/reg.h @@ -0,0 +1,33 @@ + +#ifndef __cxz_reg_h__ +#define __cxz_reg_h__ + +#include "base/base.h" + +namespace CNORXZ +{ + // pseudo extension type to be returned if extension vector of + // reuqired size is not available + // no use of Arr = std::array here, since I want ensure that + // it has exactly a memory size of N + template + struct PseudoReg + { + T mD[N]; + }; + + template + decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence is); + + // specialize for all kinds of available vector registers: + template + decltype(auto) vreg(const T* d, const EPosT& pos); + + // specialize for all kinds of available vector registers: + template + decltype(auto) vreg(T* d, const EPosT& pos); + + // TODO: Maybe specialize PseudoReg (-> Reg) itself (?) +} + +#endif diff --git a/src/include/operation/op_types.cc.h b/src/include/operation/op_types.cc.h index 6b327ff..45fd3b2 100644 --- a/src/include/operation/op_types.cc.h +++ b/src/include/operation/op_types.cc.h @@ -149,7 +149,14 @@ namespace CNORXZ constexpr decltype(auto) OpRoot::operator()(const PosT& pos) const { if constexpr(is_epos_type::value){ - return vreg(mData,pos); // distinguish between consecutive/non-consecutive + if constexpr(pos_type_is_consecutive::value){ + return vreg(mData,pos); + } + else { + // non-consecutive data cannot be directly accessed + // so there is no non-const (write) access! + return vreg(const_cast(mData),pos); + } } else { return mData[pos.val()]; diff --git a/src/include/xpr/pos_type.cc.h b/src/include/xpr/pos_type.cc.h index febcdb5..e472ded 100644 --- a/src/include/xpr/pos_type.cc.h +++ b/src/include/xpr/pos_type.cc.h @@ -527,6 +527,13 @@ namespace CNORXZ return inext(std::index_sequence_for{}); } + template + template + constexpr decltype(auto) EPos::get() const + { + return std::get(mP); + } + template template constexpr decltype(auto) EPos::ival(std::index_sequence is) const @@ -564,11 +571,11 @@ namespace CNORXZ } template - constexpr bool pos_type_consecutive_2::eval() + constexpr bool pos_types_consecutive_2::eval() { if constexpr(is_static_pos_type::value and is_static_pos_type::value){ if constexpr(sizeof...(OPosTs) != 0){ - return OPosT1().val() < OPosT2().val() and pos_type_consecutive::value; + return OPosT1().val() < OPosT2().val() and pos_types_consecutive::value; } else { return OPosT1().val() < OPosT2().val(); diff --git a/src/include/xpr/pos_type.h b/src/include/xpr/pos_type.h index 75b5610..152fbd4 100644 --- a/src/include/xpr/pos_type.h +++ b/src/include/xpr/pos_type.h @@ -245,6 +245,9 @@ namespace CNORXZ constexpr decltype(auto) val() const; constexpr decltype(auto) next() const; + + template + constexpr decltype(auto) get() const; }; /********************************* @@ -268,9 +271,15 @@ namespace CNORXZ { static constexpr SizeT value = is_pos_type::value ? 1 : 0; }; + + template + struct epos_size + { + static constexpr SizeT value = 0; + }; template - struct pos_type_consecutive_2 + struct pos_types_consecutive_2 { private: static constexpr bool eval(); @@ -280,9 +289,9 @@ namespace CNORXZ }; template - struct pos_type_consecutive + struct pos_types_consecutive { - static constexpr bool value = sizeof...(OPosTs) == 0 ? is_pos_type::value : pos_type_consecutive_2::value; + static constexpr bool value = sizeof...(OPosTs) == 0 ? is_pos_type::value : pos_types_consecutive_2::value; }; template @@ -295,7 +304,7 @@ namespace CNORXZ static constexpr bool value = eval(); }; - template struct pos_type_is_consecutive { CXZ_CVAL_FALSE; }; + template struct pos_type_is_consecutive { CXZ_CVAL_TRUE; }; template decltype(auto) mkEPos(const BPosT& a, const OPosT& b); @@ -341,10 +350,16 @@ namespace CNORXZ static constexpr SizeT value = static_pos_size::value + 1; }; + template + struct epos_size> + { + static constexpr SizeT value = sizeof...(OPosTs); + }; + template struct pos_type_is_consecutive> { - static constexpr bool value = pos_type_is_consecutive::value; + static constexpr bool value = pos_types_consecutive::value; }; } // end namespace CNORXZInternal