fixes + start extension code

This commit is contained in:
Christian Zimmermann 2022-10-24 18:34:11 +02:00
parent e2405738c1
commit 1befb14039
6 changed files with 118 additions and 14 deletions

View file

@ -1,6 +0,0 @@
#ifdef regFunc1
regFunc1(exp)
#endif

View file

@ -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 <typename T, class EPosT, SizeT... Is>
decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence<Is...> is)
{
constexpr SizeT N = epos_size<EPosT>::value;
static_assert(N == sizeof...(Is), "got inconsistent index sequence");
return PseudoReg<T,N> { d[pos.val()+pos.template get<Is>().val()]... };
}
template <typename T, class EPosT>
decltype(auto) vreg(const T* d, const EPosT& pos)
{
constexpr SizeT N = epos_size<EPosT>::value;
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
if constexpr(pos_type_is_consecutive<EPosT>::value){
return *reinterpret_cast<const PseudoReg<T,N>*>
(d+pos.val()+pos.template get<0>().val());
}
else {
return vregi(d, pos, std::make_index_sequence<N>{});
}
}
template <typename T, class EPosT>
decltype(auto) vreg(T* d, const EPosT& pos)
{
constexpr SizeT N = epos_size<EPosT>::value;
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
if constexpr(pos_type_is_consecutive<EPosT>::value){
return *reinterpret_cast<PseudoReg<T,N>*>
(d+pos.val()+pos.template get<0>().val());
}
else {
return vregi(d, pos, std::make_index_sequence<N>{});
}
}
}
#endif

View file

@ -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 <typename T, SizeT N>
struct PseudoReg
{
T mD[N];
};
template <typename T, class EPosT, SizeT... Is>
decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence<Is...> is);
// specialize for all kinds of available vector registers:
template <typename T, class EPosT>
decltype(auto) vreg(const T* d, const EPosT& pos);
// specialize for all kinds of available vector registers:
template <typename T, class EPosT>
decltype(auto) vreg(T* d, const EPosT& pos);
// TODO: Maybe specialize PseudoReg (-> Reg) itself (?)
}
#endif

View file

@ -149,7 +149,14 @@ namespace CNORXZ
constexpr decltype(auto) OpRoot<T,IndexT>::operator()(const PosT& pos) const
{
if constexpr(is_epos_type<PosT>::value){
return vreg(mData,pos); // distinguish between consecutive/non-consecutive
if constexpr(pos_type_is_consecutive<PosT>::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<const T*>(mData),pos);
}
}
else {
return mData[pos.val()];

View file

@ -527,6 +527,13 @@ namespace CNORXZ
return inext(std::index_sequence_for<OPosTs...>{});
}
template <class BPosT, class... OPosTs>
template <SizeT I>
constexpr decltype(auto) EPos<BPosT,OPosTs...>::get() const
{
return std::get<I>(mP);
}
template <class BPosT, class... OPosTs>
template <SizeT... Is>
constexpr decltype(auto) EPos<BPosT,OPosTs...>::ival(std::index_sequence<Is...> is) const
@ -564,11 +571,11 @@ namespace CNORXZ
}
template <class OPosT1, class OPosT2, class... OPosTs>
constexpr bool pos_type_consecutive_2<OPosT1,OPosT2,OPosTs...>::eval()
constexpr bool pos_types_consecutive_2<OPosT1,OPosT2,OPosTs...>::eval()
{
if constexpr(is_static_pos_type<OPosT1>::value and is_static_pos_type<OPosT2>::value){
if constexpr(sizeof...(OPosTs) != 0){
return OPosT1().val() < OPosT2().val() and pos_type_consecutive<OPosT2,OPosTs...>::value;
return OPosT1().val() < OPosT2().val() and pos_types_consecutive<OPosT2,OPosTs...>::value;
}
else {
return OPosT1().val() < OPosT2().val();

View file

@ -245,6 +245,9 @@ namespace CNORXZ
constexpr decltype(auto) val() const;
constexpr decltype(auto) next() const;
template <SizeT I>
constexpr decltype(auto) get() const;
};
/*********************************
@ -268,9 +271,15 @@ namespace CNORXZ
{
static constexpr SizeT value = is_pos_type<PosT>::value ? 1 : 0;
};
template <class PosT>
struct epos_size
{
static constexpr SizeT value = 0;
};
template <class OPosT1, class OPosT2, class... OPosTs>
struct pos_type_consecutive_2
struct pos_types_consecutive_2
{
private:
static constexpr bool eval();
@ -280,9 +289,9 @@ namespace CNORXZ
};
template <class OPosT1, class... OPosTs>
struct pos_type_consecutive
struct pos_types_consecutive
{
static constexpr bool value = sizeof...(OPosTs) == 0 ? is_pos_type<OPosT1>::value : pos_type_consecutive_2<OPosT1,OPosTs...>::value;
static constexpr bool value = sizeof...(OPosTs) == 0 ? is_pos_type<OPosT1>::value : pos_types_consecutive_2<OPosT1,OPosTs...>::value;
};
template <class OPosT1, class... OPosTs>
@ -295,7 +304,7 @@ namespace CNORXZ
static constexpr bool value = eval();
};
template <class PosT> struct pos_type_is_consecutive { CXZ_CVAL_FALSE; };
template <class PosT> struct pos_type_is_consecutive { CXZ_CVAL_TRUE; };
template <SizeT N, class BPosT, class OPosT>
decltype(auto) mkEPos(const BPosT& a, const OPosT& b);
@ -341,10 +350,16 @@ namespace CNORXZ
static constexpr SizeT value = static_pos_size<NPosT>::value + 1;
};
template <class BPosT, class... OPosTs>
struct epos_size<EPos<BPosT,OPosTs...>>
{
static constexpr SizeT value = sizeof...(OPosTs);
};
template <class BPosT, class... OPosTs>
struct pos_type_is_consecutive<EPos<BPosT,OPosTs...>>
{
static constexpr bool value = pos_type_is_consecutive<OPosTs...>::value;
static constexpr bool value = pos_types_consecutive<OPosTs...>::value;
};
} // end namespace CNORXZInternal