1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
#include <type_traits>
struct nil_t;
template <typename... Ts> struct vector;
template <typename...> struct head { using type = nil_t; };
template <template <typename...> class Seq, typename First, typename... Rest>
struct head<Seq<First, Rest...>> {
using type = First;
};
template <typename Seq> using head_t = typename head<Seq>::type;
template <typename...> struct tail { using type = nil_t; };
template <template <typename...> class Seq, typename First, typename... Rest>
struct tail<Seq<First, Rest...>> {
using type = Seq<Rest...>;
};
template <typename Seq> using tail_t = typename tail<Seq>::type;
template <typename Seq, typename State, typename Fn> struct fold {
using type =
typename fold<tail_t<Seq>,
typename Fn::template apply<head_t<Seq>, State>::type,
Fn>::type;
};
template <typename State, typename Fn> struct fold<nil_t, State, Fn> {
using type = State;
};
template <typename Seq, typename State, typename Fn>
using fold_t = typename fold<Seq, State, Fn>::type;
template <int I> using int_ = std::integral_constant<int, I>;
template <typename N> using succ = int_<N::value + 1>;
struct accumulate_if_float {
template <typename T, typename Sum> struct apply {
using type =
std::conditional_t<std::is_floating_point<T>::value, succ<Sum>, Sum>;
};
};
template <typename Seq>
constexpr auto number_of_floats_v =
fold_t<Seq, int_<0>, accumulate_if_float>::value;
using MySeq = vector<long, float, short, double, float, long, long double>;
static_assert(number_of_floats_v<MySeq> == 4);
|