Program Listing for File reduce.hpp
↰ Return to documentation for file (include/reduce.hpp
)
#pragma once
#include "htlist.hpp"
#include "predicates.hpp"
#include <type_traits>
namespace ctql {
namespace detail {
// fold_sizes<List, Op, Acc>:
// Recursively folds the HTList by applying Op to the accumulator and each head's size.
template <typename List, template <std::size_t, std::size_t> class Op, std::size_t Acc>
struct fold_sizes;
// Base case: empty list -> accumulator.
template <template <std::size_t, std::size_t> class Op, std::size_t Acc>
struct fold_sizes<HTList<>, Op, Acc> : std::integral_constant<std::size_t, Acc> { };
// Inductive case: peel head H (which satisfies HasStaticSize), push Op(Acc, H::size).
template <
HasStaticSize H,
typename... Ts,
template <std::size_t, std::size_t> class Op,
std::size_t Acc>
struct fold_sizes<HTList<H, Ts...>, Op, Acc>
: fold_sizes<HTList<Ts...>, Op, Op<Acc, static_cast<std::size_t>(H::size)>::value> { };
// Simple meta-ops on size_t.
template <std::size_t A, std::size_t B>
struct add_i : std::integral_constant<std::size_t, A + B> { };
template <std::size_t A, std::size_t B>
struct min_i : std::integral_constant<std::size_t, (A < B ? A : B)> { };
template <std::size_t A, std::size_t B>
struct max_i : std::integral_constant<std::size_t, (A < B ? B : A)> { };
} // namespace detail
template <template <std::size_t, std::size_t> class Op, std::size_t Init, typename... Ts>
using reduce_sizes_t = detail::fold_sizes<detail::HTList<Ts...>, Op, Init>;
template <template <std::size_t, std::size_t> class Op, std::size_t Init, typename... Ts>
inline constexpr std::size_t reduce_sizes_v = reduce_sizes_t<Op, Init, Ts...>::value;
template <typename... Ts>
using Sum = reduce_sizes_t<detail::add_i, 0, Ts...>;
template <typename... Ts>
inline constexpr std::size_t Sum_v = Sum<Ts...>::value;
} // namespace ctql