Skip to content

Instantly share code, notes, and snippets.

@oliverlee
Created December 16, 2020 23:30
Show Gist options
  • Save oliverlee/72f9b177bee3f33fabe73560aa7a11bf to your computer and use it in GitHub Desktop.
Save oliverlee/72f9b177bee3f33fabe73560aa7a11bf to your computer and use it in GitHub Desktop.
invoke callable with exploded tuple
template <class...>
using void_t = void;
template <class Transform, class Arg, class = void>
struct transform_takes_one_arg : std::false_type {};
template <class Transform, class Arg>
struct transform_takes_one_arg<Transform,
Arg,
void_t<decltype(std::declval<Transform>()(std::declval<Arg>()))>>
: std::true_type {};
template <class Transform,
class Arg,
std::enable_if_t<transform_takes_one_arg<Transform, Arg>::value, bool> = true>
auto invoke_transform(const Transform& transform, Arg&& arg)
{
return transform(std::forward<Arg>(arg));
}
template <class Transform, class Arg, std::size_t... Indices>
auto invoke_transform_with_argpack(const Transform& transform,
Arg&& argpack,
std::index_sequence<Indices...>)
{
return transform(std::get<Indices>(std::forward<Arg>(argpack))...);
}
template <class Transform,
class Arg,
std::size_t N = std::tuple_size<std::decay_t<Arg>>::value,
std::enable_if_t<!transform_takes_one_arg<Transform, Arg>::value, bool> = true>
auto invoke_transform(const Transform& transform, Arg&& argpack)
{
return invoke_transform_with_argpack(
transform, std::forward<Arg>(argpack), std::make_index_sequence<N>{});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment