GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/utils/projections.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 6 6 100.0%
Functions: 5 5 100.0%
Branches: 7 10 70.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 I, typename T> extern std::size_t value_at;
15
16 template<std::size_t I, auto Head, auto... Tail>
17 inline constexpr auto value_at<I, kumi::projection_map<Head, Tail...>> =
18 kumi::_::value_at<I - 1, kumi::projection_map<Tail...>>;
19
20 template<std::size_t I, auto... Vs>
21 inline constexpr auto value_at<I, kumi::projection_map<Vs...> const> =
22 kumi::_::value_at<I, kumi::projection_map<Vs...>>;
23
24 template<auto Head, auto... Tail> inline constexpr auto value_at<0, kumi::projection_map<Head, Tail...>> = Head;
25 }
26
27 //====================================================================================================================
28 /**
29 @ingroup kumi_utility
30 @class projection_map
31 @brief A stateless, compile-time schema for product type transformation.
32
33 kumi::projection_map reifies the act of indexing or member access into a first-class
34 type-level entity. It defines a sequence of accessors (projections) that can be applied
35 to any kumi::product_type to extract, reorder, or reshape its components.
36
37 Because it is a "Meta-Product Type" (a product of accessors), it allows for complex
38 data manipulations (like zipping or partitioning) to be expressed as a single
39 Non-Type Template Parameter (NTTP).
40
41 @note This type is stateless and carries zero runtime data.
42 @tparam V A pack of elements modeling kumi::concepts::projection.
43
44 ## Examples:
45 @include doc/infra/projections.cpp
46 **/
47 //====================================================================================================================
48 template<auto... V> struct projection_map
49 {
50 static_assert((kumi::concepts::projection<decltype(V)> && ...), "Invalid projections in projection_map definition");
51
52 static constexpr bool is_projection_map = true;
53
54 consteval projection_map() noexcept = default;
55
56 consteval explicit projection_map(auto...) noexcept {}
57
58 //==================================================================================================================
59 /**
60 @name Properties
61 @{
62 **/
63 //==================================================================================================================
64
65 /// Returns the number of elements in a kumi::projection_map
66 [[nodiscard]] static consteval auto size() noexcept { return sizeof...(V); }
67
68 /// Returns `true` if a kumi::projection_map contains 0 elements
69 [[nodiscard]] static consteval bool empty() noexcept { return sizeof...(V) == 0; }
70
71 //==================================================================================================================
72 //! @}
73 //==================================================================================================================
74
75 //==================================================================================================================
76 /**
77 @name Accessors
78 @{
79 **/
80 //==================================================================================================================
81 template<std::size_t I>
82 requires(I < sizeof...(V))
83 constexpr decltype(auto) operator[]([[maybe_unused]] kumi::index_t<I> i) const noexcept
84 {
85 return kumi::_::value_at<I, projection_map>;
86 }
87
88 //==================================================================================================================
89 /**
90 @brief Extracts the Ith element from a kumi::projection_map
91
92 @note Does not participate in overload resolution if `I` is not in [0, sizeof...(V)).
93 @tparam I Compile-time index of the element to access
94 @return A copy of the value of the selected element of current projection_map.
95 **/
96 //==================================================================================================================
97 template<std::size_t I>
98 requires(I < sizeof...(V))
99 [[nodiscard]] friend constexpr decltype(auto) get(projection_map const& pm) noexcept
100 {
101 return pm[kumi::index<I>];
102 }
103
104 //==================================================================================================================
105 //! @}
106 //==================================================================================================================
107 template<typename CharT, typename Traits>
108 10 friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
109 projection_map const&) noexcept
110 {
111 10 std::size_t p = 0;
112 10 os << '[';
113
7/10
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 1 times.
10 ((os << V << (++p < sizeof...(V) ? ", " : "")), ...);
114 10 os << ']';
115 10 return os;
116 }
117 };
118
119 //====================================================================================================================
120 /**
121 @ingroup kumi_utility
122 @brief kumi::projection_map deduction guide
123 @tparam Ts Type lists to build the projections with.
124 **/
125 //====================================================================================================================
126 template<kumi::concepts::projection... Ts> projection_map(Ts...) -> projection_map<Ts{}...>;
127
128 //====================================================================================================================
129 /**
130 @ingroup kumi_utility
131 @brief Creates a kumi::projection_map object, deducing the target type from the types of arguments.
132
133 @note The arguments should model kumi::index
134
135 @tparam Ts Zero or more indexes to construct the projection from.
136 @return A kumi::projection_map constructed from the ts
137
138 ## Examples:
139 @include doc/infra/projections.cpp
140 **/
141 //====================================================================================================================
142 template<kumi::concepts::index... Ts> [[nodiscard]] consteval auto indexes(Ts...) noexcept
143 {
144 return kumi::projection_map<Ts{}...>{};
145 }
146
147 //====================================================================================================================
148 /**
149 @ingroup kumi_utility
150 @brief Creates a kumi::projection_map object, deducing the target type from the types of arguments.
151
152 @note The arguments should model kumi::index
153
154 @tparam vs Zero or more values convertible to size_t to construct the projection from.
155 @return A kumi::projection_map constructed from the vs
156
157 ## Examples:
158 @include doc/infra/projections.cpp
159 **/
160 //====================================================================================================================
161 template<std::convertible_to<std::size_t> auto... vs> [[nodiscard]] consteval auto make_indexes() noexcept
162 {
163 return kumi::projection_map<kumi::index<vs>...>{};
164 }
165
166 //====================================================================================================================
167 /**
168 @ingroup kumi_utility
169 @brief Creates a kumi::projection_map object, deducing the target type from the types of arguments.
170
171 @note The arguments should model kumi::identifier
172
173 @tparam Ts Zero or more identifiers to construct the projection from.
174 @return A kumi::projection_map constructed from the ts
175
176 ## Examples:
177 @include doc/infra/projections.cpp
178 **/
179 //====================================================================================================================
180 template<kumi::concepts::identifier... Ts>
181 requires(kumi::all_uniques_v<Ts...>)
182 [[nodiscard]] consteval auto identifiers(Ts...) noexcept
183 {
184 return kumi::projection_map<Ts{}...>{};
185 }
186 }
187