Whether the type is a specialization of template T
.
template <template <typename...> class T, typename U>
struct is_specialization_of: std::false_type {};
template <template <typename...> class T, typename... Us>
struct is_specialization_of<T, T<Us...>>: std::true_type {};
Get the first element which have specific type from a tuple.
template <typename T, std::size_t N, typename... Ts>
struct index_of;
template <typename T, std::size_t N, typename... Ts>
struct index_of<T, N, T, Ts...>: std::integral_constant<int, N> {};
template <typename T, std::size_t N, typename U, typename... Ts>
struct index_of<T, N, U, Ts...>: std::integral_constant<int, index_of<T, N + 1, Ts...>::value> {};
template <typename T, std::size_t N>
struct index_of<T, N>: std::integral_constant<int, -1> {};
Pack multiple parameters into a tuple and invoke a function with the tuple.
template <typename F, size_t... Idx, typename... Ts>
constexpr auto call_via_tuple_impl(F f, std::index_sequence<Idx...>, const std::tuple<Ts...> &args) {
return f(std::get<Idx>(args)...);
}
template <typename F, typename... Ts>
constexpr auto call_via_tuple(F f, const std::tuple<Ts...> &args) {
return call_via_tuple_impl(f, std::make_index_sequence<sizeof...(Ts)>(), args);
}
With std::tuple_size
:
#define VA_ARGS_SIZE(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
template<typename Arr, std::size_t... Idx>
constexpr auto array_to_tuple_impl(const Arr &arr, std::index_sequence<Idx...>) {
return std::make_tuple(arr[Idx]...);
}
template<typename T, std::size_t N>
constexpr auto array_to_tuple(const std::array<T, N> &arr) {
return array_to_tuple_impl(arr, std::make_index_sequence<N>());
}
namespace detail {
template <typename C, typename Tup, std::size_t... Idx>
constexpr decltype(auto) make_from_tuple_cxx14_impl(Tup &&args, std::index_sequence<Idx...>) {
return C { std::get<Idx>(std::forward<Tup>(args))... };
}
}
template <typename C, typename Tup>
constexpr decltype(auto) make_from_tuple_cxx14(Tup &&args) {
return detail::make_from_tuple_cxx14_impl<C>(std::forward<Tup>(args), std::make_index_sequence<std::tuple_size<std::decay_t<Tup>>::value>());
}
namespace detail {
template <typename, typename, typename = std::void_t<>>
struct is_braces_constructible_impl: std::false_type {};
template <typename T, typename... Args>
struct is_braces_constructible_impl<T, identity<Args...>, std::void_t<decltype(T{ std::declval<Args>()... })>>: std::true_type {};
}
template <typename T, typename... Args>
struct is_braces_constructible: detail::is_braces_constructible_impl<T, identity<Args...>> {};
Runtime version of std::get.
template <typename Tup, typename F, std::size_t... Idx>
void runtime_visit_tuple_impl(Tup && tup, std::size_t idx, F && f, std::index_sequence<Idx...>) {
((idx == Idx && ((std::forward<F>(f)(std::get<Idx>(tup))), false)), ...);
}