Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
integer_sequence_ops.hpp
Go to the documentation of this file.
1// Copyright 2024, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INTEGER_SEQUENCES_INTEGER_SEQUENCE_OPS_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INTEGER_SEQUENCES_INTEGER_SEQUENCE_OPS_HPP_
7
8// IWYU pragma: private, include "arene/base/integer_sequences.hpp"
9
10// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
11
12#include "arene/base/iterator/next.hpp"
13#include "arene/base/stdlib_choice/cstddef.hpp"
14#include "arene/base/stdlib_choice/initializer_list.hpp"
15#include "arene/base/stdlib_choice/integer_sequence.hpp"
16#include "arene/base/stdlib_choice/integral_constant.hpp"
17#include "arene/base/type_traits/conditional.hpp"
18
19// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
20
21namespace arene {
22namespace base {
23
24namespace integer_sequence_ops_detail {
25
26/// @brief termination condition for @c arene::base::integer_sequence_cat
27template <typename... Sequences>
28struct integer_sequence_cat_impl {};
29
30/// @brief Concatenating a single @c integer_sequence is the identity function.
31/// @tparam T the type of the elements
32/// @tparam Elements the elements in the sequence
33template <typename T, T... Elements>
34struct integer_sequence_cat_impl<std::integer_sequence<T, Elements...>> {
35 /// @brief The input sequence
36 using type = std::integer_sequence<T, Elements...>;
37};
38
39/// @brief Concatenates two @c std::integer_sequences.
40///
41/// @tparam T the type of the elements
42/// @tparam SequenceElements1 the sequence of values in the first type sequence
43/// @tparam SequenceElements2 the sequence of values in the second type sequence
44template <typename T, T... SequenceElements1, T... SequenceElements2>
45struct integer_sequence_cat_impl<
46 std::integer_sequence<T, SequenceElements1...>,
47 std::integer_sequence<T, SequenceElements2...>> {
48 /// @brief An @c std::integer_sequence which contains all the elements in @c SequenceElements1 followed by all the
49 /// elements in
50 /// @c SequenceElements2
51 using type = std::integer_sequence<T, SequenceElements1..., SequenceElements2...>;
52};
53
54/// @brief Concatenates a @c std::integer_sequence with multiple sequences.
55/// @tparam Sequence1 the first sequence to concatenate
56/// @tparam OtherSequences the other sequences to concatenate
57template <typename Sequence1, typename... OtherSequences>
58struct integer_sequence_cat_impl<Sequence1, OtherSequences...> {
59 /// @brief An @c std::integer_sequence which contains all the elements in @c Sequence1, followed by the concatenation
60 /// of all the elements from all the sequences in @c OtherSequences
61 using type =
62 typename integer_sequence_cat_impl<Sequence1, typename integer_sequence_cat_impl<OtherSequences...>::type>::type;
63};
64
65} // namespace integer_sequence_ops_detail
66
67/// @brief Produces a single @c std::integer_sequence which is the concatenation of multiple @c std::integer_sequence
68/// @tparam Sequences the sequence of @c std::integer_sequence to concatenate
69/// @pre Each element in @c Sequences must be an instantiation of @c std::integer_sequence.
70/// @return std::integer_sequence A single sequence that contains the elements from all sequences in @c Sequences,
71/// maintaining order of appearance.
72template <typename... Sequences>
73using integer_sequence_cat = typename integer_sequence_ops_detail::integer_sequence_cat_impl<Sequences...>::type;
74
75/// @brief Trait providing the @c Index th element of a @c std::integer_sequence.
76/// The @c value member holds the value. If @c Index is out of range, there is no @c value member.
77/// @tparam Index the index of the element to retrieve
78/// @tparam Sequence the sequence to retrieve the element from
79/// @pre <c>Sequence</c> is an instantiation of @c std::integer_sequence
80template <std::size_t Index, typename Sequence, bool = (Index < Sequence::size())>
82
83namespace integer_sequence_ops_detail {
84
85/// @brief Get the specified element of an integer sequence.
86/// @tparam Index the index of the element to retrieve
87/// @tparam T the type of the elements
88/// @tparam Elements the elements in the sequence
89/// @return the specified element
90/// @pre @c Index must be less than the number of elements in the sequence
91template <std::size_t Index, typename T, T... Elements>
92constexpr auto get_integer_sequence_element(std::integer_sequence<T, Elements...>) noexcept -> T {
93 static_assert(Index < sizeof...(Elements), "Index must be in range of the sequence");
94 return *(arene::base::next(std::initializer_list<T>{Elements...}.begin(), static_cast<std::ptrdiff_t>(Index)));
95}
96
97} // namespace integer_sequence_ops_detail
98
99// @cond INTERNAL
100// parasoft-begin-suppress AUTOSAR-A2_7_3-a-2 "False positive: Documented by reference"
101/// @copydoc arene::base::integer_sequence_element<Index, Sequence, bool>
102template <std::size_t Index, typename T, T... Elements>
104 : public std::integral_constant<
105 T,
107// parasoft-end-suppress AUTOSAR-A2_7_3-a-2
108// @endcond
109
110/// @brief The value of the @c Index th element of a @c std::integer_sequence.
111/// @see arene::base::integer_sequence_element
112/// @pre @c Sequence must be an instantiation of @c std::integer_sequence.
113template <std::size_t Index, typename Sequence>
115
116namespace integer_sequence_ops_detail {
117/// @brief Check if an integer sequence contains a value.
118/// @tparam T the type of the value to search for
119/// @tparam Value the value to search for
120/// @tparam Elements the elements in the sequence
121/// @param value The value to search for
122/// @return true if @c Value is in @c Elements
123/// @return false otherwise.
124template <typename T, T... Elements>
125constexpr auto integer_sequence_contains(T value, std::integer_sequence<T, Elements...>) noexcept -> bool {
126 for (T const element : {Elements...}) {
127 if (element == value) {
128 return true;
129 }
130 }
131 return false;
132}
133/// @brief Check if an empty integer sequence contains a value.
134/// @tparam T the type of the value to search for
135/// @return false
136template <typename T>
137constexpr auto integer_sequence_contains(T, std::integer_sequence<T>) noexcept -> bool {
138 return false;
139}
140
141} // namespace integer_sequence_ops_detail
142
143/// @brief Checks if the specified integer sequence contains the specified value.
144/// @tparam Sequence the sequence to search
145/// @tparam value the value to search for
146/// @pre @c Sequence must be an instantiation of @c std::integer_sequence.
147template <typename Sequence, typename Sequence::value_type Value>
148extern constexpr bool integer_sequence_contains_v =
150
151/// @brief Trait for the index of the first occurrence of a value in a @c std::integer_sequence.
152///
153/// The result is stored in the @c value member if it is found, otherwise the member @c value is not provided.
154/// @tparam Sequence the sequence to search
155/// @tparam value the value to search for
156/// @pre @c Sequence must be an instantiation of @c std::integer_sequence.
157template <typename Sequence, typename Sequence::value_type Value, bool = integer_sequence_contains_v<Sequence, Value>>
159
160namespace integer_sequence_ops_detail {
161
162/// @brief Implementation helper for @c get_integer_sequence_index_of to detemplitize it and allow 100% branch coverage.
163/// @tparam T the type of the value to search for
164/// @param value the value to search for
165/// @param elements the elements in the sequence
166/// @return The index of the first instance of <c>value</c> in <c>elements</c>, else @c elements.size() if not found.
167template <typename T>
168constexpr auto get_integer_sequence_index_of_impl(T value, std::initializer_list<T> elements) noexcept -> std::size_t {
169 std::size_t index{0U};
170 for (T const element : elements) {
171 if (element == value) {
172 return index;
173 }
174 ++index;
175 }
176 return index;
177}
178
179/// @brief Return the index of a value in an integer sequence
180/// @tparam T the type of the value to search for
181/// @tparam Value the value to search for
182/// @tparam Elements the elements in the sequence
183/// @return The index of <c>Value</c> in <c>Elements</c>
184/// @pre Value must be present in @c Elements else compilation will fail.
185template <typename T, T Value, T... Elements>
186constexpr auto get_integer_sequence_index_of(std::integer_sequence<T, Elements...>) noexcept -> std::size_t {
187 constexpr std::size_t index{get_integer_sequence_index_of_impl(Value, {Elements...})};
188 static_assert(index < sizeof...(Elements), "Value must be in input sequence!");
189 return index;
190}
191} // namespace integer_sequence_ops_detail
192
193// @cond INTERNAL
194// parasoft-begin-suppress AUTOSAR-A2_7_3-a-2 "False positive: Documented by reference"
195/// @copydoc arene::base::integer_sequence_index_of<Sequence, Value, bool>
196template <typename Sequence, typename Sequence::value_type Value>
198 : public std::integral_constant<
199 std::size_t,
201 )> {};
202// parasoft-end-suppress AUTOSAR-A2_7_3-a-2
203// @endcond
204
205/// @brief The index of the first occurrence of a value in a @c std::integer_sequence.
206/// @see arene::base::integer_sequence_index_of_v
207/// @pre @c Sequence must be an instantiation of @c std::integer_sequence.
208/// @pre @c value must occur in @c Sequence else compilation will fail.
209template <typename Sequence, typename Sequence::value_type Value>
211
212namespace integer_sequence_ops_detail {
213/// @brief Return the number of occurrences of a value in an integer sequence
214/// @tparam T the type of the value to search for
215/// @tparam Value the value to search for
216/// @tparam Elements the elements in the sequence
217/// @param value The element to search for
218/// @return The number of occurrences of @c value in @c Elements
219template <typename T, T... Elements>
220constexpr auto get_integer_sequence_count_of(T value, std::integer_sequence<T, Elements...>) noexcept -> std::size_t {
221 std::size_t count{0U};
222 for (T const element : {Elements...}) {
223 if (element == value) {
224 ++count;
225 }
226 }
227 return count;
228}
229/// @brief Return the number of occurrences of a value in an empty integer sequence
230/// @tparam T the type of the value to search for
231/// @return Zero
232template <typename T>
233constexpr auto get_integer_sequence_count_of(T, std::integer_sequence<T>) noexcept -> std::size_t {
234 return 0U;
235}
236
237} // namespace integer_sequence_ops_detail
238
239/// @brief Get the number of occurrences of a value in the provided sequence.
240/// The result is stored in the <c>value</c> member.
241/// @tparam Sequence the sequence to search
242/// @tparam value the value to search for
243/// @pre @c Sequence must be an instantiation of @c std::integer_sequence.
244template <typename Sequence, typename Sequence::value_type Value>
249
250/// @brief Get the number of occurrences of a value in the provided sequence.
251/// @tparam Sequence the sequence to search
252/// @tparam value the value to search for
253/// @pre @c Sequence must be an instantiation of @c std::integer_sequence.
254template <typename Sequence, typename Sequence::value_type Value>
256
257namespace integer_sequence_ops_detail {
258/// @brief Create a new integer sequence with the unique values from the provided
259/// integer sequence. The values in the resultant sequence are in the order of
260/// their first occurrence in the provided sequence.
261/// The resultant sequence is returned in the <c>type</c> member type.
262/// @tparam Sequence the provided integer sequence
263/// @pre <c>Sequence</c> must be an instantiation of
264/// <c>std::integer_sequence</c>
265template <typename Sequence>
266class integer_sequence_unique_elements_impl;
267
268/// @brief Create a new integer sequence with the unique values from the provided
269/// integer sequence. The values in the resultant sequence are in the order of
270/// their first occurrence in the provided sequence.
271/// The resultant sequence is returned in the <c>type</c> member type.
272/// @tparam T the type of the integer sequence elements
273template <typename T>
274class integer_sequence_unique_elements_impl<std::integer_sequence<T>> {
275 public:
276 /// @brief The resulting sequence
277 using type = std::integer_sequence<T>;
278};
279
280/// @brief Merge two integer sequences together to produce a result with no duplicates.
281/// The resultant sequence is returned in the <c>type</c> member type.
282/// @tparam UniqueSequence The first sequence
283/// @tparam Sequence2 The second sequence
284/// @pre <c>UniqueSequence</c> and <c>Sequence2</c> must both be instantiations
285/// of <c>std::integer_sequence</c> with the same element type.
286/// <c>UniqueSequence</c> must not have any duplicate values.
287template <typename UniqueSequence, typename Sequence2>
288class integer_sequence_merge_unique_elements_impl;
289
290/// @brief Merge two integer sequences together to produce a result with no duplicates.
291/// The resultant sequence is returned in the <c>type</c> member type.
292/// @tparam UniqueSequence The first sequence
293/// @tparam T The type of elements in the second sequence
294/// @pre <c>UniqueSequence</c> must both be an instantiation of
295/// <c>std::integer_sequence</c> with an element type of <c>T</c>.
296/// <c>UniqueSequence</c> must not have any duplicate values
297template <typename UniqueSequence, typename T>
298class integer_sequence_merge_unique_elements_impl<UniqueSequence, std::integer_sequence<T>> {
299 public:
300 /// @brief The resulting sequence
301 using type = UniqueSequence;
302};
303
304/// @brief Merge two integer sequences together to produce a result with no duplicates.
305/// The resultant sequence is returned in the <c>type</c> member type.
306/// @tparam T The type of elements in the sequences
307/// @tparam UniqueElements The elements in the first sequence
308/// @tparam FirstElement The first element in the second sequence
309/// @tparam OtherElements The other elements in the second sequence
310/// @pre <c>UniqueElements</c> must not have any duplicate values
311template <typename T, T... UniqueElements, T FirstElement, T... OtherElements>
312class integer_sequence_merge_unique_elements_impl<
313 std::integer_sequence<T, UniqueElements...>,
314 std::integer_sequence<T, FirstElement, OtherElements...>> {
315 private:
316 /// @brief The current sequence of unique elements
317 using unique_sequence = std::integer_sequence<T, UniqueElements...>;
318 /// @brief A sequence of the remaining unprocessed elements from the second sequence
319 using remainder_sequence = std::integer_sequence<T, OtherElements...>;
320
321 public:
322 /// @brief The resulting sequence
323 using type = typename conditional_t<
324 integer_sequence_contains_v<unique_sequence, FirstElement>,
325 integer_sequence_merge_unique_elements_impl<unique_sequence, remainder_sequence>,
326 integer_sequence_merge_unique_elements_impl<
327 std::integer_sequence<T, UniqueElements..., FirstElement>,
328 remainder_sequence>>::type;
329};
330
331} // namespace integer_sequence_ops_detail
332
333/// @brief Create a new integer sequence with the unique values from the provided
334/// integer sequence. The values in the resultant sequence are in the order of
335/// their first occurrence in the provided sequence.
336/// @tparam Sequence the provided integer sequence
337/// @pre <c>Sequence</c> must be an instantiation of
338/// <c>std::integer_sequence</c>
339template <typename Sequence>
342
343} // namespace base
344} // namespace arene
345
346#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INTEGER_SEQUENCES_INTEGER_SEQUENCE_OPS_HPP_
Get the number of occurrences of a value in the provided sequence. The result is stored in the value ...
Definition integer_sequence_ops.hpp:248
Trait providing the Index th element of a std::integer_sequence. The value member holds the value....
Definition integer_sequence_ops.hpp:81
Definition array_exceptions_disabled.cpp:11
constexpr auto integer_sequence_element_v
The value of the Index th element of a std::integer_sequence.
constexpr bool integer_sequence_contains_v
Checks if the specified integer sequence contains the specified value.
constexpr std::size_t integer_sequence_index_of_v
The index of the first occurrence of a value in a std::integer_sequence.
constexpr std::size_t integer_sequence_count_of_v
Get the number of occurrences of a value in the provided sequence.
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10
Trait for the index of the first occurrence of a value in a std::integer_sequence.
Definition integer_sequence_ops.hpp:158