@@ -78,4 +78,69 @@ struct nth_element_impl<0, T, Ts...>
7878};
7979
8080template <std::size_t I, typename ... Ts>
81- using nth_element = typename nth_element_impl<I, Ts...>::type;
81+ using nth_element_t = typename nth_element_impl<I, Ts...>::type;
82+
83+
84+ // common_variant
85+ // common_variant builds a single variant from types or variants
86+ // bool, bool -> variant<bool>
87+ // int, bool -> variant<int, bool>
88+ // variant<int, bool>, bool -> variant<int, bool>
89+ // variant<int, bool>, float -> variant<int, bool, float>
90+ // variant<int, bool>, variant<bool, float> -> variant<int, bool, float>
91+ // variant<int, bool>, variant<bool, float, double> -> variant<int, bool, float, double>
92+
93+ // Two different types
94+ // int, bool -> variant<int, bool>
95+ template <typename T, typename U>
96+ struct common_variant
97+ {
98+ using type = std::variant<T, U>;
99+ };
100+
101+ // Identical types
102+ // int, int -> variant<int>
103+ template <typename T>
104+ struct common_variant <T, T>
105+ {
106+ using type = std::variant<T>;
107+ };
108+
109+ // Type + Variant which starts with the Type
110+ // int, variant<int> -> variant<int>
111+ template <typename T, typename ... Ts>
112+ struct common_variant <T, std::variant<T, Ts...>>
113+ {
114+ using type = std::variant<T, Ts...>;
115+ };
116+
117+ // Variant + Empty = Variant
118+ template <typename ... Ts>
119+ struct common_variant <std::variant<Ts...>, std::variant<>>
120+ {
121+ using type = std::variant<Ts...>;
122+ };
123+ // Empty + Variant = Variant
124+ template <typename ... Ts>
125+ struct common_variant <std::variant<>, std::variant<Ts...>>
126+ {
127+ using type = std::variant<Ts...>;
128+ };
129+
130+ template <typename T, typename ... Ts>
131+ struct common_variant <T, std::variant<Ts...>>
132+ {
133+ using type = std::conditional_t <std::is_convertible_v<T, std::variant<Ts...>>, std::variant<Ts...>, std::variant<T, Ts...>>;
134+ };
135+
136+ template <typename T, typename ... Ts>
137+ struct common_variant <std::variant<Ts...>, T>
138+ {
139+ using type = typename common_variant<T, std::variant<Ts...>>::type;
140+ };
141+
142+ template <typename T, typename ... Ts, typename ... Us>
143+ struct common_variant <std::variant<T, Ts...>, std::variant<Us...>>
144+ {
145+ using type = typename common_variant<std::variant<Ts...>, typename common_variant<T, std::variant<Us...>>::type>::type;
146+ };
0 commit comments