cnorxz/src/include/operation/extensions/reg.cc.h
Christian Zimmermann 8a0fdf7a7c
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
improve comment notation + add missing briefs
2024-02-03 23:21:40 +01:00

263 lines
8.6 KiB
C++

// -*- C++ -*-
/**
@file include/operation/extensions/reg.cc.h
@brief Register type template implementations.
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de
**/
#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>
inline 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 Consecutive<T,N> { d[pos.template get<Is>().val()]... };
}
template <typename T, class EPosT>
inline 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 Consecutive<T,N>*>(d+pos.scal().val());
}
else {
return vregi(d, pos, std::make_index_sequence<N>{});
}
}
template <typename T, class EPosT>
inline 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");
static_assert(pos_type_is_consecutive<EPosT>::value, "no write access for non-consecutive");
if constexpr(pos_type_is_consecutive<EPosT>::value){
return *reinterpret_cast<Consecutive<T,N>*>(d+pos.scal().val());
}
else {
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>
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<N>( [](const auto& x, const auto& y) { return x + y; }, a, b );
}
template <typename T, typename U, SizeT N>
constexpr decltype(auto)
PlusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA<N>( [](auto& x, const auto& y) { return x += y; }, o, a );
}
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<N>( [](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<T,N>& b)
{
return consecFunc<N>( [](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>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA<N>( [](auto& x, const auto& y) { return x += y; }, o, a );
}
/*=============================+
| basic operations: minus |
+=============================*/
template <typename T, typename U, SizeT N>
constexpr decltype(auto) MinusCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MinusCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MinusCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
}
template <typename T, typename U, SizeT N>
constexpr decltype(auto) MinusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA<N>( [](auto& x, const auto& y) { return x -= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MinusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA<N>( [](auto& x, const auto& y) { return x -= y; }, o, a );
}
/*=================================+
| basic operations: muliplies |
+=================================*/
template <typename T, typename U, SizeT N>
constexpr decltype(auto) MultipliesCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MultipliesCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MultipliesCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
}
template <typename T, typename U, SizeT N>
constexpr decltype(auto) MultipliesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA<N>( [](const auto& x, const auto& y) { return x *= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MultipliesCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA<N>( [](const auto& x, const auto& y) { return x *= y; }, o, a );
}
/*===============================+
| basic operations: divides |
+===============================*/
template <typename T, typename U, SizeT N>
constexpr decltype(auto) DividesCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) DividesCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) DividesCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
{
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
}
template <typename T, typename U, SizeT N>
constexpr decltype(auto) DividesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA<N>( [](const auto& x, const auto& y) { return x /= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) DividesCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA<N>( [](const auto& x, const auto& y) { return x /= y; }, o, a );
}
}
#endif