cnorxz/src/include/xpr/pos_type.h
Christian Zimmermann fcf6712912
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
WIP: doxy
2023-11-01 02:58:05 +01:00

441 lines
12 KiB
C++

#ifndef __cxz_pos_type_h__
#define __cxz_pos_type_h__
#include "base/base.h"
namespace CNORXZ
{
template <SizeT N>
class SPos
{
public:
constexpr SPos() = default;
constexpr SPos(const SPos& a) = default;
constexpr SPos(SPos&& a) = default;
constexpr SizeT size() const;
constexpr SizeT val() const;
template <SizeT N1>
constexpr auto operator+(const SPos<N1>& a) const;
template <SizeT N1>
constexpr auto operator-(const SPos<N1>& a) const;
template <SizeT N1>
constexpr auto operator*(const SPos<N1>& a) const;
template <SizeT N1>
constexpr auto operator()(const SPos<N1>& a) const;
constexpr auto operator+(const UPos& a) const;
constexpr auto operator*(const UPos& a) const;
constexpr auto operator()(const UPos& a) const;
template <class PosT>
constexpr decltype(auto) extend(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator UPos() const;
explicit constexpr operator SizeT() const;
};
class UPos
{
private:
SizeT mExt = 0;
public:
DEFAULT_MEMBERS(UPos);
constexpr UPos(SizeT ext);
constexpr SizeT size() const;
constexpr const SizeT& val() const;
template <class PosT>
constexpr UPos operator+(const PosT& a) const;
template <class PosT>
constexpr UPos operator-(const PosT& a) const;
constexpr SPos<0> operator*(const SPos<0>& a) const;
template <class PosT>
constexpr UPos operator*(const PosT& a) const;
constexpr SPos<0> operator()(const SPos<0>& a) const;
template <class PosT>
constexpr UPos operator()(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) extend(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator SizeT() const;
};
class FPos
{
private:
SizeT mExt = 0;
const SizeT* mMap = nullptr;
public:
DEFAULT_MEMBERS(FPos);
inline FPos(SizeT ext, const SizeT* map);
constexpr SizeT size() const;
constexpr const SizeT& val() const;
template <class PosT1>
constexpr UPos operator+(const PosT1& a) const;
template <class PosT1>
constexpr FPos operator*(const PosT1& a) const;
template <class PosT>
constexpr UPos operator()(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) extend(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator SizeT() const;
};
template <SizeT N, SizeT... Ms>
class SFPos
{
private:
static Arr<SizeT,sizeof...(Ms)> sMs;
public:
constexpr SFPos() = default;
constexpr SizeT size() const;
constexpr SizeT val() const;
template <SizeT N1>
constexpr auto operator+(const SPos<N1>& a) const;
template <SizeT N1>
constexpr auto operator*(const SPos<N1>& a) const;
template <SizeT N1>
constexpr auto operator()(const SPos<N1>& a) const;
constexpr auto operator+(const UPos& a) const;
constexpr auto operator*(const UPos& a) const;
constexpr auto operator()(const UPos& a) const;
template <class PosT>
constexpr decltype(auto) extend(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator FPos() const;
explicit constexpr operator SizeT() const;
};
template <class BPosT, class NPosT>
class MPos : public BPosT // BPos should be a SCALAR PosT (NO MPos!)
{
protected:
NPosT mNext;
public:
constexpr MPos();
constexpr MPos(const BPosT& b, const NPosT& n);
template <typename... Args>
constexpr MPos(Args&&... args, const NPosT& next);
template <typename... Args>
constexpr MPos(Args&&... args, NPosT&& next);
constexpr SizeT size() const;
constexpr const NPosT& next() const;
template <class PosT>
constexpr auto operator+(const PosT& a) const;
template <class PosT>
constexpr auto operator*(const PosT& a) const;
// same as operator*, except for FPos/SFPos, where map is executed
template <class PosT>
constexpr auto operator()(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) extend(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) operator<<(const PosT& a) const;
};
// treat as scalar pos!
class DPos : public ObjHandle<VPosBase>
{
public:
DEFAULT_MEMBERS(DPos);
inline DPos(Uptr<VPosBase>&& a);
inline DPos(const DPosRef& a);
template <class PosT>
inline explicit DPos(const PosT& a);
template <class PosT>
inline explicit DPos(PosT&& a);
inline const VPosBase* get() const;
inline const VPosBase* vpos() const;
inline SizeT size() const;
inline SizeT val() const;
inline DPosRef sub() const;
//inline DPosRef next() const;
template <class PosT>
inline DPos operator+(const PosT& a) const;
template <class PosT>
inline DPos operator*(const PosT& a) const;
// same as operator*, except for FPos/SFPos, where map is executed
template <class PosT>
inline DPos operator()(const PosT& a) const;
template <class PosT>
inline decltype(auto) extend(const PosT& a) const;
template <class PosT>
inline decltype(auto) operator<<(const PosT& a) const;
explicit inline operator SizeT() const;
};
class DPosRef
{
private:
const VPosBase* mP = nullptr;
public:
DEFAULT_MEMBERS(DPosRef);
explicit DPosRef(const VPosBase* p);
inline const VPosBase* get() const;
inline const VPosBase* vpos() const;
inline SizeT size() const;
inline SizeT val() const;
inline DPosRef sub() const;
//inline DPosRef next() const;
template <class PosT>
inline DPos operator+(const PosT& a) const;
template <class PosT>
inline DPos operator*(const PosT& a) const;
// same as operator*, except for FPos/SFPos, where map is executed
template <class PosT>
inline DPos operator()(const PosT& a) const;
template <class PosT>
inline decltype(auto) extend(const PosT& a) const;
template <class PosT>
inline decltype(auto) operator<<(const PosT& a) const;
explicit inline operator SizeT() const;
};
// for common call of extension vector elements
// BPos = base pos type
// OPos = offset pos type (i.e. step/ext * for index of lowest for layer)
// currently EPos must be used only at the lowest for layer
template <class BPosT, class... OPosTs>
class EPos : public BPosT
{
private:
Tuple<OPosTs...> mP;
template <SizeT... Is>
constexpr decltype(auto) ival(std::index_sequence<Is...> is) const;
template <SizeT... Is>
constexpr decltype(auto) inext(std::index_sequence<Is...> is) const;
public:
DEFAULT_MEMBERS(EPos);
constexpr EPos(const BPosT& b, const OPosTs&... os);
constexpr EPos(BPosT&& b, OPosTs&&... os);
template <class PosT>
constexpr decltype(auto) operator+(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) operator*(const PosT& a) const;
template <class PosT>
constexpr decltype(auto) operator()(const PosT& a) const;
constexpr decltype(auto) val() const;
constexpr decltype(auto) next() const;
constexpr decltype(auto) scal() const;
template <SizeT I>
constexpr decltype(auto) get() const;
};
/*********************************
* Traits and Helper-Classes *
*********************************/
template <class T>
struct is_pos_type { CXZ_CVAL_FALSE; };
template <class T>
struct is_scalar_pos_type { CXZ_CVAL_FALSE; };
template <class T>
struct is_static_pos_type { CXZ_CVAL_FALSE; };
template <class T>
struct is_epos_type { CXZ_CVAL_FALSE; };
template <class PosT>
struct static_pos_size
{
static constexpr SizeT value = is_pos_type<PosT>::value ? 1 : 0;
};
template <class PosT>
struct epos_size
{
static constexpr SizeT value = 1;
};
template <class OPosT1, class OPosT2, class... OPosTs>
struct pos_types_consecutive_2
{
private:
static constexpr bool eval();
public:
static constexpr bool value = eval();
};
template <class OPosT1, class... OPosTs>
struct pos_types_consecutive
{
static constexpr bool value = sizeof...(OPosTs) == 0 ? is_pos_type<OPosT1>::value : pos_types_consecutive_2<OPosT1,OPosTs...>::value;
};
template <class OPosT1, class... OPosTs>
struct pos_type_same
{
private:
static constexpr bool eval();
public:
static constexpr bool value = eval();
};
template <class PosT> struct pos_type_is_consecutive { CXZ_CVAL_TRUE; };
template <class BPosT, class OPosT, SizeT N>
struct MkEPos
{
static decltype(auto) mk(const BPosT& a, const OPosT& b);
};
template <class BPosT, class NPosT, class OPosT, class ONPosT, SizeT N>
struct MkEPos<MPos<BPosT,NPosT>,MPos<OPosT,ONPosT>,N>
{
static decltype(auto) mk(const MPos<BPosT,NPosT>& a, const MPos<OPosT,ONPosT>& b);
};
template <SizeT N, class BPosT, class OPosT>
decltype(auto) mkEPos(const BPosT& a, const OPosT& b);
template <class BPosT, class OPosT, SizeT... Is>
decltype(auto) mkiEPos(const BPosT& a, const OPosT& b, std::index_sequence<Is...> is);
/**************************************************
* Traits and Helper-Classes: Specializations *
**************************************************/
template <SizeT N> struct is_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
template <SizeT N> struct is_scalar_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
template <SizeT N> struct is_static_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
template <> struct is_pos_type<UPos> { CXZ_CVAL_TRUE; };
template <> struct is_scalar_pos_type<UPos> { CXZ_CVAL_TRUE; };
template <> struct is_pos_type<FPos> { CXZ_CVAL_TRUE; };
template <> struct is_scalar_pos_type<FPos> { CXZ_CVAL_TRUE; };
template <SizeT N, SizeT... Ms> struct is_pos_type<SFPos<N,Ms...>> { CXZ_CVAL_TRUE; };
template <SizeT N, SizeT... Ms> struct is_scalar_pos_type<SFPos<N,Ms...>> { CXZ_CVAL_TRUE; };
template <SizeT N, SizeT... Ms> struct is_static_pos_type<SFPos<N,Ms...>> { CXZ_CVAL_TRUE; };
template <class BPosT, class NPosT> struct is_pos_type<MPos<BPosT,NPosT>> { CXZ_CVAL_TRUE; };
template <> struct is_pos_type<DPos> { CXZ_CVAL_TRUE; };
template <> struct is_pos_type<DPosRef> { CXZ_CVAL_TRUE; };
template <> struct is_scalar_pos_type<DPos> { CXZ_CVAL_TRUE; };
template <> struct is_scalar_pos_type<DPosRef> { CXZ_CVAL_TRUE; };
template <class BPosT, class... OPosTs> struct is_pos_type<EPos<BPosT,OPosTs...>> { CXZ_CVAL_TRUE; };
template <class BPosT, class... OPosTs> struct is_scalar_pos_type<EPos<BPosT,OPosTs...>>
{ static constexpr bool value = is_scalar_pos_type<BPosT>::value; };
template <class BPosT, class... OPosTs> struct is_static_pos_type<EPos<BPosT,OPosTs...>>
{ static constexpr bool value = is_static_pos_type<BPosT>::value and (is_static_pos_type<OPosTs>::value and ...); };
template <class BPosT, class... OPosTs> struct is_epos_type<EPos<BPosT,OPosTs...>> { CXZ_CVAL_TRUE; };
template <class BPosT, class NPosT> struct is_epos_type<MPos<BPosT,NPosT>> { static constexpr bool value = is_epos_type<BPosT>::value or is_epos_type<NPosT>::value; };
template <class BPosT, class NPosT>
struct static_pos_size<MPos<BPosT,NPosT>>
{
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 NPosT>
struct epos_size<MPos<BPosT,NPosT>>
{
static constexpr SizeT value = epos_size<BPosT>::value;
};
template <class BPosT, class... OPosTs>
struct pos_type_is_consecutive<EPos<BPosT,OPosTs...>>
{
static constexpr bool value = pos_types_consecutive<OPosTs...>::value;
};
template <class BPosT, class NPosT>
struct pos_type_is_consecutive<MPos<BPosT,NPosT>>
{
static constexpr bool value = pos_type_is_consecutive<BPosT>::value;
};
} // end namespace CNORXZ
#endif