6#ifndef SL_UTILITY_TUPLE_ALGORITHM_HPP
7#define SL_UTILITY_TUPLE_ALGORITHM_HPP
41 template <
class Tuple,
class Transform>
47 [&]<
class... Elements>(Elements&&... elements) -> std::tuple<std::invoke_result_t<Transform, Elements>...>
49 return {std::invoke(transform, std::forward<Elements>(elements))...};
51 std::forward<Tuple>(tuple));
59namespace sl::tuple::detail
61 template <
class Tuple>
62 requires concepts::tuple<std::remove_cvref_t<Tuple>>
64 constexpr auto envelop_elements(Tuple&& tuple)
67 std::forward<Tuple>(tuple),
68 []<
class Element>(Element&& el) {
return std::make_tuple(std::forward<Element>(el)); });
83 template <
class Tuple>
84 requires concepts::tuple<std::remove_cvref_t<Tuple>>
87 using type =
decltype(detail::envelop_elements(std::declval<Tuple>()));
93 template <
class Tuple>
108 template <
class Tuple>
113 )
noexcept(std::is_nothrow_constructible_v<std::remove_cvref_t<Tuple>, Tuple>)
115 return detail::envelop_elements(std::forward<Tuple>(tuple));
121namespace sl::tuple::detail
123 template <
class... Tuples>
125 constexpr auto zip(Tuples&&... tuples)
127 return [&]<std::size_t... indices>([[maybe_unused]] std::index_sequence<indices...>)
129 return std::make_tuple(
130 [&]<std::size_t index>()
132 return std::make_tuple(std::get<index>(std::forward<Tuples>(tuples))...);
133 }.template operator()<indices>()...
135 }(std::make_index_sequence<std::min({std::tuple_size_v<Tuples>...})>{});
150 template <
class... Tuples>
151 requires (2 <=
sizeof...(Tuples))
152 && (concepts::tuple<std::remove_cvref_t<Tuples>> && ...)
155 using type =
decltype(detail::zip(std::declval<Tuples>()...));
161 template <
class... Tuples>
162 requires (2 <=
sizeof...(Tuples))
191 template <
class First,
class Second,
class... Others>
196 constexpr zip_result_t<First, Second, Others...>
zip(First&& first, Second&& second, Others&&... others)
199 std::forward<First>(first),
200 std::forward<Second>(second),
201 std::forward<Others>(others)...);
207namespace sl::tuple::detail
211 constexpr auto cartesian_product(
const concepts::tuple
auto& first)
213 return envelop_elements(first);
217 constexpr auto cartesian_product(
const concepts::tuple
auto& first,
const concepts::tuple
auto&... others)
221 [&](
auto&... firstElements)
223 return std::tuple_cat(
224 [&](
auto& currentFirst)
227 [&](
auto&... trailerElements)
229 return std::make_tuple(std::tuple_cat(std::make_tuple(currentFirst), trailerElements)...);
252 template <
class... Tuples>
253 requires (2 <=
sizeof...(Tuples))
254 && (concepts::tuple<std::remove_cvref_t<Tuples>> && ...)
257 using type =
decltype(detail::cartesian_product(std::declval<Tuples>()...));
263 template <
class... Tuples>
264 requires (2 <=
sizeof...(Tuples))
292 const Second& second,
293 const Others&... others
294 )
noexcept(std::is_nothrow_copy_constructible_v<First>
295 && std::is_nothrow_copy_constructible_v<Second>
296 && (std::is_nothrow_copy_constructible_v<Others> && ...))
298 return detail::cartesian_product(first, second, others...);
Determines whether a type can be used as a tuple-like.
Definition: General.hpp:105
constexpr cartesian_product_result_t< First, Second, Others... > cartesian_product(const First &first, const Second &second, const Others &... others) noexcept(std::is_nothrow_copy_constructible_v< First > &&std::is_nothrow_copy_constructible_v< Second > &&(std::is_nothrow_copy_constructible_v< Others > &&...))
Creates the cartesian product of the given tuples.
Definition: Algorithm.hpp:290
typename cartesian_product_result< Tuples... >::type cartesian_product_result_t
Alias type determining the result of a cartesian_product call.
Definition: Algorithm.hpp:266
constexpr envelop_elements_result_t< Tuple > envelop_elements(Tuple &&tuple) noexcept(std::is_nothrow_constructible_v< std::remove_cvref_t< Tuple >, Tuple >)
Envelops all elements of the given tuple into their own std::tuple and creates a tuple of tuples.
Definition: Algorithm.hpp:111
typename envelop_elements_result< Tuple >::type envelop_elements_result_t
Alias type determining the result of a tuple_envelop_elements call.
Definition: Algorithm.hpp:95
constexpr auto transform_elements(Tuple &&tuple, Transform transform)
Applies the transform on each element of the given source tuple and returns the results as a new tupl...
Definition: Algorithm.hpp:44
typename zip_result< Tuples... >::type zip_result_t
Alias type determining the result of a zip call.
Definition: Algorithm.hpp:164
constexpr zip_result_t< First, Second, Others... > zip(First &&first, Second &&second, Others &&... others)
Zips elements of all provided source tuples and creates a tuple of tuples.
Definition: Algorithm.hpp:196
cartesian_product_as< common_container< Lists... >::template type, Lists... > cartesian_product
Alternative algorithm yielding the result as the type member alias and determining the result contain...
Definition: TypeList.hpp:1475
Definition: Algorithm.hpp:18
Trait type determining the result of a cartesian_product call.
Definition: Algorithm.hpp:256
decltype(detail::cartesian_product(std::declval< Tuples >()...)) type
Definition: Algorithm.hpp:257
Trait type determining the result of a tuple_envelop_elements call.
Definition: Algorithm.hpp:86
decltype(detail::envelop_elements(std::declval< Tuple >())) type
Definition: Algorithm.hpp:87
Trait type determining the result of a zip call.
Definition: Algorithm.hpp:154
decltype(detail::zip(std::declval< Tuples >()...)) type
Definition: Algorithm.hpp:155