cnorxz/orig/include/arith.h
Christian Zimmermann 3463e6ceea wip...
2022-09-11 02:48:30 +02:00

213 lines
4.8 KiB
C++

#ifndef __cxz_arith_h__
#define __cxz_arith_h__
#include <functional>
namespace CNORXZ
{
//template <typename T, class F, typename... As>
template <class F>
struct StaticFunctionBase
{
static constexpr bool FISSTATIC = true;
typedef F function;
//typedef typename F::value_type value_type;
template <class... Ops>
static auto mk(const Ops&... ops);
template <size_t N, class Tuple, typename... As>
static inline auto xapply(const Tuple& tp, As... as);
template <typename... As>
static inline auto apply(const std::tuple<As...>& arg);
};
// OPERATIONS (STATIC)
template <typename T>
struct identity : public StaticFunctionBase<identity<T>>
{
//static constexpr bool FISSTATIC = true;
using StaticFunctionBase<identity<T>>::apply;
typedef T value_type;
static inline T apply(T a)
{
return a;
}
static inline T selfApply(T& a1, const T& a2)
{
return a1 = a2;
}
};
template <typename T, typename U>
using plusv = decltype(std::declval<T>()+std::declval<U>());
template <typename T, typename U>
using minusv = decltype(std::declval<T>()-std::declval<U>());
template <typename T, typename U>
using multipliesv = decltype(std::declval<T>()*std::declval<U>());
template <typename T, typename U>
using dividesv = decltype(std::declval<T>()/std::declval<U>());
template <typename T, typename U>
struct plusx : public StaticFunctionBase<plusx<T,U>>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<plusx<T,U>>::apply;
typedef plusv<T,U> value_type;
static inline value_type apply(T a1, U a2)
{
return a1 + a2;
}
static inline T& selfApply(T& a1, const T& a2)
{
return a1 += a2;
}
};
template <typename T, typename U>
struct minusx : public StaticFunctionBase<minusx<T,U>>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<minusx<T,U>>::apply;
typedef minusv<T,U> value_type;
static inline value_type apply(T a1, U a2)
{
return a1 - a2;
}
};
template <typename T, typename U>
struct multipliesx : public StaticFunctionBase<multipliesx<T,U>>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<multipliesx<T,U>>::apply;
typedef multipliesv<T,U> value_type;
static inline value_type apply(T a1, U a2)
{
return a1 * a2;
}
};
template <typename T, typename U>
struct dividesx : public StaticFunctionBase<dividesx<T,U>>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<dividesx<T,U>>::apply;
typedef dividesv<T,U> value_type;
static inline value_type apply(T a1, U a2)
{
return a1 / a2;
}
};
template <typename T>
struct negate : public StaticFunctionBase<negate<T>>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<negate<T>>::apply;
typedef T value_type;
static inline T apply(T a)
{
return -a;
}
};
template <typename T>
using plus = plusx<T,T>;
template <typename T>
using minus = minusx<T,T>;
template <typename T>
using multiplies = multipliesx<T,T>;
template <typename T>
using divides = dividesx<T,T>;
// OPERATIONS (STATIC)
template <typename R, typename... Args>
class function
{
public:
static constexpr bool FISSTATIC = false;
private:
std::function<R(Args...)> mF;
public:
function() = default;
function(const std::function<R(Args...)>& in) : mF(in) {}
inline R operator()(const Args&... args)
{
return mF(args...);
}
template <size_t N, class Tuple, typename... As>
static inline auto xapply(const std::function<R(Args...)>& ff, const Tuple& tp, As... as)
{
if constexpr(N > 0){
return xapply<N-1>(ff, tp, std::get<N>(tp), as...);
}
else {
return ff(std::get<0>(tp), as...);
}
}
inline R operator()(const std::tuple<Args...>& args)
{
return xapply<sizeof...(Args)-1>(mF, args);
}
};
#include <cmath>
#define regFunc1(fff) template <typename T>\
struct x_##fff : public StaticFunctionBase<x_##fff<T>> {\
static constexpr bool FISSTATIC = true;\
typedef T value_type; \
static inline T apply(T a){\
return fff(a); } };
#include "extensions/math.h"
#undef regFunc1
template <size_t N>
struct x_ipow
{
static constexpr bool FISSTATIC = true;
template <typename T>
static inline T apply(T a)
{
if constexpr(N > 0){
return a * x_ipow<N-1>::apply(a);
}
else {
return a;
}
}
};
} // end namespace CNORXZInternal
#include "arith.cc.h"
#endif