more on extensions...
This commit is contained in:
parent
cf7dcb816b
commit
fbfd84f421
4 changed files with 379 additions and 121 deletions
|
@ -6,41 +6,60 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
inline decltype(auto) MkConsecutive<Double,AVX_SIZE/sizeof(Double)>::make(const Double* d)
|
constexpr decltype(auto) PlusCC<Double,Double,ND>::eval(const Consecutive<Double,ND>& a,
|
||||||
|
const Consecutive<Double,ND>& b)
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<const AVX::ConsecutiveD*>( d );
|
Consecutive<Double,ND> o;
|
||||||
|
__m256d av = _mm256_load_pd(a.mD);
|
||||||
|
__m256d bv = _mm256_load_pd(b.mD);
|
||||||
|
__m256d ov = _mm256_add_pd(av, bv);
|
||||||
|
_mm256_store_pd(o.mD, ov);
|
||||||
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline decltype(auto) MkConsecutive<Double,AVX_SIZE/sizeof(Double)>::make(Double* d)
|
constexpr decltype(auto) PlusCC<Double,Double,ND>::aeval(Consecutive<Double,ND>& a,
|
||||||
|
const Consecutive<Double,ND>& b)
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<AVX::ConsecutiveD*>( d );
|
__m256d av = _mm256_load_pd(a.mD);
|
||||||
}
|
__m256d bv = _mm256_load_pd(b.mD);
|
||||||
|
__m256d ov = _mm256_add_pd(av, bv);
|
||||||
template <typename... Args>
|
_mm256_store_pd(a.mD, ov);
|
||||||
inline decltype(auto) MkConsecutive<Double,AVX_SIZE/sizeof(Double)>::makeA(Args&&... args)
|
return a;
|
||||||
{
|
|
||||||
static_assert(sizeof...(Args) == AVX_SIZE/sizeof(Double),
|
|
||||||
"got inconsistent number of arguments");
|
|
||||||
return AVX::ConsecutiveD { _mm256_setr_pd(args...); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline decltype(auto) MkConsecutive<Int,AVX_SIZE/sizeof(Int)>::make(const Int* d)
|
template <typename X>
|
||||||
|
static constexpr decltype(auto)
|
||||||
|
PlusCX<Double,X,ND>::eval(const Consecutive<Double,ND>& a, const X& b)
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<const AVX::ConsecutiveI*>( d );
|
Consecutive<Double,ND> o;
|
||||||
|
__m256d av = _mm256_load_pd(a.mD);
|
||||||
|
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||||
|
__m256d ov = _mm256_add_pd(av, bv);
|
||||||
|
_mm256_store_pd(o.mD, ov);
|
||||||
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline decltype(auto) MkConsecutive<Int,AVX_SIZE/sizeof(Int)>::make(Int* d)
|
template <typename X>
|
||||||
|
static constexpr decltype(auto)
|
||||||
|
PlusCX<Double,X,ND>::aeval(Consecutive<Double,ND>& a, const X& b)
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<AVX::ConsecutiveI*>( d );
|
__m256d av = _mm256_load_pd(a.mD);
|
||||||
|
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||||
|
__m256d ov = _mm256_add_pd(av, bv);
|
||||||
|
_mm256_store_pd(a.mD, ov);
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename X>
|
||||||
inline decltype(auto) MkConsecutive<Int,AVX_SIZE/sizeof(Int)>::makeA(Args&&... args)
|
static constexpr decltype(auto)
|
||||||
|
PlusCX<Double,X,ND>::eval(const X& a, const Consecutive<Double,ND>& b)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Int) == 32/8, "lib error: Int size has changed");
|
Consecutive<Double,ND> o;
|
||||||
static_assert(sizeof...(Args) == AVX_SIZE/sizeof(Int),
|
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
|
||||||
"got inconsistent number of arguments");
|
__m256d bv = _mm256_load_pd(b.mD);
|
||||||
return AVX::ConsecutiveI { _mm256_setr_epi32(args...); }
|
__m256d ov = _mm256_add_pd(av, bv);
|
||||||
|
_mm256_store_pd(o.mD, ov);
|
||||||
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,40 +12,31 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace AVX
|
namespace AVX
|
||||||
{
|
{
|
||||||
// define for all types that are defined in base/types.h
|
static constexpr SizeT ND = AVX_VSIZE/sizeof(Double);
|
||||||
struct ConsecutiveD
|
|
||||||
{
|
|
||||||
__m256d mD;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ConsecutiveI
|
|
||||||
{
|
|
||||||
__m256i mD;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct MkConsecutive<Double,AVX_SIZE/sizeof(Double)>
|
struct PlusCC<Double,Double,ND>
|
||||||
{
|
{
|
||||||
static inline decltype(auto) make(const Double* d);
|
static constexpr decltype(auto)
|
||||||
|
eval(const Consecutive<Double,ND>& a, const Consecutive<Double,ND>& b);
|
||||||
|
|
||||||
static inline decltype(auto) make(Double* d);
|
static constexpr decltype(auto)
|
||||||
|
aeval(Consecutive<Double,ND>& a, const Consecutive<Double,ND>& b);
|
||||||
template <typename... Args>
|
|
||||||
static inline decltype(auto) makeA(Args&&... args);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <typename X>
|
||||||
struct MkConsecutive<Double,AVX_SIZE/sizeof(Int)>
|
struct PlusCX<Double,X,ND>
|
||||||
{
|
{
|
||||||
static inline decltype(auto) make(const Int* d);
|
static constexpr decltype(auto)
|
||||||
|
eval(const Consecutive<Double,ND>& a, const X& b);
|
||||||
|
|
||||||
static inline decltype(auto) make(Int* d);
|
static constexpr decltype(auto)
|
||||||
|
aeval(Consecutive<Double,ND>& a, const X& b);
|
||||||
|
|
||||||
template <typename... Args>
|
static constexpr decltype(auto)
|
||||||
static inline decltype(auto) makeA(Args&&... args);
|
eval(const X& a, const Consecutive<Double,ND>& b);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,31 +7,12 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
template <typename T, SizeT N>
|
|
||||||
inline decltype(auto) MkConsecutive<T,N>::make(const T* d)
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<const Consecutive<T,N>*>(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
|
||||||
inline decltype(auto) MkConsecutive<T,N>::make(T* d)
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<Consecutive<T,N>*>(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
|
||||||
template <typename... Args>
|
|
||||||
inline decltype(auto) MkConsecutive<T,N>::makeA(Args&&... args)
|
|
||||||
{
|
|
||||||
return Consecutive<T,N> { args... };
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class EPosT, SizeT... Is>
|
template <typename T, class EPosT, SizeT... Is>
|
||||||
inline decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence<Is...> is)
|
inline decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence<Is...> is)
|
||||||
{
|
{
|
||||||
constexpr SizeT N = epos_size<EPosT>::value;
|
constexpr SizeT N = epos_size<EPosT>::value;
|
||||||
static_assert(N == sizeof...(Is), "got inconsistent index sequence");
|
static_assert(N == sizeof...(Is), "got inconsistent index sequence");
|
||||||
return MkConsecutive<T,N>::makeA( d[pos.val()+pos.template get<Is>().val()]... );
|
return Consecutive<T,N> { args... };
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class EPosT>
|
template <typename T, class EPosT>
|
||||||
|
@ -40,7 +21,7 @@ namespace CNORXZ
|
||||||
constexpr SizeT N = epos_size<EPosT>::value;
|
constexpr SizeT N = epos_size<EPosT>::value;
|
||||||
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
|
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
|
||||||
if constexpr(pos_type_is_consecutive<EPosT>::value){
|
if constexpr(pos_type_is_consecutive<EPosT>::value){
|
||||||
return MkConsecutive<T,N>::make(d+pos.val()+pos.template get<0>().val());
|
return *reinterpret_cast<const Consecutive<T,N>*>(d);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return vregi(d, pos, std::make_index_sequence<N>{});
|
return vregi(d, pos, std::make_index_sequence<N>{});
|
||||||
|
@ -53,13 +34,218 @@ namespace CNORXZ
|
||||||
constexpr SizeT N = epos_size<EPosT>::value;
|
constexpr SizeT N = epos_size<EPosT>::value;
|
||||||
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
|
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
|
||||||
if constexpr(pos_type_is_consecutive<EPosT>::value){
|
if constexpr(pos_type_is_consecutive<EPosT>::value){
|
||||||
return MkConsecutive<T,N>::make(d+pos.val()+pos.template get<0>().val());
|
return *reinterpret_cast<Consecutive<T,N>*>(d);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return vregi(d, pos, std::make_index_sequence<N>{});
|
return vregi(d, pos, std::make_index_sequence<N>{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <SizeT I, typename T>
|
||||||
|
constexpr decltype(auto) consecGet(const T& a)
|
||||||
|
{
|
||||||
|
if constexpr(is_consecutive_type<T>::value){
|
||||||
|
static_assert(I < consecutive_size<T>::value,
|
||||||
|
"consecutive index out of range");
|
||||||
|
return a.mD[I];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <SizeT I, typename T>
|
||||||
|
constexpr decltype(auto) consecGet(T& a)
|
||||||
|
{
|
||||||
|
if constexpr(is_consecutive_type<T>::value){
|
||||||
|
static_assert(I < consecutive_size<T>::value,
|
||||||
|
"consecutive index out of range");
|
||||||
|
return a.mD[I];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <SizeT I, class F, typename... Args>
|
||||||
|
constexpr decltype(auto) consecApply(const F& f, const Args&... args)
|
||||||
|
{
|
||||||
|
return f( consecGet<I>(args)... );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <SizeT I, class F, typename Dst, typename... Args>
|
||||||
|
constexpr Dst& consecAssign(const F& f, Dst& dst, const Args&... args)
|
||||||
|
{
|
||||||
|
f( consecGet<I>(dst), consecGet<I>(args)... );
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, typename... Args, SizeT... Is>
|
||||||
|
static constexpr decltype(auto) consecFuncI(const F& f, const Args&... args,
|
||||||
|
std::index_sequence<Is...> is);
|
||||||
|
{
|
||||||
|
typedef decltype(consecApply<0>(f, args...)) OType;
|
||||||
|
constexpr SizeT N = sizeof...(Is);
|
||||||
|
return Consecutive<OType,N> { consecApply<Is>(f, args...) ... };
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, typename Dst, typename... Args, SizeT... Is>
|
||||||
|
constexpr Dst& consecFuncAI(const F& f, Dst& dst, const Args&... args,
|
||||||
|
std::index_sequence<Is...> is)
|
||||||
|
{
|
||||||
|
( consecAssign<Is>(f, dst, args...), ... );
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <SizeT N, class F, typename... Args>
|
||||||
|
constexpr decltype(auto) consecFunc(const F& f, const Args&... args)
|
||||||
|
{
|
||||||
|
return consecFuncI<F,Args...>(f, args..., std::make_index_sequence<N>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <SizeT N, class F, typename Dst, typename... Args>
|
||||||
|
constexpr Dst& consecFuncA(const F& f, Dst& dst, const Args&... args)
|
||||||
|
{
|
||||||
|
return consecFuncAI<F,Dst,Args...>(f, dst, args..., std::make_index_sequence<N>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* basic operations: plus *
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto)
|
||||||
|
PlusCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x + y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr Consecutive<T,N>&
|
||||||
|
PlusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||||
|
{
|
||||||
|
return consecFuncA( [](auto& x, const auto& y) { return x += y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename X, SizeT N>
|
||||||
|
constexpr decltype(auto) PlusCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x + y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename X, SizeT N>
|
||||||
|
constexpr decltype(auto) PlusCX<T,X,N>::eval(const X& a, const Consecutive<U,N>& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x + y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename X, SizeT N>
|
||||||
|
constexpr Consecutive<T,N>& PlusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
|
||||||
|
{
|
||||||
|
return consecFuncA( [](auto& x, const auto& y) { return x += y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* basic operations: minus *
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator-(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x - y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator-(const Consecutive<T,N>& a, const U& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x - y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator-(const T& a, const Consecutive<U,N>& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x - y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||||
|
{
|
||||||
|
return consecFuncA( [](auto& x, const auto& y) { return x -= y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const U& a)
|
||||||
|
{
|
||||||
|
return consecFuncA( [](auto& x, const auto& y) { return x -= y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************
|
||||||
|
* basic operations: muliplies *
|
||||||
|
***********************************/
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x * y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const U& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x * y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator*(const T& a, const Consecutive<U,N>& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x * y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||||
|
{
|
||||||
|
return consecFuncA( [](const auto& x, const auto& y) { return x *= y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const U& a)
|
||||||
|
{
|
||||||
|
return consecFuncA( [](const auto& x, const auto& y) { return x *= y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************
|
||||||
|
* basic operations: divides *
|
||||||
|
*********************************/
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator/(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x / y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator/(const Consecutive<T,N>& a, const U& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x / y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr decltype(auto) operator/(const T& a, const Consecutive<U,N>& b)
|
||||||
|
{
|
||||||
|
return consecFunc( [](const auto& x, const auto& y) { return x / y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||||
|
{
|
||||||
|
return consecFuncA( [](const auto& x, const auto& y) { return x /= y; }, a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const U& a)
|
||||||
|
{
|
||||||
|
return consecFuncA( [](const auto& x, const auto& y) { return x /= y; }, a, b );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
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
|
// no use of Arr = std::array here, since I want ensure that
|
||||||
// it has exactly a memory size of N
|
// it has exactly a memory size of N
|
||||||
template <typename T, SizeT N>
|
template <typename T, SizeT N>
|
||||||
|
@ -16,18 +15,23 @@ namespace CNORXZ
|
||||||
T mD[N];
|
T mD[N];
|
||||||
};
|
};
|
||||||
|
|
||||||
// specialize for all kinds of available vector registers:
|
template <typename T>
|
||||||
template <typename T, SizeT N>
|
struct is_consecutive_type { CXZ_CVAL_FALSE; };
|
||||||
struct MkConsecutive
|
|
||||||
{
|
|
||||||
static inline decltype(auto) make(const T* d);
|
|
||||||
|
|
||||||
static inline decltype(auto) make(T* d);
|
template <typename T>
|
||||||
|
struct consecutive_base { typedef T type; };
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename T>
|
||||||
static inline decltype(auto) makeA(Args&&... args);
|
struct consecutive_size { static constexpr SizeT value = 0; };
|
||||||
};
|
|
||||||
|
|
||||||
|
template <typename T, SizeT N>
|
||||||
|
struct is_consecutive_type<Consecutive<T,N>> { CXZ_CVAL_TRUE; };
|
||||||
|
|
||||||
|
template <typename T, SizeT N>
|
||||||
|
struct consecutive_base<Consecutive<T,N>> { typedef T type; };
|
||||||
|
|
||||||
|
template <typename T, SizeT N>
|
||||||
|
struct consecutive_size<Consecutive<T,N>> { static constexpr SizeT value = N; };
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
* consecutive generating functions *
|
* consecutive generating functions *
|
||||||
|
@ -42,81 +46,139 @@ namespace CNORXZ
|
||||||
template <typename T, class EPosT>
|
template <typename T, class EPosT>
|
||||||
inline decltype(auto) vreg(T* d, const EPosT& pos);
|
inline decltype(auto) vreg(T* d, const EPosT& pos);
|
||||||
|
|
||||||
|
/******************
|
||||||
|
* ConsecFunc *
|
||||||
|
******************/
|
||||||
|
|
||||||
|
template <SizeT I, typename T>
|
||||||
|
constexpr decltype(auto) consecGet(const T& a);
|
||||||
|
|
||||||
|
template <SizeT I, typename T>
|
||||||
|
constexpr decltype(auto) consecGet(T& a);
|
||||||
|
|
||||||
|
template <SizeT I, class F, typename... Args>
|
||||||
|
constexpr decltype(auto) consecApply(const F& f, const Args&... args);
|
||||||
|
|
||||||
|
template <SizeT I, class F, typename Dst, typename... Args>
|
||||||
|
constexpr Dst& consecAssign(const F& f, Dst& dst, const Args&... args);
|
||||||
|
|
||||||
|
template <class F, typename... Args, SizeT... Is>
|
||||||
|
constexpr decltype(auto) consecFuncI(const F& f, const Args&... args,
|
||||||
|
std::index_sequence<Is...> is);
|
||||||
|
|
||||||
|
template <class F, typename Dst, typename... Args, SizeT... Is>
|
||||||
|
constexpr Dst& consecFuncAI(const F& f, Dst& dst, const Args&... args,
|
||||||
|
std::index_sequence<Is...> is);
|
||||||
|
|
||||||
|
template <SizeT N, class F, typename... Args>
|
||||||
|
constexpr decltype(auto) consecFunc(const F& f, const Args&... args);
|
||||||
|
|
||||||
|
template <SizeT N, class F, typename Dst, typename... Args>
|
||||||
|
constexpr Dst& consecFuncA(const F& f, Dst& dst, const Args&... args);
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
* basic operations: plus *
|
* basic operations: plus *
|
||||||
******************************/
|
******************************/
|
||||||
|
|
||||||
|
template <typename T, typename U, SizeT N>
|
||||||
|
struct PlusCC
|
||||||
|
{
|
||||||
|
static constexpr decltype(auto)
|
||||||
|
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||||
|
|
||||||
|
static constexpr decltype(auto)
|
||||||
|
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename X, SizeT N>
|
||||||
|
struct PlusCX
|
||||||
|
{
|
||||||
|
static constexpr decltype(auto)
|
||||||
|
eval(const Consecutive<T,N>& a, const X& b);
|
||||||
|
|
||||||
|
static constexpr decltype(auto)
|
||||||
|
aeval(Consecutive<T,N>& a, const X& b);
|
||||||
|
|
||||||
|
static constexpr decltype(auto)
|
||||||
|
eval(const X& a, const Consecutive<T,N>& b);
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator+(const Consecutive<T,N>& a, const Consecutive<T,N>& b);
|
constexpr decltype(auto) operator+(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||||
|
{ return PlusCC<T,U,N>::eval(a,b); }
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator+(const Consecutive<T,N>& a, const T& b);
|
constexpr decltype(auto) operator+(const Consecutive<T,N>& a, const U& b)
|
||||||
|
{ return PlusCX<T,U,N>::eval(a,b); }
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator+(const T& a, const Consecutive<T,N>& b);
|
constexpr decltype(auto) operator+(const T& a, const Consecutive<U,N>& b)
|
||||||
|
{ return PlusCX<U,T,N>::eval(a,b); }
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator+=(const Consecutive<T,N>& a);
|
constexpr Consecutive<T,N>& operator+=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||||
|
{ return PlusCC<T,U,N>::aeval(a,b); }
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator+=(const T& a);
|
constexpr Consecutive<T,N>& operator+=(Consecutive<T,N>& o, const U& a)
|
||||||
|
{ return PlusCX<T,U,N>::aeval(a,b); }
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* basic operations: minus *
|
* basic operations: minus *
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator-(const Consecutive<T,N>& a, const Consecutive<T,N>& b);
|
constexpr decltype(auto) operator-(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator-(const Consecutive<T,N>& a, const T& b);
|
constexpr decltype(auto) operator-(const Consecutive<T,N>& a, const U& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator-(const T& a, const Consecutive<T,N>& b);
|
constexpr decltype(auto) operator-(const T& a, const Consecutive<U,N>& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator-=(const Consecutive<T,N>& a);
|
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const Consecutive<U,N>& a);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator-=(const T& a);
|
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const U& a);
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* basic operations: muliplies *
|
* basic operations: muliplies *
|
||||||
***********************************/
|
***********************************/
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator*(const Consecutive<T,N>& a, const Consecutive<T,N>& b);
|
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator*(const Consecutive<T,N>& a, const T& b);
|
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const U& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator*(const T& a, const Consecutive<T,N>& b);
|
constexpr decltype(auto) operator*(const T& a, const Consecutive<U,N>& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator*=(const Consecutive<T,N>& a);
|
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const Consecutive<U,N>& a);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator*=(const T& a);
|
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const U& a);
|
||||||
|
|
||||||
/*********************************
|
/*********************************
|
||||||
* basic operations: divides *
|
* basic operations: divides *
|
||||||
*********************************/
|
*********************************/
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator/(const Consecutive<T,N>& a, const Consecutive<T,N>& b);
|
constexpr decltype(auto) operator/(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator/(const Consecutive<T,N>& a, const T& b);
|
constexpr decltype(auto) operator/(const Consecutive<T,N>& a, const U& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator/(const T& a, const Consecutive<T,N>& b);
|
constexpr decltype(auto) operator/(const T& a, const Consecutive<U,N>& b);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator/=(const Consecutive<T,N>& a);
|
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const Consecutive<U,N>& a);
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, typename U, SizeT N>
|
||||||
constexpr Consecutive<T,N> operator/=(const T& a);
|
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const U& a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue