tuple/value: allow calls to 'each' with empty tuples
This commit is contained in:
parent
f1f1a64845
commit
df9902a0b5
@ -18,24 +18,50 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace cruft::tuple::value {
|
namespace cruft::tuple::value {
|
||||||
|
namespace detail {
|
||||||
|
// Call the function for the value at the index `S`, then increment
|
||||||
|
// the index and call ourselves again if we haven't reached the end.
|
||||||
|
//
|
||||||
|
// A detail function is used to simplify the case for empty tuples;
|
||||||
|
// ie, we'd like to keep the index assertion, but a constexpr-if won't
|
||||||
|
// elide the assertion.
|
||||||
|
template<
|
||||||
|
typename FunctionT,
|
||||||
|
typename TupleT,
|
||||||
|
std::size_t S = 0
|
||||||
|
>
|
||||||
|
void
|
||||||
|
each (FunctionT &&func, TupleT &&value)
|
||||||
|
{
|
||||||
|
using tuple_t = std::decay_t<TupleT>;
|
||||||
|
static_assert (S < std::tuple_size_v<tuple_t>);
|
||||||
|
|
||||||
|
std::invoke (func, std::get<S> (value));
|
||||||
|
|
||||||
|
if constexpr (S + 1 < std::tuple_size_v<tuple_t>) {
|
||||||
|
each<FunctionT,TupleT,S+1> (
|
||||||
|
std::forward<FunctionT> (func),
|
||||||
|
std::forward<TupleT> (value)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
/// Call a provided functor of type FunctionT with each value in a
|
/// Call a provided functor of type FunctionT with each value in a
|
||||||
/// provided tuple-like object TupleT
|
/// provided tuple-like object TupleT
|
||||||
template<
|
template<
|
||||||
typename FunctionT,
|
typename FunctionT,
|
||||||
typename TupleT,
|
typename TupleT
|
||||||
std::size_t S = 0
|
|
||||||
>
|
>
|
||||||
void
|
void
|
||||||
each (FunctionT &&func, TupleT &&value)
|
each (FunctionT &&func, TupleT &&value)
|
||||||
{
|
{
|
||||||
using tuple_t = std::decay_t<TupleT>;
|
if constexpr (std::tuple_size_v<std::decay_t<TupleT>> > 0) {
|
||||||
static_assert (S < std::tuple_size_v<tuple_t>);
|
return detail::each (
|
||||||
|
std::forward<FunctionT> (func),
|
||||||
std::invoke (func, std::get<S> (value));
|
std::forward<TupleT> (value)
|
||||||
|
);
|
||||||
if constexpr (S + 1 < std::tuple_size_v<tuple_t>) {
|
|
||||||
each<FunctionT,TupleT,S+1> (std::forward<FunctionT> (func), std::forward<TupleT> (value));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user