template <typename ...Fs, typename Pipe>
struct ProductMap {
template <typename ...Ts>
using f = /* .... */;
};
ProductMap<Fs..., Pipe>
is a metafunction that passes to Pipe
the parameter pack Us...
, which is generated by invoking each F
in the parameter pack Fs...
on the corresponding element of the parameter pack Ts...
.
f:: Ts... -> Fs(Ts).. >-> Pipe
The parameter pack of the ProductMap<Args...>
will be treated as Pipe
, and must always be provided (there is no default).
We will write the ml::CountIf
<ml::IsClass<>
using ml::Reduce
. For that, we need the accumulator function
f:: Init, T -> Init, IsClass(T) >-> Add
which we will make using ml::ProductMap
. Note that the above is equivalent to
f:: Init, T -> Identity(Init), IsClass(T) >-> Add
Thus,
template <typename Predicate>
using MakeCounter = ml::ProductMap<ml::Identity<>, Predicate, ml::Add<>>;
using T = ml::f<
ml::Reduce<
MakeCounter<ml::CountIf<>>>,
ml::Int<0>, // Init
int, std::string, bool, std::string>; // Ts...
static_assert(
std::is_same_v<
T,
ml::Int<2>>);