pretty-automata/src/distinct-types.h

53 lines
1.7 KiB
C++

#ifndef SHADER_AUTOMATON_DISTINCT_TYPES_H
#define SHADER_AUTOMATON_DISTINCT_TYPES_H
#include <variant>
// #include <type_traits>
namespace distinct_types_internal {
template <typename TList, typename... Ts>
struct UniqueTypes;
template <template <typename...> typename X, typename... Ts>
struct UniqueTypes<X<Ts...>> {
using type = X<Ts...>;
};
template <template <typename...> typename X, typename... Ts, typename T, typename... Us>
struct UniqueTypes<X<Ts...>, T, Us...> {
using type = typename UniqueTypes<
typename std::conditional<
std::disjunction<std::is_same<T, Ts>...>::value,
X<Ts...>,
X<Ts..., T>>::type,
Us...>::type;
};
template <template <typename...> typename X, typename... Ts>
struct Distinct {
using type = typename UniqueTypes<X<>, Ts...>::type;
};
} // namespace distinct_types_internal
template <typename... Ts>
using distinct_types_variant = typename distinct_types_internal::Distinct<std::variant, Ts...>::type;
template <typename... Ts>
using distinct_types_tuple = typename distinct_types_internal::Distinct<std::tuple, Ts...>::type;
template <typename T, typename... Ts>
using if_single_type = std::enable_if_t<std::tuple_size<distinct_types_tuple<Ts...>>::value == 1, T>;
template <typename T, typename... Ts>
using if_not_single_type = std::enable_if_t<(std::tuple_size<distinct_types_tuple<Ts...>>::value > 1), T>;
template <typename T, typename F, typename... Ts>
using single_type_conditional = std::conditional<(std::tuple_size<distinct_types_tuple<Ts...>>::value == 1), T, F>;
template <typename... Ts>
using single_type = if_single_type<typename std::tuple_element<0, std::tuple<Ts...>>::type, Ts...>;
#endif // SHADER_AUTOMATON_DISTINCT_TYPES_H