GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/algorithm/cartesian_product.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 7 7 100.0%
Functions: 112 112 100.0%
Branches: 3 3 100.0%

Line Branch Exec Source
1 //======================================================================================================================
2 /*
3 KUMI - Compact Tuple Tools
4 Copyright : KUMI Project Contributors
5 SPDX-License-Identifier: BSL-1.0
6 */
7 //======================================================================================================================
8 #pragma once
9
10 namespace kumi
11 {
12 namespace _
13 {
14 template<std::size_t K, typename T, std::size_t... I, std::size_t... J, std::size_t... S>
15 210 KUMI_HIDDEN_ABI constexpr auto cartesian_element_(
16 kumi::_::adl_tag_t, T&& t, std::index_sequence<I...>, std::index_sequence<J...> j, std::index_sequence<S...>)
17 {
18 210 return kumi::_::builder(KUMI_FWD(t), std::index_sequence<((K / S) % I)...>{}, j);
19 }
20
21 template<typename T, typename Sizes, typename Elts, typename Strides, std::size_t... I>
22 12 KUMI_HIDDEN_ABI constexpr auto cartesian_product_(
23 kumi::_::adl_tag_t, T&& t, Sizes s, Elts e, Strides st, std::index_sequence<I...>)
24 {
25 24 return kumi::make_tuple(cartesian_element_<I>(kumi::_::adl_tag, t, s, e, st)...);
26 }
27 }
28
29 struct cartesian_product_t
30 {
31 template<kumi::concepts::product_type... Ts>
32 [[nodiscard]] KUMI_ABI constexpr auto operator()(Ts&&... ts) const
33 requires(kumi::concepts::follows_same_semantic<Ts...>)
34 {
35 2 if constexpr (sizeof...(Ts) == 0) return kumi::tuple{};
36 else
37 {
38 using out = std::make_index_sequence<(kumi::size_v<Ts> * ...)>;
39 using elts = std::index_sequence_for<Ts...>;
40 using sizes = std::index_sequence<kumi::size_v<Ts>...>;
41 using strides = kumi::function::cartesian_strides<sizes, elts>;
42
2/2
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 1 times.
12 return cartesian_product_(kumi::_::adl_tag, kumi::forward_as_tuple(KUMI_FWD(ts)...), sizes{}, elts{}, strides{},
43
1/1
✓ Branch 1 taken 2 times.
12 out{});
44 }
45 }
46 };
47
48 //====================================================================================================================
49 /**
50 @ingroup kumi_generators
51 @brief Callable object returning the Cartesian Product of all elements of its arguments product types
52
53 @var cartesian_product
54
55 @note This function does not take part in overload resolution if the input product types do not follow the same
56 semantic. @see concepts::follows_same_semantic
57
58 @qualifier nodiscard
59 @qualifier inline
60 @qualifier constexpr
61
62 @groupheader{Header file}
63 @code
64 #include <kumi/algorithm/cartesian_product.hpp>
65 @endcode
66
67 @groupheader{Call Signature}
68
69 @code
70 template<product_type... Ts>
71 [[nodiscard]] constexpr auto cartesian_product(Ts &&... ts);
72 @endcode
73
74 @subgroupheader{Parameters}
75
76 - `ts`: Product Types to process
77
78 @subgroupheader{Return value}
79
80 - A tuple containing all the product types built from all combination of all ts' elements
81
82 @groupheader{Helper type}
83
84 @snippet include/kumi/algorithm/cartesian_product.hpp cartesian_product_t
85
86 Computes the return type of a call to kumi::cartesian_product
87
88 @groupheader{Examples}
89
90 @tab_begin
91
92 @tab{Tuple}
93 @godbolt{doc/tuple/algo/cartesian_product.cpp}
94
95 @tab{Record}
96 @godbolt{doc/record/algo/cartesian_product.cpp}
97
98 @tab_end
99 **/
100 //====================================================================================================================
101 KUMI_VARIABLE_ABI constexpr cartesian_product_t cartesian_product{};
102
103 namespace result
104 {
105 //! [cartesian_product_t]
106 template<typename... Ts> using cartesian_product_t = decltype(kumi::cartesian_product(std::declval<Ts>()...));
107
108 template<typename... Ts> struct cartesian_product
109 {
110 using type = kumi::result::cartesian_product_t<Ts...>;
111 };
112
113 //! [cartesian_product_t]
114 }
115 }
116