I have this forwarding function, that may or may not throw, depending on what the arguments are:
template <std::size_t M>
constexpr void split_apply(auto f, auto&& ...a) // noexcept(?)
{
// transforms provided tuple t into a tuple of N-element tuples
constexpr auto split([]<std::size_t N>(auto&& t) noexcept requires (bool(N))
{
constexpr auto n(std::tuple_size_v<std::remove_cvref_t<decltype(t)>>);
static_assert(n && !(n % N));
return [&]<auto ...I>(std::index_sequence<I...>) noexcept
{
return std::make_tuple(
[&]<auto ...J>(std::index_sequence<J...>) noexcept
{
constexpr auto K(N * I);
return std::forward_as_tuple(std::get<K + J>(t)...);
}(std::make_index_sequence<N + I - I>())...
);
}(std::make_index_sequence<n / N>());
}
);
std::apply([&](auto&& ...t) noexcept(noexcept(
(std::apply(f, std::forward<decltype(t)>(t)), ...)))
{
(std::apply(f, std::forward<decltype(t)>(t)), ...);
},
split.template operator()<M>(std::forward_as_tuple(a...))
);
}
Since std::apply()
does not have a noexcept
specifier (a defect IMO), there probably should not be any here as well, but let's assume that it had one. How would I compute whether split_apply()
throws for some provided arguments?