pfor/src/pfor/mp/meta.h

92 lines
1.9 KiB
C++

#ifndef PFOR_PFOR_MP_META_H
#define PFOR_PFOR_MP_META_H
#include <utility>
#include <functional>
namespace pfor {
/**
* compile-time type to store unsigned integers
*/
template<std::size_t v>
struct UIntToType {
using value_type = std::size_t;
static constexpr value_type value = v;
};
/**
* compile-time type to store integers
*/
template<long v>
struct IntToType {
using value_type = long;
static constexpr value_type value = v;
};
/**
* If
* returns first type if condition is true, else second type
*/
template<bool, typename, typename> struct IfImpl;
template<typename T, typename F>
struct IfImpl<false, T, F> {
using type = F;
};
template<typename T, typename F>
struct IfImpl<true, T, F> {
using type = T;
};
template<bool Cond, typename T, typename F>
using If = typename IfImpl<Cond, T, F>::type;
/**
*/
template<template<typename> class F, typename P, typename V, typename Af> struct Accumulate;
template<template<typename> class F, template<typename...> class P, typename T, typename... Ts, typename V, typename Af>
struct Accumulate<F, P<T, Ts...>, V, Af> {
static decltype(auto) eval(V const& value, Af const& f) {
return Accumulate<F, P<Ts...>, V, Af>::eval(f(value, +F<T>::value), f);
}
};
template<template<typename> class F, template<typename...> class P, typename V, typename Af>
struct Accumulate<F, P<>, V, Af> {
static V eval(V const& value, Af const&) { return value; }
};
template<template<typename> class F, typename P, typename V, typename Af>
decltype(auto) accumulate(V const& value, Af const& f) {
return Accumulate<F, P, V, Af>::eval(value, f);
}
/**
* @brief computes the GCD of two integers
*
* @param a an integer
* @param b an integer
*
* @return GCD(A, B)
*/
namespace impl {
constexpr long gcd(long a, long b) {
if(!b) return a;
return gcd(b, a%b);
}
}
constexpr long gcd(long a, long b) {
if(a < 0) a = -a;
if(b < 0) b = -b;
return impl::gcd(a, b);
}
}
#endif