92 lines
1.9 KiB
C++
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
|