13 #include <type_traits>
15 namespace qx::tuple_utils
29 template<
class... first_pack_t,
class... second_pack_t>
30 struct join<std::tuple<first_pack_t...>, std::tuple<second_pack_t...>>
32 using type = std::tuple<first_pack_t..., second_pack_t...>;
35 template<
class... first_pack_t,
class second_t,
class... optional_args_t>
36 struct join<std::tuple<first_pack_t...>, second_t, optional_args_t...>
38 using type = std::tuple<first_pack_t..., second_t, optional_args_t...>;
41 template<
class... args_t>
42 using join_t =
typename join<args_t...>::type;
57 template<
class target_t,
class... pack_t>
60 using type = std::tuple<pack_t...>;
63 template<
class target_t,
class parameter_t,
class... pack_t>
66 using type =
typename join<
67 std::conditional_t<std::is_same_v<target_t, parameter_t>, std::tuple<>, std::tuple<parameter_t>>,
68 typename remove_single<target_t, std::tuple<pack_t...>>::type>::type;
82 template<
class... types_t>
83 struct remove<std::tuple<types_t...>, std::tuple<>>
85 using type = std::tuple<types_t...>;
88 template<
class target_t,
class... remaining_targets_t,
class... types_t>
89 struct remove<std::tuple<types_t...>, std::tuple<target_t, remaining_targets_t...>>
93 typename remove<std::tuple<types_t...>, std::tuple<remaining_targets_t...>>::type>::type;
96 template<
class... args_t>
97 using remove_t =
typename remove<args_t...>::type;
107 template<
class T,
class tuple_t>
115 template<
class T,
class U,
class... args_t>
120 template<
class T,
class... args_t>
121 struct contains<T, std::tuple<T, args_t...>> : std::true_type
133 template<
class tuple_t,
class T>
134 using contains = details::contains<T, tuple_t>;
136 template<
class tuple_t,
class T>
150 template<
class tuple_t,
template<
class T>
class transformation_t>
153 template<
template<
class T>
class transformation_t,
class... args_t>
154 struct transform<std::tuple<args_t...>, transformation_t>
156 using type = std::tuple<typename transformation_t<args_t>::type...>;
159 template<
class tuple_t,
template<
class T>
class transformation_t>
173 template<
class tuple_t,
class T>
176 template<
class T,
class... args_t>
177 struct index<std::tuple<T, args_t...>, T>
179 static constexpr
size_t value = 0;
182 template<
class T,
class U,
class... args_t>
183 struct index<std::tuple<U, args_t...>, T>
185 static constexpr
size_t value = 1 +
index<std::tuple<args_t...>, T>::value;
188 template<
class tuple_t,
class T>
211 template<
class tuple_t,
class type_callable_t>
212 constexpr
void iterate(
const type_callable_t& callable)
215 using tuple_pointer_type = transform_t<tuple_t, std::add_pointer>;
217 auto temp_callable = [&callable]<
class T>(const T&)
219 callable.template operator()<std::remove_pointer_t<T>, index_v<tuple_pointer_type, T>>();
223 [&temp_callable](
auto&&... args)
225 ((temp_callable(args)), ...);
227 tuple_pointer_type());
235 namespace permutations_details
237 constexpr
size_t pow(
size_t n1,
size_t n2)
240 for (
size_t i = 0; i < n2; ++i)
246 template<
class... tuples_t>
249 template<
class... args_t>
252 using type = std::tuple<args_t...>;
255 template<
class... args_1_t,
class... args_2_t,
class... args_rest_t>
256 struct merge_tuples<std::tuple<args_1_t...>, std::tuple<args_2_t...>, args_rest_t...>
258 using type =
typename merge_tuples<std::tuple<args_1_t..., args_2_t...>, args_rest_t...>::type;
261 template<
class inner_tuples_tuple_t,
class... all_types_t>
264 template<
class... inner_tuples_t,
class... all_types_t>
268 template<
class inner_tuple_t>
271 using type = std::tuple<typename join<inner_tuple_t, all_types_t>::type...>;
278 template<
class all_tuples_t,
class prev_new_tuples_t,
size_t nCombinations,
class... all_types_t>
281 template<
bool bBreak ,
class all_tuples_t,
class new_tuples_t,
size_t nCombinations,
class... all_types_t>
284 using type = all_tuples_t;
287 template<
class all_tuples_t,
class new_tuples_t,
size_t nCombinations,
class... all_types_t>
294 template<
class all_tuples_t,
class prev_new_tuples_t,
size_t nCombinations,
class... all_types_t>
298 using new_tuples_t =
typename generate_layer<prev_new_tuples_t, all_types_t...>::type;
302 nCombinations == std::tuple_size_v<all_tuples_t>,
306 all_types_t...>::type;
323 template<
class... all_types_t>
326 static constexpr
size_t nTypes =
sizeof...(all_types_t);
327 static constexpr
size_t nCombinations = nTypes * (permutations_details::pow(nTypes, nTypes) - 1) / (nTypes - 1);
328 using start_tuples_t = std::tuple<std::tuple<all_types_t>...>;
333 template<
class... all_types_t>
334 using permutations_t =
typename permutations<all_types_t...>::type;
341 namespace cartesian_product_details
344 template<
class prefix_t,
class tuple_t>
347 template<
class prefix_t,
class... rest_types_t>
350 using type = std::tuple<typename join<std::tuple<prefix_t>, rest_types_t>::type...>;
353 template<
class... tuples_t>
359 using type = std::tuple<>;
362 template<
class... first_tuple_args_t>
363 struct flatten<std::tuple<first_tuple_args_t...>>
365 using type = std::tuple<first_tuple_args_t...>;
368 template<
class... first_tuple_args_t,
class... second_tuple_args_t,
class... rest_tuples_t>
369 struct flatten<std::tuple<first_tuple_args_t...>, std::tuple<second_tuple_args_t...>, rest_tuples_t...>
371 using type =
typename flatten<std::tuple<first_tuple_args_t..., second_tuple_args_t...>, rest_tuples_t...>::type;
376 template<
class... input_tuples_t>
382 using type = std::tuple<std::tuple<>>;
385 template<
class first_input_tuple_t,
class... rest_input_tuples_t>
389 using tail_product_type =
typename cartesian_product<rest_input_tuples_t...>::type;
391 template<
class element_t>
397 template<
class... elements_t>
400 template<
class... elements_t>
401 struct expand_all<std::tuple<elements_t...>>
407 using type =
typename expand_all<first_input_tuple_t>::type;
410 template<
class... tuples_args_t>
418 template<
template<
class>
class predicate_t,
class... args_t>
419 concept all_of_c = (predicate_t<args_t>::value && ...);
421 template<
template<
class>
class predicate_t,
class tuple_t>
424 template<
template<
class>
class predicate_t,
class... args_t>
425 struct all_of<predicate_t, std::tuple<args_t...>>
427 static constexpr
bool value = all_of_c<predicate_t, args_t...>;
430 template<
template<
class>
class predicate_t,
class... args_t>
431 constexpr
bool all_of_v =
all_of<predicate_t, args_t...>::value;
void iterate(const container_t &container, const callable_t &callable, const filter_t &filter=filters::always_true, const adapter_t &adapter=iterate_adapters::no_change)
Iterate container with filter.
double pow(T number, int nPower)
Power function for integer power.
Check that tuple type contains T.
Get an index of the first occurrence of the given type.
Appends types or another tuple to tuple.
Generates k-permutations with repetition for all_types_t.
Removes all types from the second argument from the first tuple.