Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
integer_sequence.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_STDLIB_INCLUDE_STDLIB_DETAIL_INTEGER_SEQUENCE_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_INTEGER_SEQUENCE_HPP_
7
8// parasoft-begin-suppress CERT_CPP-DCL58-a-2 "Part of a standard library implementation"
9// parasoft-begin-suppress AUTOSAR-A17_6_1-a-2 "Part of a standard library implementation"
10
11// IWYU pragma: private, include <utility>
12// IWYU pragma: friend "stdlib_detail/.*"
13
14#include "stdlib/include/stdlib_detail/conditional.hpp"
15#include "stdlib/include/stdlib_detail/cstddef.hpp"
16#include "stdlib/include/stdlib_detail/cstdint.hpp"
17#include "stdlib/include/stdlib_detail/enable_if.hpp"
18#include "stdlib/include/stdlib_detail/is_integral.hpp"
19#include "stdlib/include/stdlib_detail/is_signed.hpp"
20
21namespace std {
22
23/// @brief Implements a compile-time sequence of integers
24/// @tparam Type an integer type to use for the sequence of elements
25/// @tparam Ints a non-type parameter pack of elements defining the sequence
26///
27/// Represents a compile-time sequence of integers of type @c Type. When used as
28/// an argument to a function template, the parameter pack defining the sequence
29/// can be deduced and used in a pack expansion.
30///
31template <typename Type, Type... Ints>
33 public:
34 static_assert(is_integral_v<Type>, "'Type' must be an integer.");
35
36 /// @brief The sequence integer type
37 using value_type = Type;
38
39 /// @brief Returns the number of elements in the sequence
40 /// @return @c sizeof...(Ints)
41 static constexpr auto size() noexcept -> size_t { return sizeof...(Ints); }
42};
43
45
46/// @brief helper for quickly expanding the elements in a sequence
47/// @tparam T integer type
48/// @tparam DoDouble if true, double the number of elements in the sequence
49///
50/// Helper type used to reduce the number of template instantiations for a large
51/// integer sequence.
52///
53template <class T, bool DoDouble>
54class fast_expand_sequence;
55
56/// @brief helper for constructing an integer sequence from @c 0 to <tt>N - 1</tt>
57/// @tparam T integer type
58/// @tparam N remaining number of sequence elements to generate
59/// @tparam Is current sequence
60///
61/// Primary template for expanding the sequence of elements.
62///
63template <typename T, size_t N, T... Is>
64class make_sequence_impl : public fast_expand_sequence<T, (N >= sizeof...(Is))>::template type<N, Is...> {};
65
66/// @brief recursive base case specialization
67/// @tparam T integer type
68/// @tparam Is sequence of elements
69///
70/// If @c N is @c 0, construction of the sequence is complete
71///
72template <typename T>
73class make_sequence_impl<T, 0> {
74 public:
75 /// @brief completed integer sequence type
76 using type = integer_sequence<T>;
77};
78
79/// @brief recursive base case specialization
80/// @tparam T integer type
81/// @tparam Is sequence of elements
82///
83/// If @c N is @c 0, construction of the sequence is complete
84///
85template <typename T, T... Is>
86class make_sequence_impl<T, 0, Is...> {
87 public:
88 /// @brief completed integer sequence type
89 using type = integer_sequence<T, Is...>;
90};
91
92/// @brief initial make sequence specialization
93/// @tparam T integer type
94/// @tparam N remaining number of sequence elements to generate
95///
96/// If the sequence @c Is is empty, reduce remaining by 1 and create a sequence
97/// with the zero element.
98///
99template <typename T, size_t N>
100class make_sequence_impl<T, N> : public make_sequence_impl<T, N - 1, T{}> {};
101
102/// @brief specialization if the sequence cannot be doubled
103/// @tparam T integer type
104/// @tparam DoDouble false for this primary template
105///
106template <class T, bool DoDouble>
107class fast_expand_sequence {
108 public:
109 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
110
111 /// @brief finishes the sequence since it can no longer be doubled
112 /// @tparam Is sequence head
113 /// @tparam Js sequence tail
114 /// @return helper type containing the completed sequence
115 ///
116 template <T... Is, T... Js>
117 static constexpr auto finish_sequence(integer_sequence<T, Js...>)
118 -> make_sequence_impl<T, 0, Is..., sizeof...(Is) + Js...>;
119
120 // parasoft-end-suppress CERT_C-EXP37-a-3
121
122 /// @brief finish the current sequence
123 /// @tparam N remaining number of sequence elements to generate
124 /// @tparam Is current sequence
125 ///
126 template <size_t N, T... Is>
127 using type = decltype(finish_sequence<Is...>(typename make_sequence_impl<T, N>::type{}));
128};
129
130/// @brief specialization if the sequence can be doubled
131/// @tparam T integer type
132///
133template <class T>
134class fast_expand_sequence<T, true> {
135 public:
136 /// @brief double the current sequence
137 /// @tparam N remaining number of sequence elements to generate
138 /// @tparam Is current sequence
139 ///
140 template <size_t N, T... Is>
141 using type = make_sequence_impl<T, N - sizeof...(Is), Is..., sizeof...(Is) + Is...>;
142};
143
144/// @brief Helper variable used to determine if an integer value is negative
145/// @tparam Type integer type
146/// @tparam Value integer value to check
147///
148/// The primary template is always @c false.
149///
150template <typename Type, Type Value, typename = void>
151extern constexpr bool is_negative_v = false;
152
153/// @brief Helper variable used to used to determine if an integer value is negative
154/// @tparam Type integer type
155/// @tparam Value integer value to check
156///
157/// Template specialization for signed integer types.
158///
159/// The value is defined to be <tt>int64_t{Value} < 0</tt>. An explicit
160/// promotion to @c int64_t is used to avoid warnings of implicit conversions of
161/// smaller types (e.g. @c bool) to @c int.
162///
163template <typename Type, Type Value>
164extern constexpr bool is_negative_v<Type, Value, enable_if_t<is_signed_v<Type>>> = int64_t{Value} < 0;
165
166/// @brief Helper type to check that the requested sequence size is non-negative
167/// @tparam Type integer type
168/// @tparam Size sequence size
169///
170/// The primary template is the successful case where the size is non-negative.
171///
172template <typename Type, Type Size, bool = is_negative_v<Type, Size>>
173class make_integer_sequence : public make_sequence_impl<Type, Size> {};
174
175/// @brief Helper type to check that the requested sequence size is non-negative
176/// @tparam Type integer type
177/// @tparam Size sequence size
178///
179/// Template specialization instantiated if @c Size is a negative value.
180///
181template <typename Type, Type Size>
183 public:
184 // parasoft-begin-suppress CERT_C-PRE31-c-3 "False positive: static_assert is
185 // a compile-time assert and can have no side-effects"
186 static_assert(!is_negative_v<Type, Size>, "'Size' must be non-negative.");
187 // parasoft-end-suppress CERT_C-PRE31-c-3
188
189 /// @brief an unused type alias provided to reduce compiler error messages
190 ///
192};
193
194/// @}
195
196} // namespace integer_sequence_detail
197
198// parasoft-begin-suppress AUTOSAR-A2_7_3-a "False positive: Declaration *is* preceeded by the @brief tag."
199/// @brief Helper alias template to simplify creation of @c std::integer_sequence types
200/// with <tt>0</tt>, <tt>1</tt>, ..., <tt>N - 1</tt> as @c Ints.
201/// @tparam Type an integer type to use for the sequence of elements
202/// @tparam Size size of the sequence
203///
204/// If @c N is negative the program is ill-formed. The alias template
205/// @c make_integer_sequence denotes a specialization of @c integer_sequence
206/// with @c N template non-type arguments. The type
207/// @c make_integer_sequence<T, N> denotes the type
208/// <tt>integer_sequence<T, 0, 1, ..., N-1></tt>.
209template <typename Type, Type Size>
211// parasoft-end-suppress AUTOSAR-A2_7_3-a "False positive: Declaration *is* preceeded by the @brief tag."
212
213/// @brief A helper alias template for <tt>integer_sequence<size_t, Ints></tt>
214/// @tparam Ints a non-type parameter pack of elements defining the sequence
215template <size_t... Ints>
217
218// parasoft-begin-suppress AUTOSAR-A2_7_3-a "False positive: there is an @brief tag."
219/// @brief A helper alias template for <tt>make_integer_sequence<size_t, Size></tt>
220/// @tparam Size size of the sequence
221template <size_t Size>
223// parasoft-end-suppress AUTOSAR-A2_7_3-a "False positive: there is an @brief tag."
224
225/// @brief A helper alias template convert any type parameter pack into an index sequence of the same length
226/// @tparam Types parameter pack of types
227template <typename... Types>
229
230} // namespace std
231
232#endif // INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_INTEGER_SEQUENCE_HPP_
static constexpr auto finish_sequence(integer_sequence< T, Js... >) -> make_sequence_impl< T, 0, Is..., sizeof...(Is)+Js... >
finishes the sequence since it can no longer be doubled
Helper type to check that the requested sequence size is non-negative.
Definition integer_sequence.hpp:173
helper for constructing an integer sequence from 0 to N - 1
Definition integer_sequence.hpp:64
Implements a compile-time sequence of integers.
Definition integer_sequence.hpp:32
static constexpr auto size() noexcept -> size_t
Returns the number of elements in the sequence.
Definition integer_sequence.hpp:41
Definition integer_sequence.hpp:44
constexpr bool is_negative_v
Helper variable used to determine if an integer value is negative.
constexpr auto operator()(::arene::base::result< void, E > const &value) const noexcept(noexcept(hash< E >{}(std::declval< E const & >()))) -> std::size_t
Calculate the hash of a result.
Definition result.hpp:1827