Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
vector.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_INLINE_CONTAINER_VECTOR_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_VECTOR_HPP_
7
8// parasoft-begin-suppress AUTOSAR-A7_1_5-a-2 "Trailing return syntax permitted by A7-1-5 Permit #1 v1.0.0"
9
10// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
11#include "arene/base/algorithm/equal.hpp"
12#include "arene/base/algorithm/lexicographical_compare.hpp"
13#include "arene/base/array/array.hpp"
14#include "arene/base/compare/operators.hpp"
15#include "arene/base/constraints/constraints.hpp"
16#include "arene/base/contracts/contract.hpp"
17#include "arene/base/detail/exceptions.hpp"
18#include "arene/base/detail/wrapped_iterator.hpp" // IWYU pragma: keep
19#include "arene/base/inline_container/detail/unsafe_element_storage.hpp"
20#include "arene/base/iterator/distance.hpp"
21#include "arene/base/iterator/next.hpp"
22#include "arene/base/iterator/reverse_iterator.hpp"
23#include "arene/base/memory/construct_at.hpp"
24#include "arene/base/optional/optional.hpp"
25#include "arene/base/span/span.hpp"
26#include "arene/base/stdlib_choice/cstddef.hpp"
27#include "arene/base/stdlib_choice/enable_if.hpp"
28#include "arene/base/stdlib_choice/forward.hpp"
29#include "arene/base/stdlib_choice/initializer_list.hpp"
30#include "arene/base/stdlib_choice/integral_constant.hpp"
31#include "arene/base/stdlib_choice/is_assignable.hpp"
32#include "arene/base/stdlib_choice/is_constructible.hpp"
33#include "arene/base/stdlib_choice/is_copy_assignable.hpp"
34#include "arene/base/stdlib_choice/is_copy_constructible.hpp"
35#include "arene/base/stdlib_choice/is_default_constructible.hpp"
36#include "arene/base/stdlib_choice/is_destructible.hpp"
37#include "arene/base/stdlib_choice/is_move_assignable.hpp"
38#include "arene/base/stdlib_choice/is_move_constructible.hpp"
39#include "arene/base/stdlib_choice/is_same.hpp"
40#include "arene/base/stdlib_choice/iterator_traits.hpp"
41#include "arene/base/stdlib_choice/min_value_overload.hpp"
42#include "arene/base/stdlib_choice/move.hpp"
43#include "arene/base/stdlib_choice/move_iterator.hpp"
44#include "arene/base/type_manipulation/non_constructible_dummy.hpp"
45#include "arene/base/type_traits/comparison_traits.hpp"
46#include "arene/base/type_traits/conditional.hpp"
47#include "arene/base/type_traits/denotes_range.hpp"
48#include "arene/base/type_traits/is_swappable.hpp"
49#include "arene/base/type_traits/iterator_category_traits.hpp"
50#include "arene/base/utility/in_place.hpp"
51#include "arene/base/utility/make_subrange.hpp"
52#include "arene/base/utility/swap.hpp"
53
54// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
55
56// parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
57// parasoft-begin-suppress AUTOSAR-M2_10_1-a-2 "Similar names permitted by M2-10-1 Permit #1"
58// parasoft-begin-suppress CERT_CPP-ERR55-a-2 "False positive: Exception specification is conditional"
59// parasoft-begin-suppress CERT_CPP-ERR50-h-3 "False positive: Exception specification is conditional"
60// parasoft-begin-suppress CERT_CPP-ERR50-g-3 "False positive: Exception specification is conditional"
61// parasoft-begin-suppress CERT_CPP-ERR51-b-3 "False positive: Exception specification is conditional"
62// parasoft-begin-suppress AUTOSAR-A15_3_2-a-2 "False positive: Exception specification is conditional"
63// parasoft-begin-suppress AUTOSAR-A15_5_3-g-2 "False positive: Exception specification is conditional"
64// parasoft-begin-suppress AUTOSAR-A15_5_3-h-2 "False positive: Exception specification is conditional"
65// parasoft-begin-suppress AUTOSAR-M15_3_4-b-2 "False positive: Exception is caught"
66// parasoft-begin-suppress AUTOSAR-A15_2_1-b-2 "False positive: Throwing constructor not invoked"
67// parasoft-begin-suppress CERT_CPP-ERR50-b-3 "False positive: Called functions are noexcept"
68// parasoft-begin-suppress AUTOSAR-A15_5_1-a-2 "False positive: Called functions are noexcept"
69// parasoft-begin-suppress AUTOSAR-A15_5_3-b-2 "False positive: Called functions are noexcept"
70// parasoft-begin-suppress CERT_CPP-DCL57-a-2 "False positive: Called functions are noexcept"
71
72namespace arene {
73namespace base {
74
75/// @brief A container similar to @c std::vector<T> that has a fixed capacity. The
76/// storage for the elements is held directly within the class. Any attempt to
77/// store more than @c Capacity elements will throw @c std::length_error
78/// @tparam T The type of each element
79/// @tparam Capacity The maximum number of elements that can be stored.
80template <typename T, std::size_t Capacity>
81class inline_vector;
82
83namespace inline_vector_detail {
84
85/// @brief implementation details for @c inline_vector which depend on neither the capacity nor the storage mechanism.
86template <typename T>
87class vector_base {
88 protected:
89 /// @brief Tag type used to protect construction of iterators.
90 class iterator_passkey {
91 public:
92 /// @brief The default constructor is explicit to disable construction with just @c {}
93 constexpr explicit iterator_passkey() noexcept = default;
94 };
95
96 public:
97 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False Positive: These identifiers do not hide anything"
98 // parasoft-begin-suppress AUTOSAR-A2_10_1-e "False Positive: These identifiers do not hide anything"
99 /// @brief The type used for the size of the vector.
100 using size_type = std::size_t;
101 /// @brief The type of a value stored in the vector
102 using value_type = T;
103 /// @brief The type of a reference to a value stored in the vector
104 using reference = value_type&;
105 /// @brief The type of a const reference to a value stored in the vector
106 using const_reference = value_type const&;
107 /// @brief The type of a pointer to an element stored in the container
108 using pointer = value_type*;
109 /// @brief The type of a const pointer to an element stored in the container
110 using const_pointer = value_type const*;
111 /// @brief The type of an iterator to a position in the vector
112 using iterator = ::arene::base::detail::wrapped_iterator<pointer, iterator_passkey>;
113 /// @brief The type of a const iterator to a position in the vector
114 using const_iterator = ::arene::base::detail::wrapped_iterator<const_pointer, iterator_passkey>;
115 /// @brief The type of a reverse-iterator to a position in the vector
116 using reverse_iterator = ::arene::base::reverse_iterator<iterator>;
117 /// @brief The type of a const reverse-iterator to a position in the vector
118 using const_reverse_iterator = ::arene::base::reverse_iterator<const_iterator>;
119 /// @brief The type of the difference between two iterators
120 using difference_type = typename iterator::difference_type;
121 // parasoft-end-suppress AUTOSAR-A2_10_1-e
122 // parasoft-end-suppress AUTOSAR-A2_10_1-d
123};
124
125/// @brief Type trait to check if we can construct a vector of @c T in c constexpr
126/// contexts. The result is @c true if we can, @c false otherwise.
127/// @tparam T the type being checked.
128template <typename T>
129constexpr bool allow_constexpr_vector_v =
130 std::is_trivially_default_constructible<T>::value && std::is_trivially_move_assignable<T>::value;
131
132/// @brief Base class for @c inline_vector that holds the elements when the elements aren't usable in @c constexpr
133/// contexts.
134/// @tparam T The type of the elements
135/// @tparam Capacity The capacity of the vector
136template <typename T, std::size_t Capacity, bool = std::is_trivially_destructible<T>::value>
137// NOLINTNEXTLINE(hicpp-special-member-functions)
138class inline_vector_internal_non_constexpr_storage {
139 public:
140 /// @brief Deleted copy constructor
141 inline_vector_internal_non_constexpr_storage(inline_vector_internal_non_constexpr_storage const&) = delete;
142 /// @brief Deleted move constructor
143 inline_vector_internal_non_constexpr_storage(inline_vector_internal_non_constexpr_storage&&) = delete;
144
145 /// @brief Deleted copy assignment
146 auto operator=(inline_vector_internal_non_constexpr_storage const&)
147 -> inline_vector_internal_non_constexpr_storage& = delete;
148 /// @brief Deleted move assignment
149 auto operator=(inline_vector_internal_non_constexpr_storage&&)
150 -> inline_vector_internal_non_constexpr_storage& = delete;
151
152 protected:
153 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'size_type' does not hide anything"
154 /// @brief The type used to hold the size
155 using size_type = std::size_t;
156 // parasoft-end-suppress AUTOSAR-A2_10_1-d
157 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'value_type' does not hide anything"
158 /// @brief The type of the elements
159 using value_type = T;
160 // parasoft-end-suppress AUTOSAR-A2_10_1-d
161
162 /// @brief Construct the storage with no elements
163 constexpr inline_vector_internal_non_constexpr_storage() = default;
164
165 /// @brief Destroy all constructed elements.
166 ~inline_vector_internal_non_constexpr_storage() {
167 // parasoft-begin-suppress AUTOSAR-M0_1_3-b-2 "False positive: necessary for invoking the destructors"
168 for (auto& value : values()) {
169 value.~T();
170 }
171 // parasoft-end-suppress AUTOSAR-M0_1_3-b-2
172 }
173
174 /// @brief Get a span over the current elements
175 /// @return The span
176 constexpr auto values() noexcept -> span<value_type> {
177 // We specify Capacity as a maximum valid value to eliminate the
178 // precondition in base::span constructor.
179 return {&values_.front().object, std::min(size_, Capacity)};
180 }
181
182 /// @brief Get a @c const span over the current elements
183 /// @return The span
184 constexpr auto values() const noexcept -> span<value_type const> {
185 // We specify Capacity as a maximum valid value to eliminate the
186 // precondition in base::span constructor.
187 return {&values_.front().object, std::min(size_, Capacity)};
188 }
189
190 /// @brief If the current size is more than @c new_size, reduce the size to @c new_size.
191 /// @param new_size The new size limit
192 constexpr void shrink_to(size_type new_size) noexcept {
193 if (new_size < this->size_) {
194 // parasoft-begin-suppress AUTOSAR-M0_1_3-b-2 "False positive: necessary for invoking the destructors"
195 for (auto& value : values().last(size_ - new_size)) {
196 value.~T();
197 }
198 // parasoft-end-suppress AUTOSAR-M0_1_3-b-2
199 size_ = new_size;
200 }
201 }
202
203 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "Protected member to allow access by derived class"
204 /// @brief The current size
205 // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
206 size_type size_{0U};
207 // parasoft-end-suppress AUTOSAR-M11_0_1-a
208
209 /// @brief underlying element type that allows a value to exist or not exist
210 using element_storage = inline_container::detail::unsafe_element_storage<T>;
211
212 // parasoft-begin-suppress CERT_C-PRE31-c-3 "False positive: static_assert is a compile-time assert and can have no
213 // side-effects"
214 static_assert(alignof(element_storage) == alignof(T), "Alignment must be the same");
215 static_assert(sizeof(element_storage) == sizeof(T), "Size must be the same");
216 // parasoft-end-suppress CERT_C-PRE31-c-3
217
218 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "Protected member to allow access by derived class"
219 // parasoft-begin-suppress AUTOSAR-M8_5_2-b-2 "False Positive: all elements default-initialized"
220 /// @brief The storage for the elements
221 // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
222 arene::base::array<element_storage, Capacity> values_{};
223 // parasoft-end-suppress AUTOSAR-M8_5_2-b-2
224 // parasoft-end-suppress AUTOSAR-M11_0_1-a
225};
226
227/// @brief Base class for @c inline_vector that holds the elements when the elements aren't usable in @c constexpr
228/// contexts.
229/// @tparam T The type of the elements
230/// @tparam Capacity The capacity of the vector
231///
232/// This specialization handles the case that the elements are trivially destructible
233template <typename T, std::size_t Capacity>
234// NOLINTNEXTLINE(hicpp-special-member-functions)
235class inline_vector_internal_non_constexpr_storage<T, Capacity, true> {
236 protected:
237 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'size_type' does not hide anything"
238 /// @brief The type used to hold the size
239 using size_type = std::size_t;
240 // parasoft-end-suppress AUTOSAR-A2_10_1-d
241 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'value_type' does not hide anything"
242 /// @brief The type of the elements
243 using value_type = T;
244 // parasoft-end-suppress AUTOSAR-A2_10_1-d
245
246 /// @brief Get a span over the current elements
247 /// @return The span
248 constexpr auto values() noexcept -> span<value_type> {
249 // We specify Capacity as a maximum valid value to eliminate the
250 // precondition in base::span constructor.
251 return {&values_.front().object, std::min(size_, Capacity)};
252 }
253
254 /// @brief Get a @c const span over the current elements
255 /// @return The span
256 constexpr auto values() const noexcept -> span<value_type const> {
257 // We specify Capacity as a maximum valid value to eliminate the
258 // precondition in base::span constructor.
259 return {&values_.front().object, std::min(size_, Capacity)};
260 }
261
262 /// @brief If the current size is more than @c new_size, reduce the size to @c new_size.
263 /// @param new_size The new size limit
264 constexpr void shrink_to(size_type new_size) noexcept {
265 if (new_size < this->size_) {
266 size_ = new_size;
267 }
268 }
269
270 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "Protected member to allow access by derived class"
271 /// @brief The current size
272 // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
273 size_type size_{0U};
274 // parasoft-end-suppress AUTOSAR-M11_0_1-a
275
276 /// @brief underlying element type that allows a value to exist or not exist
277 using element_storage = inline_container::detail::unsafe_element_storage<T>;
278
279 // parasoft-begin-suppress CERT_C-PRE31-c-3 "False positive: static_assert is a compile-time assert and can have no
280 // side-effects"
281 static_assert(alignof(element_storage) == alignof(T), "Alignment must be the same");
282 static_assert(sizeof(element_storage) == sizeof(T), "Size must be the same");
283 // parasoft-end-suppress CERT_C-PRE31-c-3
284
285 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "Protected member to allow access by derived class"
286 // parasoft-begin-suppress AUTOSAR-M8_5_2-b-2 "False Positive: all elements default-initialized"
287 /// @brief The storage for the elements
288 // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
289 arene::base::array<element_storage, Capacity> values_{};
290 // parasoft-end-suppress AUTOSAR-M8_5_2-b-2
291 // parasoft-end-suppress AUTOSAR-M11_0_1-a
292};
293
294// parasoft-begin-suppress CERT_CPP-MEM51-c-1 "False Positive: Copy assignment is defined or deleted as appropriate"
295// parasoft-begin-suppress AUTOSAR-M14_5_3-a-2 "False Positive: Copy assignment is defined or deleted as appropriate"
296// parasoft-begin-suppress AUTOSAR-A14_5_1-a-2 "False Positive: Copy constructor is defined or deleted as appropriate"
297// parasoft-begin-suppress AUTOSAR-A1_1_1-c-2 "False Positive: Copy operations are defined or deleted as appropriate"
298// parasoft-begin-suppress AUTOSAR-A1_1_1-b-2 "False Positive: Copy operations are defined or deleted as appropriate"
299// parasoft-begin-suppress AUTOSAR-A12_0_1-a-2 "False Positive: Copy operations are defined or deleted as appropriate"
300/// @brief Base class for @c inline_vector that holds the elements.
301/// @tparam T The type of the elements
302/// @tparam Capacity The capacity of the vector
303template <typename T, std::size_t Capacity, bool = Capacity != 0 && allow_constexpr_vector_v<T>>
304// NOLINTNEXTLINE(hicpp-special-member-functions)
305class inline_vector_internal_storage : public inline_vector_internal_non_constexpr_storage<T, Capacity> {
306 /// @brief The base class with the actual storage
307 using non_constexpr_storage_base = inline_vector_internal_non_constexpr_storage<T, Capacity>;
308
309 /// @brief The type of the argument to the "copy constructor": either @c
310 /// inline_vector_internal_storage to provide a real copy constructor if @c T is
311 /// copy-constructible, or @c non_constructible_dummy otherwise.
312 using copy_constructor_arg =
313 conditional_t<std::is_copy_constructible<T>::value, inline_vector_internal_storage, non_constructible_dummy>;
314
315 /// @brief The type of the argument to the "copy assignment operator": either @c
316 /// inline_vector_internal_storage to provide a real copy assignment operator if @c T is
317 /// copy-assignable, or @c non_constructible_dummy otherwise.
318 using copy_assignment_arg = conditional_t<
319 std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
320 inline_vector_internal_storage,
321 non_constructible_dummy>;
322
323 /// @brief The type of the argument to the "move constructor": either @c
324 /// inline_vector_internal_storage to provide a real move constructor if @c T is
325 /// move-constructible, or @c non_constructible_dummy otherwise.
326 using move_constructor_arg =
327 conditional_t<std::is_move_constructible<T>::value, inline_vector_internal_storage, non_constructible_dummy>;
328
329 /// @brief The type of the argument to the "move assignment operator": either @c
330 /// inline_vector_internal_storage to provide a real move assignment operator if @c T is
331 /// move-assignable, or @c non_constructible_dummy otherwise.
332 using move_assignment_arg = conditional_t<
333 std::is_move_constructible<T>::value && std::is_move_assignable<T>::value,
334 inline_vector_internal_storage,
335 non_constructible_dummy>;
336
337 public:
338 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'size_type' does not hide anything"
339 /// @brief The type used to hold the size
340 using size_type = typename non_constexpr_storage_base::size_type;
341 // parasoft-end-suppress AUTOSAR-A2_10_1-d
342 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'value_type' does not hide anything"
343 /// @brief The type of the elements
344 using value_type = typename non_constexpr_storage_base::value_type;
345 // parasoft-end-suppress AUTOSAR-A2_10_1-d
346
347 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property,
348 /// @brief Get the maximum number of elements in the vector, @c Capacity
349 static constexpr std::integral_constant<std::size_t, Capacity> capacity{};
350 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
351 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property,
352 /// @brief Get the maximum number of elements in the vector, @c Capacity
353 static constexpr std::integral_constant<std::size_t, Capacity> max_size{};
354 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
355
356 /// @brief Construct the storage with no elements
357 constexpr inline_vector_internal_storage() = default;
358
359 // parasoft-begin-suppress AUTOSAR-A12_8_6-a-2 "Not guaranteed to be a base class"
360 /// @brief Copy constructor if @c T is copy-constructible, useless conversion from @c
361 /// non_constructible_dummy otherwise. If copying, copies all the elements
362 /// from @c other into @c *this.
363 /// @param other The source
364 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
365 constexpr inline_vector_internal_storage(copy_constructor_arg const& other
366 ) noexcept(std::is_nothrow_copy_constructible<T>::value)
367 : non_constexpr_storage_base{} {
368 for (auto& value : other.values()) {
369 internal_emplace_back(value);
370 }
371 }
372 // parasoft-end-suppress AUTOSAR-A12_8_6-a-2
373
374 // parasoft-begin-suppress AUTOSAR-A15_5_1-b-2 "False positive: Conditionally noxecept"
375 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "False positive: Elements are moved"
376 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "False positive: Elements are moved"
377 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "False positive: Elements are moved"
378 /// @brief Move constructor if @c T is move-constructible, useless conversion from @c
379 /// non_constructible_dummy otherwise. If moving, move-constructs all the
380 /// elements from @c other into @c *this.
381 /// @param other The source
382 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
383 constexpr inline_vector_internal_storage(move_constructor_arg&& other
384 ) noexcept(std::is_nothrow_move_constructible<T>::value)
385 : non_constexpr_storage_base{} {
386 for (auto& value : other.values()) {
387 internal_emplace_back(std::move(value));
388 }
389 other.shrink_to(0U);
390 }
391 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
392 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
393 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
394 // parasoft-end-suppress AUTOSAR-A15_5_1-b-2
395
396 // parasoft-begin-suppress AUTOSAR-A12_8_6-a-2 "Not guaranteed to be a base class"
397 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "False positive: Elements are moved"
398 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "False positive: Elements are moved"
399 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "False positive: Elements are moved"
400 /// @brief Copy assignment operator if @c T is copy-constructible and copy
401 /// assignable, useless conversion from @c non_constructible_dummy otherwise.
402 /// If copying, copies all the elements from @c other into @c *this, assigning
403 /// over existing elements, constructing new ones, and destroying an excess
404 /// existing elements.
405 /// @param other The source
406 /// @return @c *this
407 constexpr auto operator=(copy_assignment_arg const& other
408 ) noexcept(std::is_nothrow_copy_constructible<T>::value && std::is_nothrow_copy_assignable<T>::value)
409 -> inline_vector_internal_storage& {
410 if (&other != this) {
411 auto our_values = this->values();
412 auto other_values = other.values();
413 inline_vector_internal_storage::size_type idx{0U};
414 for (; (idx < our_values.size()) && (idx < other_values.size()); ++idx) {
415 our_values[idx] = other_values[idx];
416 }
417 for (; idx < other_values.size(); ++idx) {
418 internal_emplace_back(other_values[idx]);
419 }
420 this->shrink_to(idx);
421 }
422 return *this;
423 }
424 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
425 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
426 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
427 // parasoft-end-suppress AUTOSAR-A12_8_6-a-2
428
429 // parasoft-begin-suppress AUTOSAR-A15_5_1-b-2 "False positive: Conditionally noxecept"
430 // parasoft-begin-suppress AUTOSAR-A12_8_6-a-2 "Not guaranteed to be a base class"
431 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "False positive: Elements are moved"
432 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "False positive: Elements are moved"
433 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "False positive: Elements are moved"
434 /// @brief Move assignment operator if @c T is move-constructible and move
435 /// assignable, useless conversion from @c non_constructible_dummy otherwise.
436 /// If moving, copies all the elements from @c other into @c *this, assigning
437 /// over existing elements, constructing new ones, and destroying an excess
438 /// existing elements.
439 /// @param other The source
440 /// @return @c *this
441 constexpr auto operator=(move_assignment_arg&& other
442 ) noexcept(std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value)
443 -> inline_vector_internal_storage& {
444 if (&other != this) {
445 auto our_values = this->values();
446 auto other_values = other.values();
447 inline_vector_internal_storage::size_type idx{0U};
448 for (; (idx < our_values.size()) && (idx < other_values.size()); ++idx) {
449 our_values[idx] = std::move(other_values[idx]);
450 }
451 for (; idx < other_values.size(); ++idx) {
452 internal_emplace_back(std::move(other_values[idx]));
453 }
454 this->shrink_to(idx);
455 other.shrink_to(0U);
456 }
457 return *this;
458 }
459 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
460 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
461 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
462 // parasoft-end-suppress AUTOSAR-A12_8_6-a-2
463 // parasoft-end-suppress AUTOSAR-A15_5_1-b-2
464 /// @brief Destroy all constructed elements.
465 ~inline_vector_internal_storage() = default;
466
467 /// @brief Construct a new element at the end of the existing range, from the
468 /// supplied arguments.
469 /// @tparam Args The types of the arguments
470 /// @param args The constructor arguments
471 template <typename... Args>
472 constexpr void internal_emplace_back(Args&&... args) noexcept(std::is_nothrow_constructible<T, Args...>::value) {
473 construct_at(&this->values_[this->size_].object, std::forward<Args>(args)...);
474 ++this->size_;
475 }
476};
477// parasoft-end-suppress AUTOSAR-A12_0_1-a-2
478// parasoft-end-suppress AUTOSAR-A1_1_1-c-2
479// parasoft-end-suppress AUTOSAR-A1_1_1-b-2
480// parasoft-end-suppress AUTOSAR-M14_5_3-a-2
481// parasoft-end-suppress AUTOSAR-A14_5_1-a-2
482
483/// @brief Specialization for the case that the element @c T is suitable for use in a
484/// @c constexpr container. The elements are held as a default-constructed array
485/// of @c T rather than an array of storage entries.
486/// @tparam T The type of the elements
487/// @tparam Capacity The number of elements that can be stored
488template <typename T, std::size_t Capacity>
489class inline_vector_internal_storage<T, Capacity, true> {
490 public:
491 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'size_type' does not hide anything"
492 /// @brief The type used to hold the size
493 using size_type = std::size_t;
494 // parasoft-end-suppress AUTOSAR-A2_10_1-d
495 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'value_type' does not hide anything"
496 /// @brief The type of the elements
497 using value_type = T;
498 // parasoft-end-suppress AUTOSAR-A2_10_1-d
499
500 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property,
501 /// @brief Get the maximum number of elements in the vector, @c Capacity
502 static constexpr std::integral_constant<size_type, Capacity> capacity{};
503 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
504 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property,
505 /// @brief Get the maximum number of elements in the vector, @c Capacity
506 static constexpr std::integral_constant<size_type, Capacity> max_size{};
507 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
508
509 /// @brief Get a span of the current "live" values
510 /// @return The span
511 constexpr auto values() noexcept -> span<value_type> {
512 // We specify Capacity as a maximum valid value to eliminate the
513 // precondition in base::span constructor.
514 return {&values_.front(), std::min(size_, Capacity)};
515 }
516 /// @brief Get a @c const span of the current "live" values
517 /// @return The span
518 constexpr auto values() const noexcept -> span<value_type const> {
519 // We specify Capacity as a maximum valid value to eliminate the
520 // precondition in base::span constructor.
521 return {&values_.front(), std::min(size_, Capacity)};
522 }
523
524 /// @brief Construct a new element at the end of the existing range, from the
525 /// supplied arguments.
526 /// @tparam Args The types of the arguments
527 /// @param args The constructor arguments
528 template <typename... Args>
529 constexpr void internal_emplace_back(Args&&... args) noexcept(std::is_nothrow_constructible<T, Args...>::value) {
530 // parasoft-begin-suppress AUTOSAR-A5_2_2-a-2 "False positive: constructor call, not C-style cast"
531 values_[size_] = T(std::forward<Args>(args)...);
532 // parasoft-end-suppress AUTOSAR-A5_2_2-a-2
533 ++size_;
534 }
535
536 /// @brief If the current size is more than @c new_size, reduce the size to @c new_size.
537 /// @param new_size The new size limit
538 constexpr void shrink_to(size_type new_size) noexcept {
539 if (new_size < size_) {
540 size_ = new_size;
541 }
542 }
543
544 private:
545 /// @brief The current size
546 size_type size_{0U};
547
548 /// @brief The elements
549 arene::base::array<value_type, Capacity> values_{};
550};
551// parasoft-end-suppress CERT_CPP-MEM51-c-1
552
553/// @brief Specialization for the case that the @c Capacity is zero: such a vector can
554/// never hold any elements, so has a size of zero and is an empty class.
555/// @tparam T The element type
556template <typename T>
557class inline_vector_internal_storage<T, 0, false> {
558 public:
559 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'size_type' does not hide anything"
560 /// @brief The type used to hold the size
561 using size_type = std::size_t;
562 // parasoft-end-suppress AUTOSAR-A2_10_1-d
563 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: 'value_type' does not hide anything"
564 /// @brief The type of the elements
565 using value_type = T;
566 // parasoft-end-suppress AUTOSAR-A2_10_1-d
567
568 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property,
569 /// @brief Get the maximum number of elements in the vector, @c Capacity
570 static constexpr std::integral_constant<size_type, 0> capacity{};
571 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
572 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property,
573 /// @brief Get the maximum number of elements in the vector, @c Capacity
574 static constexpr std::integral_constant<size_type, 0> max_size{};
575 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
576
577 /// @brief Get an empty span for the current elements
578 /// @return The span
579 static constexpr auto values() noexcept -> span<value_type> { return {}; }
580 /// @brief Do-nothing placeholder for constructing a new element
581 /// @tparam Args The types of the initializers
582 template <typename... Args>
583 static constexpr void internal_emplace_back(Args&&...) noexcept {
584 ARENE_INVARIANT_UNREACHABLE("Can never add to a zero-size container");
585 }
586 /// @brief Do-nothing placeholder for shrinking the size
587 /// @param new_size The new size to shrink to
588 static constexpr void shrink_to(size_type new_size) noexcept { ARENE_PRECONDITION(new_size == 0U); }
589};
590
591template <typename T, std::size_t Capacity, bool NonEmptyConstexpr>
592constexpr std::integral_constant<std::size_t, Capacity>
593 inline_vector_internal_storage<T, Capacity, NonEmptyConstexpr>::capacity;
594
595template <typename T, std::size_t Capacity, bool NonEmptyConstexpr>
596constexpr std::integral_constant<std::size_t, Capacity>
597 inline_vector_internal_storage<T, Capacity, NonEmptyConstexpr>::max_size;
598
599template <typename T, std::size_t Capacity>
600constexpr std::integral_constant<std::size_t, Capacity> inline_vector_internal_storage<T, Capacity, true>::capacity;
601
602template <typename T, std::size_t Capacity>
603constexpr std::integral_constant<std::size_t, Capacity> inline_vector_internal_storage<T, Capacity, true>::max_size;
604
605template <typename T>
606constexpr std::integral_constant<std::size_t, 0> inline_vector_internal_storage<T, 0, false>::capacity;
607
608template <typename T>
609constexpr std::integral_constant<std::size_t, 0> inline_vector_internal_storage<T, 0, false>::max_size;
610
611// parasoft-begin-suppress CERT_CPP-MEM51-c-1 "False Positive: Copy assignment is defined or deleted as appropriate"
612// parasoft-begin-suppress AUTOSAR-M14_5_3-a-2 "False Positive: Copy assignment is defined or deleted as appropriate"
613// parasoft-begin-suppress AUTOSAR-A14_5_1-a-2 "False Positive: Copy constructor is defined or deleted as appropriate"
614// parasoft-begin-suppress AUTOSAR-A1_1_1-c-2 "False Positive: Copy operations are defined or deleted as appropriate"
615// parasoft-begin-suppress AUTOSAR-A1_1_1-b-2 "False Positive: Copy operations are defined or deleted as appropriate"
616// parasoft-begin-suppress AUTOSAR-A12_0_1-a-2 "False Positive: Copy operations are defined or deleted as appropriate"
617// parasoft-begin-suppress AUTOSAR-A10_1_1-a-2 "False positive: 'vector_base' is an interface
618/// @brief Interface to the storage for @c inline_vector
619/// @tparam Storage The class that provides storage for holding the elements
620///
621/// Helper class to define functions necessary for defining a vector.
622///
623/// The @c Storage type is required to provide the following typedefs:
624/// * @c size_type
625/// * @c value_type
626///
627/// The @c Storage type is required to implement the following functions:
628/// * <tt> auto values() const -> span<value_type const> </tt>
629/// * <tt> auto values() -> span<value_type> </tt>
630/// * <tt> void internal_emplace_back(args&&...) </tt>
631/// * <tt> void shrink_to() </tt>
632///
633/// This interface can be constructed as:
634/// * <tt> vector_interface(vector_interface) </tt> (protected)
635/// * <tt> vector_interface() </tt>
636/// * <tt> vector_interface(std::initializer_list) </tt>
637/// * <tt> vector_interface(size_type) </tt>
638/// * <tt> vector_interface(size_type, value_type) </tt>
639/// * <tt> vector_interface(Iterator, Iterator) </tt>
640/// * <tt> vector_interface(move_construction_tag, SourceContainer) </tt>
641///
642/// This interface will provide:
643/// * <tt> auto empty() const -> bool </tt>
644/// * <tt> auto size() const -> size_type </tt>
645/// * <tt> auto back() -> reference </tt>
646/// * <tt> auto back() const -> const_reference </tt>
647/// * <tt> auto front() -> reference </tt>
648/// * <tt> auto front() const -> const_reference </tt>
649/// * <tt> void assign(Iterator, Iterator) </tt>
650/// * <tt> void assign(std::initializer_list) </tt>
651/// * <tt> void assign(size_type, value_type) </tt>
652/// * <tt> void resize(size_type) </tt>
653/// * <tt> void resize(size_type, value_type) </tt>
654/// * <tt> void push_back(value_type) </tt>
655/// * <tt> void emplace_back(Args...) </tt>
656/// * <tt> void clear() </tt>
657/// * <tt> auto data() -> pointer </tt>
658/// * <tt> auto data() const -> const_pointer </tt>
659/// * <tt> auto at(size_type) -> reference </tt>
660/// * <tt> auto at(size_type) const -> const_reference </tt>
661/// * <tt> auto operator[](size_type) -> reference </tt>
662/// * <tt> auto operator[](size_type) const -> const_reference </tt>
663/// * <tt> auto begin() -> iterator </tt>
664/// * <tt> auto begin() const -> const_iterator </tt>
665/// * <tt> auto cbegin() const -> const_iterator </tt>
666/// * <tt> auto end() -> iterator </tt>
667/// * <tt> auto end() const -> const_iterator </tt>
668/// * <tt> auto cend() const -> const_iterator </tt>
669/// * <tt> auto rbegin() -> reverse_iterator </tt>
670/// * <tt> auto rbegin() const -> const_reverse_iterator </tt>
671/// * <tt> auto crbegin() const -> const_reverse_iterator </tt>
672/// * <tt> auto rend() -> reverse_iterator </tt>
673/// * <tt> auto rend() const -> const_reverse_iterator </tt>
674/// * <tt> auto crend() const -> const_iterator </tt>
675/// * <tt> auto insert(const_iterator, value_type) -> iterator </tt>
676/// * <tt> auto insert(const_iterator, size_type, value_type) -> iterator </tt>
677/// * <tt> auto insert(const_iterator, InputIterator, InputIterator) -> iterator </tt>
678/// * <tt> auto erase(const_iterator) -> iterator </tt>
679/// * <tt> auto erase(const_iterator, const_iterator) -> iterator </tt>
680/// * <tt> void pop_back() </tt>
681template <typename Storage>
682// NOLINTNEXTLINE(hicpp-special-member-functions)
683class vector_interface
684 : public vector_base<typename Storage::value_type>
685 , public detail::mixin_at<vector_interface<Storage>, typename vector_base<typename Storage::value_type>::size_type>
686 , protected Storage {
687 /// @brief type alias for the base class with type aliases
688 using vector_base_type = vector_base<typename Storage::value_type>;
689
690 protected:
691 // Alias in typedefs from base class
692 using typename vector_base_type::const_iterator;
693 using typename vector_base_type::const_pointer;
694 using typename vector_base_type::const_reference;
695 using typename vector_base_type::const_reverse_iterator;
696 using typename vector_base_type::difference_type;
697 using typename vector_base_type::iterator;
698 using typename vector_base_type::pointer;
699 using typename vector_base_type::reference;
700 using typename vector_base_type::reverse_iterator;
701 using typename vector_base_type::size_type;
702 using typename vector_base_type::value_type;
703
704 using Storage::capacity;
705
706 /// @brief swaps all the elements between this vector and another.
707 ///
708 /// @param other the vector to swap with.
709 /// @post The elements in @c this and @c other are exchanged 1:1 up to the @c size() of the smallest vector. Relative
710 /// order is maintained. The remaining elements from the originally larger vector are move-constructed into the
711 /// originally smaller vector maintaining relative order, and the elements in the originally larger vector are
712 /// destroyed.
713 ///
714 constexpr void do_swap(vector_interface& other
715 ) noexcept(is_nothrow_swappable_v<value_type> && std::is_nothrow_move_constructible<value_type>::value) {
716 auto our_values = this->values();
717 auto other_values = other.values();
718 auto const swap_count = std::min<>(size(), other.size());
719 for (vector_interface::size_type i{0U}; i < swap_count; ++i) {
720 ::arene::base::swap(our_values[i], other_values[i]);
721 }
722 if (size() < other.size()) {
723 for (vector_interface::size_type i{swap_count}; i < other.size(); ++i) {
724 this->internal_emplace_back(std::move(other_values[i]));
725 }
726 other.shrink_to(swap_count);
727 } else {
728 for (vector_interface::size_type i{swap_count}; i < size(); ++i) {
729 other.internal_emplace_back(std::move(our_values[i]));
730 }
731 this->shrink_to(swap_count);
732 }
733 }
734
735 /// @brief passkey type for constructor to indicate move construction from a source
736 class move_construction_tag {
737 public:
738 /// @brief explicit default constructor to avoid initialization from empty braces
739 explicit move_construction_tag() = default;
740 };
741
742 /// @brief Default copy constructor
743 constexpr vector_interface(vector_interface const&) = default;
744 /// @brief Default move constructor
745 constexpr vector_interface(vector_interface&&) = default;
746
747 /// @brief Default copy assignment operator
748 constexpr auto operator=(vector_interface const&) -> vector_interface& = default;
749 /// @brief Default move assignment operator
750 constexpr auto operator=(vector_interface&&) -> vector_interface& = default;
751
752 public:
753 /// @brief Construct the storage with no elements
754 constexpr vector_interface() noexcept = default;
755
756 /// @brief Default destructor
757 ~vector_interface() = default;
758
759 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
760 // initialize the base class"
761 /// @brief Construct a vector populated with the supplied elements.
762 /// @tparam U Dummy template parameter the same as @c value_type for constraints
763 /// @param initial_values The initial initial_values
764 /// @pre @c initial_values.size()<=capacity(), else @c ARENE_PRECONDITION violation
765 template <
766 typename U = value_type,
767 constraints<
768 std::enable_if_t<std::is_same<U, value_type>::value>,
769 std::enable_if_t<std::is_copy_constructible<U>::value>> = nullptr>
770 constexpr vector_interface(std::initializer_list<value_type> initial_values
771 ) noexcept(std::is_nothrow_copy_constructible<value_type>::value)
772 : vector_interface() {
773 ARENE_PRECONDITION(initial_values.size() <= capacity());
774 // parasoft-begin-suppress AUTOSAR-M14_6_1-a-2 "False Positive: unqualified identifier not used"
775 for (auto& value : initial_values) { // parasoft-suppress AUTOSAR-A7_1_5-a-2 "False Positive: variable is declared
776 // to have same type as initializer"
777 // parasoft-end-suppress AUTOSAR-M14_6_1-a-2
778 this->internal_emplace_back(value);
779 }
780 }
781 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
782
783 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
784 // initialize the base class"
785 /// @brief Construct a vector populated with the specified number of default-constructed elements
786 /// @tparam U Dummy template parameter the same as @c value_type for constraints
787 /// @param count The initial size
788 /// @pre @c count<=capacity(), else @c ARENE_PRECONDITION violation
789 template <
790 typename U = value_type,
791 constraints<
792 std::enable_if_t<std::is_same<U, value_type>::value>,
793 std::enable_if_t<std::is_default_constructible<U>::value>> = nullptr>
794 constexpr explicit vector_interface(vector_interface::size_type const count
795 ) noexcept(std::is_nothrow_default_constructible<value_type>::value)
796 : vector_interface() {
797 ARENE_PRECONDITION(count <= capacity());
798 for (vector_interface::size_type i{count}; i != 0U; --i) {
799 this->internal_emplace_back();
800 }
801 }
802 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
803
804 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
805 // initialize the base class"
806 /// @brief Construct a vector populated with the specified number of
807 /// elements copy-constructed from the supplied value
808 /// @tparam U Dummy template parameter the same as @c value_type for constraints
809 /// @param count The initial size
810 /// @param source The initial value
811 /// @pre @c count<=capacity(), else @c ARENE_PRECONDITION violation
812 template <
813 typename U = value_type,
814 constraints<
815 std::enable_if_t<std::is_same<U, value_type>::value>,
816 std::enable_if_t<std::is_copy_constructible<U>::value>> = nullptr>
817 constexpr explicit vector_interface(vector_interface::size_type const count, value_type const& source) noexcept(
818 std::is_nothrow_copy_constructible<value_type>::value
819 )
820 : vector_interface() {
821 ARENE_PRECONDITION(count <= capacity());
822 for (vector_interface::size_type i{count}; i != 0U; --i) {
823 this->internal_emplace_back(source);
824 }
825 }
826 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
827
828 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
829 // initialize the base class"
830 /// @brief Construct a vector from the elements of an input iterator range
831 /// @tparam Iterator The type of the iterator
832 /// @param first The start of the range
833 /// @param last The end of the range
834 /// @pre The number of elements in the range must be less than @c Capacity, else @c ARENE_PRECONDITION violation
835 template <
836 typename Iterator,
837 constraints<
838 std::enable_if_t<arene::base::is_input_iterator_v<Iterator>>,
839 std::enable_if_t<!arene::base::is_bidirectional_iterator_v<Iterator>>> = nullptr>
840 vector_interface(Iterator first, Iterator last) noexcept(
841 denotes_nothrow_iterable_range_v<Iterator> &&
842 std::is_nothrow_constructible<value_type, typename std::iterator_traits<Iterator>::reference>::value
843 )
844 : vector_interface() {
845 for (auto&& elem : make_subrange(first, last)) {
846 push_back(std::forward<decltype(elem)>(elem));
847 }
848 }
849 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
850 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
851 // initialize the base class"
852 /// @brief Construct a vector from the elements of a bidrectional iterator range
853 /// @tparam Iterator The type of the iterator
854 /// @param first The start of the range
855 /// @param last The end of the range
856 /// @pre The number of elements in the range must be less than @c Capacity, else @c ARENE_PRECONDITION violation
857 template <
858 typename Iterator,
859 constraints<
860 std::enable_if_t<arene::base::is_bidirectional_iterator_v<Iterator>>,
861 std::enable_if_t<
862 std::is_constructible<value_type, typename std::iterator_traits<Iterator>::reference>::value>> = nullptr>
863 constexpr vector_interface(Iterator first, Iterator last) noexcept(
864 denotes_nothrow_iterable_range_v<Iterator> &&
865 std::is_nothrow_constructible<value_type, typename std::iterator_traits<Iterator>::reference>::value
866 )
867 : vector_interface() {
868 auto const source_count = static_cast<size_type>(arene::base::distance(first, last));
869 ARENE_PRECONDITION(source_count <= capacity());
870 for (auto&& elem : make_subrange(first, last)) {
871 this->internal_emplace_back(std::forward<decltype(elem)>(elem));
872 }
873 }
874 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
875
876 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
877 // initialize the base class"
878 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "False positive: Elements are moved"
879 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "False positive: Elements are moved"
880 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "False positive: Elements are moved"
881 /// @brief Move construct from another vector
882 /// @tparam SoureContainer The type of the other vector
883 /// @param other The other vector
884 /// @pre @c other.size()<=Capacity, else @c ARENE_PRECONDITION violation
885 template <typename SourceContainer>
886 constexpr explicit vector_interface(move_construction_tag, SourceContainer&& other) noexcept(
887 std::is_nothrow_move_constructible<value_type>::value
888 )
889 : vector_interface() {
890 ARENE_PRECONDITION(other.size() <= capacity());
891 // parasoft-begin-suppress AUTOSAR-M14_6_1-a-2 "False Positive: unqualified identifier not used"
892 for (auto& elem : other) {
893 // parasoft-end-suppress AUTOSAR-M14_6_1-a-2
894 this->internal_emplace_back(std::move(elem));
895 }
896 }
897 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
898 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
899 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
900 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
901
902 /// @brief Check if the vector is empty.
903 /// @return @c true if the vector is empty, @c false otherwise
904 constexpr auto empty() const noexcept -> bool { return size() == 0U; }
905 /// @brief Get the current number of live elements in the vector
906 /// @return the size
907 constexpr auto size() const noexcept -> size_type { return this->values().size(); }
908
909 /// @brief Get a reference to the last element.
910 /// @return A reference to the element
911 /// @pre The vector must not be empty
912 constexpr auto back() noexcept -> reference { return this->values().back(); }
913 /// @brief Get a reference to the last element.
914 /// @return A reference to the element
915 /// @pre The vector must not be empty
916 constexpr auto back() const noexcept -> const_reference { return this->values().back(); }
917
918 /// @brief Get a reference to the first element.
919 /// @return A reference to the element
920 /// @pre The vector must not be empty
921 constexpr auto front() noexcept -> reference { return this->values().front(); }
922 /// @brief Get a reference to the first element.
923 /// @return A reference to the element
924 /// @pre The vector must not be empty
925 constexpr auto front() const noexcept -> const_reference { return this->values().front(); }
926
927 // parasoft-begin-suppress AUTOSAR-M0_1_8-b "False positive: function assign is not empty"
928 // parasoft-begin-suppress AUTOSAR-A0_1_4-a "False positive: parameters first and last are used"
929 /// @brief Assign to the vector from the elements of an input iterator range. Assigns
930 /// over existing elements, constructs additional elements, and destroys any
931 /// excess.
932 /// @tparam Iterator The type of the iterator
933 /// @param first The start of the range
934 /// @param last The end of the range
935 /// @pre The number of elements in the range must be less than @c Capacity, else @c ARENE_PRECONDITION violation
936 template <
937 typename Iterator,
938 constraints<
939 std::enable_if_t<arene::base::is_input_iterator_v<Iterator>>,
940 std::enable_if_t<!arene::base::is_forward_iterator_v<Iterator>>> = nullptr>
941 constexpr void assign(Iterator first, Iterator last) noexcept(
942 denotes_nothrow_iterable_range_v<Iterator> &&
943 std::is_nothrow_constructible<value_type, typename std::iterator_traits<Iterator>::reference>::value &&
944 std::is_nothrow_assignable<value_type&, typename std::iterator_traits<Iterator>::reference>::value
945 ) {
946 auto our_values = this->values();
947 vector_interface::size_type idx{0U};
948 while ((idx < our_values.size()) && (first != last)) {
949 our_values[idx] = *first++;
950 ++idx;
951 }
952 while (first != last) {
953 push_back(*first++);
954 ++idx;
955 }
956 this->shrink_to(idx);
957 }
958 // parasoft-end-suppress AUTOSAR-A0_1_4-a
959 // parasoft-end-suppress AUTOSAR-M0_1_8-b
960
961 /// @brief Assign to the vector from the elements of a bidrectional iterator range.
962 /// Assigns over existing elements, constructs additional elements, and
963 /// destroys any excess.
964 /// @tparam Iterator The type of the iterator
965 /// @param first The start of the range
966 /// @param last The end of the range
967 /// @pre The number of elements in the range must be less than @c Capacity, else @c ARENE_PRECONDITION violation
968 template <typename Iterator, constraints<std::enable_if_t<arene::base::is_forward_iterator_v<Iterator>>> = nullptr>
969 constexpr void assign(Iterator const first, Iterator const last) noexcept(
970 denotes_nothrow_iterable_range_v<Iterator> &&
971 std::is_nothrow_constructible<value_type, typename std::iterator_traits<Iterator>::reference>::value &&
972 std::is_nothrow_assignable<value_type&, typename std::iterator_traits<Iterator>::reference>::value
973 ) {
974 auto const source_distance = arene::base::distance(first, last);
975 auto const source_size = static_cast<size_type>(source_distance);
976 ARENE_PRECONDITION(source_size <= this->capacity());
977
978 // parasoft-begin-suppress AUTOSAR-M14_6_1-a-2 "False Positive: unqualified identifier not used"
979 Iterator current_source{first};
980 for (auto& elem_to_overwrite : this->values()) {
981 // parasoft-end-suppress AUTOSAR-M14_6_1-a-2
982 if (current_source == last) {
983 break;
984 }
985 elem_to_overwrite = *current_source;
986 // parasoft-begin-suppress AUTOSAR-M5_0_15-a-2 "False positive: current_source is an iterator, bounded by last"
987 ++current_source;
988 // parasoft-end-suppress AUTOSAR-M5_0_15-a-2
989 }
990
991 for (auto&& source_elem : make_subrange(current_source, last)) {
992 this->internal_emplace_back(std::forward<decltype(source_elem)>(source_elem));
993 }
994 this->shrink_to(source_size);
995 }
996
997 /// @brief Assign to the vector from the elements of an initializer list. Assigns
998 /// over existing elements, constructs additional elements, and destroys any
999 /// excess.
1000 /// @param source_values The source values
1001 /// @pre @c source_values.size()<=Capacity, else @c ARENE_PRECONDITION violation
1002 void assign(std::initializer_list<value_type> source_values) noexcept(
1003 std::is_nothrow_copy_constructible<value_type>::value && std::is_nothrow_copy_assignable<value_type>::value
1004 ) {
1005 assign(source_values.begin(), source_values.end());
1006 }
1007
1008 /// @brief Assign to the vector the specified number of copies of a given source
1009 /// element. Assigns over existing elements, constructs additional elements,
1010 /// and destroys any excess.
1011 /// @param count The number of copies to store
1012 /// @param value The source value to use
1013 /// @pre @c count<=Capacity, else @c ARENE_PRECONDITION violation
1014 void assign(size_type count, value_type const& value) noexcept(
1015 std::is_nothrow_copy_constructible<value_type>::value && std::is_nothrow_copy_assignable<value_type>::value
1016 ) {
1017 ARENE_PRECONDITION(count <= this->capacity());
1018 auto our_values = this->values();
1019 for (vector_interface::size_type i{0U}; (i < our_values.size()) && (i < count); ++i) {
1020 our_values[i] = value;
1021 }
1022 resize(count, value);
1023 }
1024
1025 /// @brief Resize the vector to the specified size. Default-constructs any missing
1026 /// elements, and destroys any excess.
1027 /// @param count The desired size
1028 /// @pre @c count<=Capacity, else @c ARENE_PRECONDITION violation
1029 constexpr void resize(size_type count) noexcept(std::is_nothrow_default_constructible<value_type>::value) {
1030 ARENE_PRECONDITION(count <= this->capacity());
1031 while (size() < count) {
1032 this->internal_emplace_back();
1033 }
1034 this->shrink_to(count);
1035 }
1036
1037 /// @brief Resize the vector to the specified size using a supplied value.
1038 /// Copy-constructs any missing elements from the provided value, and destroys
1039 /// any excess.
1040 /// @param count The desired size
1041 /// @param value The source value to use for the new elements
1042 /// @pre @c count<=Capacity, else @c ARENE_PRECONDITION violation
1043 constexpr void resize(size_type count, value_type const& value) noexcept(
1044 std::is_nothrow_copy_constructible<value_type>::value
1045 ) {
1046 ARENE_PRECONDITION(count <= this->capacity());
1047 while (size() < count) {
1048 this->internal_emplace_back(value);
1049 }
1050 this->shrink_to(count);
1051 }
1052
1053 /// @brief Add a new element to the end of the vector as a copy of the supplied
1054 /// value.
1055 /// @param value The value to copy
1056 /// @pre @c size()<Capacity, else @c ARENE_PRECONDITION violation
1057 constexpr void push_back(value_type const& value) noexcept(std::is_nothrow_copy_constructible<value_type>::value) {
1058 ARENE_PRECONDITION(size() < this->capacity());
1059 this->internal_emplace_back(value);
1060 }
1061
1062 /// @brief Add a new element to the end of the vector by move-constructing from the
1063 /// supplied value.
1064 /// @param value The value to move from
1065 /// @pre @c size()<Capacity, else @c ARENE_PRECONDITION violation
1066 constexpr void push_back(value_type&& value) noexcept(std::is_nothrow_move_constructible<value_type>::value) {
1067 ARENE_PRECONDITION(size() < this->capacity());
1068 this->internal_emplace_back(std::move(value));
1069 }
1070
1071 /// @brief Add a new element to the end of the vector, constructed in place from the
1072 /// supplied arguments.
1073 /// @tparam Args The types of the arguments
1074 /// @param args The constructor arguments
1075 /// @return A reference to the new element
1076 /// @pre @c size()<Capacity, else @c ARENE_PRECONDITION violation
1077 template <typename... Args>
1078 constexpr auto emplace_back(Args&&... args) noexcept(std::is_nothrow_constructible<value_type, Args&&...>::value)
1079 -> reference {
1080 ARENE_PRECONDITION(size() < this->capacity());
1081 this->internal_emplace_back(std::forward<Args>(args)...);
1082 return back();
1083 }
1084
1085 /// @brief Destroy all elements and set the size to zero
1086 constexpr void clear() noexcept { this->shrink_to(size_type{}); }
1087
1088 /// @brief Obtain a pointer to the stored elements
1089 /// @return A raw pointer to the elements
1090 constexpr auto data() noexcept -> pointer { return this->values().data(); }
1091
1092 /// @brief Obtain a pointer to the stored elements
1093 /// @return A raw pointer to the elements
1094 constexpr auto data() const noexcept -> const_pointer { return this->values().data(); }
1095
1096 // parasoft-begin-suppress AUTOSAR-A2_10_1-a "False Positive: 'index' does not hide anything"
1097 /// @brief Obtain a reference to the element with the specified index
1098 /// @param index The index of the element
1099 /// @return A reference to the element
1100 /// @pre @c index must be less than @c size()
1101 constexpr auto operator[](size_type index) noexcept -> reference { return this->values()[index]; }
1102
1103 /// @brief Obtain a const reference to the element with the specified index
1104 /// @param index The index of the element
1105 /// @return A reference to the element
1106 /// @pre @c index must be less than @c size()
1107 constexpr auto operator[](size_type index) const noexcept -> const_reference { return this->values()[index]; }
1108 // parasoft-end-suppress AUTOSAR-A2_10_1-a
1109
1110 /// @brief Obtain an iterator to the start of the vector.
1111 /// @return The iterator
1112 constexpr auto begin() noexcept -> iterator {
1113 return {typename vector_base_type::iterator_passkey{}, this->values().begin().base()};
1114 }
1115 /// @brief Obtain an iterator to the end of the vector.
1116 /// @return The iterator
1117 constexpr auto end() noexcept -> iterator {
1118 return {typename vector_base_type::iterator_passkey{}, this->values().end().base()};
1119 }
1120
1121 /// @brief Obtain an iterator to the start of the vector.
1122 /// @return The iterator
1123 constexpr auto begin() const noexcept -> const_iterator { return cbegin(); }
1124 /// @brief Obtain an iterator to the end of the vector.
1125 /// @return The iterator
1126 constexpr auto end() const noexcept -> const_iterator { return cend(); }
1127
1128 /// @brief Obtain an iterator to the start of the vector.
1129 /// @return The iterator
1130 constexpr auto cbegin() const noexcept -> const_iterator {
1131 return {typename vector_base_type::iterator_passkey{}, this->values().cbegin().base()};
1132 }
1133 /// @brief Obtain an iterator to the end of the vector.
1134 /// @return The iterator
1135 constexpr auto cend() const noexcept -> const_iterator {
1136 return {typename vector_base_type::iterator_passkey{}, this->values().cend().base()};
1137 }
1138
1139 /// @brief Obtain an iterator to the end of the vector for iterating in reverse.
1140 /// @return The iterator
1141 constexpr auto rbegin() noexcept -> reverse_iterator { return reverse_iterator(end()); }
1142 /// @brief Obtain an iterator to the start of the vector for iterating in reverse
1143 /// @return The iterator
1144 constexpr auto rend() noexcept -> reverse_iterator { return reverse_iterator(begin()); }
1145
1146 /// @brief Obtain an iterator to the end of the vector for iterating in reverse.
1147 /// @return The iterator
1148 constexpr auto rbegin() const noexcept -> const_reverse_iterator { return crbegin(); }
1149 /// @brief Obtain an iterator to the start of the vector for iterating in reverse
1150 /// @return The iterator
1151 constexpr auto rend() const noexcept -> const_reverse_iterator { return crend(); }
1152
1153 /// @brief Obtain an iterator to the end of the vector for iterating in reverse.
1154 /// @return The iterator
1155 constexpr auto crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(cend()); }
1156 /// @brief Obtain an iterator to the start of the vector for iterating in reverse
1157 /// @return The iterator
1158 constexpr auto crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(cbegin()); }
1159
1160 /// @brief Insert a new element at the specified position in the vector by
1161 /// move-constructing or move-assigning from the supplied value. Any existing
1162 /// elements from the specified position to the end of the vector are moved to
1163 /// make room.
1164 /// @param pos The position to insert the new element
1165 /// @param value The value to move from
1166 /// @return An iterator referring to the new element
1167 /// @pre @c size()<Capacity, else @c ARENE_PRECONDITION violation
1168 constexpr auto insert(const_iterator pos, value_type&& value) noexcept(
1169 std::is_nothrow_move_constructible<value_type>::value && std::is_nothrow_move_assignable<value_type>::value
1170 ) -> iterator {
1171 return internal_insert(pos, 1U, std::move(value));
1172 }
1173 /// @brief Insert a new element at the specified position in the vector by
1174 /// copy-constructing or copy-assigning from the supplied value. Any existing
1175 /// elements from the specified position to the end of the vector are moved to
1176 /// make room.
1177 /// @param pos The position to insert the new element
1178 /// @param value The value to copy from
1179 /// @return An iterator referring to the new element
1180 /// @pre @c size()<Capacity, else @c ARENE_PRECONDITION violation
1181 constexpr auto insert(const_iterator pos, value_type const& value) noexcept(
1182 std::is_nothrow_move_constructible<value_type>::value && std::is_nothrow_move_assignable<value_type>::value &&
1183 std::is_nothrow_copy_constructible<value_type>::value
1184 ) -> iterator {
1185 return internal_insert(pos, 1U, value);
1186 }
1187 /// @brief Insert a specified number of copies of a new element at the specified
1188 /// position in the vector by copy-constructing or copy-assigning from the
1189 /// supplied value. Any existing elements from the specified position to the
1190 /// end of the vector are moved to make room.
1191 /// @param pos The position to insert the new element
1192 /// @param count The number of copies to insert
1193 /// @param value The value to copy from
1194 /// @return An iterator referring to the location of the new elements
1195 /// @pre @c count<=(Capacity-size()), else @c ARENE_PRECONDITION violation
1196 constexpr auto insert(const_iterator pos, size_type count, value_type const& value) noexcept(
1197 std::is_nothrow_move_constructible<value_type>::value && std::is_nothrow_move_assignable<value_type>::value &&
1198 std::is_nothrow_copy_constructible<value_type>::value
1199 ) -> iterator {
1200 return internal_insert(pos, count, value);
1201 }
1202
1203 /// @brief Insert new element at the specified position in the vector by
1204 /// constructing or assigning from the elements in the supplied range. Any
1205 /// existing elements from the specified position to the end of the vector are
1206 /// moved to make room.
1207 /// @param pos The position to insert the new element
1208 /// @param first The start of the range to insert
1209 /// @param last The end of the range to insert
1210 /// @return An iterator referring to the new element
1211 /// @pre The number of elements in the range must be less than or equal to @c Capacity-size(), else @c
1212 /// ARENE_PRECONDITION violation
1213 template <
1214 typename InputIterator,
1215 constraints<std::enable_if_t<arene::base::is_input_iterator_v<InputIterator>>> = nullptr>
1216 constexpr auto insert(const_iterator pos, InputIterator first, InputIterator last) noexcept(
1217 denotes_nothrow_iterable_range_v<InputIterator> && std::is_nothrow_move_constructible<value_type>::value &&
1218 std::is_nothrow_move_assignable<value_type>::value &&
1219 std::is_nothrow_constructible<value_type, typename std::iterator_traits<InputIterator>::reference>::value
1220 ) -> iterator {
1221 return internal_insert(pos, first, last);
1222 }
1223
1224 /// @brief Insert a new element at the specified position in the vector by
1225 /// move-constructing or move-assigning from a new element constructed from
1226 /// the supplied arguments. Any existing elements from the specified position
1227 /// to the end of the vector are moved to make room.
1228 /// @tparam Args The types of the constructor arguments
1229 /// @param pos The position to insert the new element
1230 /// @param args The constructor arguments
1231 /// @return An iterator referring to the new element
1232 /// @pre @c size()<Capacity, else @c ARENE_PRECONDITION violation
1233 template <typename... Args>
1234 constexpr auto emplace(const_iterator pos, Args&&... args) noexcept(
1235 std::is_nothrow_move_constructible<value_type>::value && std::is_nothrow_move_assignable<value_type>::value &&
1236 std::is_nothrow_constructible<value_type, Args&&...>::value
1237 ) -> iterator {
1238 // parasoft-begin-suppress AUTOSAR-A5_2_2-a-2 "False positive: constructor syntax not C-style cast"
1239 return internal_insert(pos, 1U, value_type(std::forward<Args>(args)...));
1240 // parasoft-end-suppress AUTOSAR-A5_2_2-a-2
1241 }
1242
1243 /// @brief Erase the element at the specified position.
1244 /// @param pos An iterator referring to the element to erase
1245 /// @return An iterator referring to the erase location
1246 /// @pre @c pos Must be a valid iterator to a live element in @c this
1247 constexpr auto erase(const_iterator pos) noexcept(std::is_nothrow_move_assignable<value_type>::value) -> iterator {
1248 return erase(pos, pos + 1);
1249 }
1250
1251 /// @brief Erase all the element in the specified range.
1252 /// @param first An iterator referring to the start of the range to erase
1253 /// @param last An iterator referring to the end of the range to erase
1254 /// @pre @c [first,last) Must be a valid iterator range in @c this
1255 /// @return An iterator referring to the erase location
1256 constexpr auto erase(const_iterator first, const_iterator last) noexcept(
1257 std::is_nothrow_move_assignable<value_type>::value
1258 ) -> iterator {
1259 // parasoft-begin-suppress AUTOSAR-M14_6_1-a-2 "False Positive: unqualified identifier not used"
1260 auto count = last - first;
1261 auto ncpos = begin() + (first - begin());
1262 for (auto next = ncpos + count, endpos = end(); next != endpos; ++next) {
1263 *(next - count) = std::move(*next);
1264 }
1265 // parasoft-end-suppress AUTOSAR-M14_6_1-a-2
1266 this->shrink_to(size() - static_cast<size_type>(count));
1267 return ncpos;
1268 }
1269
1270 /// @brief Destroy the last element in the vector and decrease the size
1271 /// @pre The vector must not be empty
1272 constexpr void pop_back() noexcept {
1273 ARENE_PRECONDITION(!empty());
1274 this->shrink_to(size() - size_type{1U});
1275 }
1276
1277 private:
1278 /// @brief Obtain the available free space
1279 /// @return std::size_t holding the available space before the capacity is exhausted
1280 constexpr auto free_space() const noexcept -> std::size_t { return this->capacity() - size(); }
1281
1282 /// @brief Actually do an insert at the specified position, of the specified number
1283 /// of elements from the given source. Existing elements are moved out of the
1284 /// way.
1285 /// @tparam Source The type of the source
1286 /// @param pos The position at which to insert elements
1287 /// @param count The number of elements to insert
1288 /// @param source A class representing the source of the elements
1289 /// @return An iterator to the insert position
1290 /// @pre @c (Capacity-size())<=count, else @c ARENE_PRECONDITION violation
1291 template <typename Source>
1292 constexpr auto internal_do_insert(const_iterator pos, size_type count, Source source) -> iterator {
1293 ARENE_PRECONDITION(free_space() >= count);
1294 auto const insert_offset = pos - begin();
1295 auto ncpos = begin() + insert_offset;
1296 auto const move_count = end() - pos;
1297 auto const insert_count = static_cast<difference_type>(count);
1298 auto const move_construct_count = std::min<>(move_count, insert_count);
1299 auto const insert_construct_count = (insert_count > move_count) ? insert_count - move_count : 0;
1300 // parasoft-begin-suppress AUTOSAR-M3_4_1-a-2 "False positive: Moving this later may affect the value"
1301 // NOLINTNEXTLINE(hicpp-use-auto)
1302 difference_type const original_end_offset{static_cast<difference_type>(size())};
1303 // parasoft-end-suppress AUTOSAR-M3_4_1-a-2
1304
1305 source.reset_index(move_construct_count);
1306 for (vector_interface::difference_type i{0}; i < insert_construct_count; ++i) {
1307 this->internal_emplace_back(source.next());
1308 }
1309 if (move_count != 0) {
1310 auto const move_assign_count = (insert_count > move_count) ? 0 : move_count - insert_count;
1311 auto old_elem = original_end_offset - move_construct_count;
1312 for (vector_interface::difference_type i{0}; i < move_construct_count; ++i) {
1313 this->internal_emplace_back(std::move((*this)[static_cast<size_type>(old_elem)]));
1314 ++old_elem;
1315 }
1316 old_elem = original_end_offset - move_construct_count - 1;
1317 vector_interface::difference_type move_target{original_end_offset - 1};
1318
1319 for (vector_interface::difference_type i{0}; i < move_assign_count; ++i) {
1320 (*this)[static_cast<size_type>(move_target)] = std::move((*this)[static_cast<size_type>(old_elem)]);
1321 --move_target;
1322 --old_elem;
1323 }
1324 auto insert_pos = ncpos;
1325 source.reset_index(0);
1326 for (vector_interface::difference_type i{0}; i < move_construct_count; ++i) {
1327 *insert_pos++ = source.next();
1328 }
1329 }
1330 return ncpos;
1331 }
1332
1333 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "False positive: arg is moved"
1334 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "False positive: arg is moved"
1335 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "False positive: arg is moved"
1336 /// @brief Insert a number of copies of the specified value at the specified
1337 /// position. If @c Arg is an rvalue, moves rather than copies.
1338 /// @tparam Arg The type of the argument.
1339 /// @param pos The position at which to insert the elements
1340 /// @param count The number of elements to insert
1341 /// @param arg The value to insert
1342 /// @return An iterator referring to the insert location
1343 template <typename Arg>
1344 constexpr auto internal_insert(const_iterator pos, size_type count, Arg&& arg) -> iterator {
1345 /// @brief This type holds a reference to the argument, in order to avoid unnecessary copying.
1346 /// The stored reference is then used to construct the inserted value
1347 class fixed_source {
1348 // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members)
1349 Arg& arg_;
1350
1351 public:
1352 constexpr explicit fixed_source(Arg& arg) noexcept
1353 : arg_(arg) {}
1354 constexpr void reset_index(difference_type) noexcept {}
1355 constexpr auto next() const noexcept -> Arg&& { return std::forward<Arg>(arg_); }
1356 };
1357 return internal_do_insert(pos, count, fixed_source{arg});
1358 }
1359 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
1360 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
1361 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
1362
1363 /// @brief Insert elements from a bidirectional iterator range at the specified
1364 /// position.
1365 /// @tparam Iterator The type of the iterator
1366 /// @param pos The position at which to insert the elements
1367 /// @param first The start of the iterator range to insert
1368 /// @param last The end of the iterator range to insert
1369 /// @return An iterator referring to the insert location
1370 template <
1371 typename Iterator,
1372 constraints<std::enable_if_t<arene::base::is_bidirectional_iterator_v<Iterator>>> = nullptr>
1373 constexpr auto internal_insert(const_iterator pos, Iterator first, Iterator last) -> iterator {
1374 auto const insert_count = static_cast<size_type>(arene::base::distance(first, last));
1375 ARENE_PRECONDITION(free_space() >= insert_count);
1376
1377 class iterator_source {
1378 Iterator base_;
1379 Iterator current_;
1380
1381 public:
1382 constexpr explicit iterator_source(Iterator base)
1383 : base_(base),
1384 current_(base) {}
1385
1386 constexpr void reset_index(difference_type index) { current_ = ::arene::base::next(base_, index); }
1387 constexpr auto next() -> decltype(*current_) { return *current_++; }
1388 };
1389 return internal_do_insert(pos, insert_count, iterator_source{first});
1390 }
1391
1392 /// @brief Insert elements from an input iterator range at the specified
1393 /// position.
1394 /// @return An iterator referring to the insert location
1395 /// @tparam Iterator The type of the iterator
1396 /// @param pos The position at which to insert the elements
1397 /// @param first The start of the iterator range to insert
1398 /// @param last The end of the iterator range to insert
1399 template <
1400 typename Iterator,
1401 constraints<
1402 std::enable_if_t<arene::base::is_input_iterator_v<Iterator>>,
1403 std::enable_if_t<!arene::base::is_bidirectional_iterator_v<Iterator>>> = nullptr>
1404 constexpr auto internal_insert(const_iterator pos, Iterator first, Iterator last) -> iterator {
1405 auto ncpos = begin() + (pos - begin());
1406 for (; first != last; ++first) {
1407 internal_insert(pos++, 1, *first);
1408 }
1409 return ncpos;
1410 }
1411};
1412// parasoft-end-suppress AUTOSAR-A10_1_1-a-2
1413// parasoft-end-suppress AUTOSAR-A12_0_1-a-2
1414// parasoft-end-suppress AUTOSAR-A1_1_1-c-2
1415// parasoft-end-suppress AUTOSAR-A1_1_1-b-2
1416// parasoft-end-suppress AUTOSAR-M14_5_3-a-2
1417// parasoft-end-suppress AUTOSAR-A14_5_1-a-2
1418
1419/// @brief Constant that is @c true if a container is an instantiation of @c inline_vector of @c T with any capacity,
1420/// @c false otherwise
1421/// @tparam T The element type
1422/// @tparam Container The container type to check
1423template <typename T, typename Container>
1424constexpr bool is_inline_vector_of_t_v = false;
1425
1426/// @brief Constant that is @c true if a container is an instantiation of @c inline_vector of @c T with any capacity,
1427/// @c false otherwise
1428/// @tparam T The element type
1429/// @tparam Capacity The capacity of the @c inline_vector being checked
1430template <typename T, std::size_t Capacity>
1431constexpr bool is_inline_vector_of_t_v<T, inline_vector<T, Capacity>> = true;
1432
1433} // namespace inline_vector_detail
1434
1435// parasoft-begin-suppress AUTOSAR-A10_1_1-a-2 "False positive: the vector_interface is the only non-empty base class"
1436// parasoft-begin-suppress AUTOSAR-A12_1_5-a "False positive: No work done in constructors to delegate"
1437/// @brief A container similar to @c std::vector<T> that has a fixed capacity. The
1438/// storage for the elements is held directly within the class. Any attempt to
1439/// store more than @c Capacity elements will throw @c std::length_error
1440/// @tparam T The type of each element
1441/// @tparam Capacity The maximum number of elements that can be stored.
1442template <typename T, std::size_t Capacity>
1443class inline_vector
1444 : public inline_vector_detail::vector_interface<inline_vector_detail::inline_vector_internal_storage<T, Capacity>>
1445 , full_ordering_operators_from_less_than_and_equals<inline_vector<T, Capacity>> {
1446 static_assert(std::is_nothrow_destructible<T>::value, "Destructors must not throw");
1447
1448 // parasoft-begin-suppress AUTOSAR-A2_10_1-e "False Positive: This identifier does not hide anything"
1449 /// @brief The type of the interface base class
1450 using interface_base =
1451 inline_vector_detail::vector_interface<inline_vector_detail::inline_vector_internal_storage<T, Capacity>>;
1452 // parasoft-end-suppress AUTOSAR-A2_10_1-e
1453
1454 public:
1455 // Alias in typedefs from base class
1456 using typename interface_base::const_iterator;
1457 using typename interface_base::const_pointer;
1458 using typename interface_base::const_reference;
1459 using typename interface_base::const_reverse_iterator;
1460 using typename interface_base::difference_type;
1461 using typename interface_base::iterator;
1462 using typename interface_base::pointer;
1463 using typename interface_base::reference;
1464 using typename interface_base::reverse_iterator;
1465 using typename interface_base::size_type;
1466 using typename interface_base::value_type;
1467
1468 using interface_base::assign;
1469 using interface_base::back;
1470 using interface_base::begin;
1471 using interface_base::capacity;
1472 using interface_base::cbegin;
1473 using interface_base::cend;
1474 using interface_base::clear;
1475 using interface_base::crbegin;
1476 using interface_base::crend;
1477 using interface_base::data;
1478 using interface_base::emplace_back;
1479 using interface_base::empty;
1480 using interface_base::end;
1481 using interface_base::erase;
1482 using interface_base::front;
1483 using interface_base::insert;
1484 using interface_base::max_size;
1485 using interface_base::push_back;
1486 using interface_base::rbegin;
1487 using interface_base::rend;
1488 using interface_base::resize;
1489 using interface_base::size;
1490 using interface_base::operator[];
1491 using interface_base::interface_base;
1492
1493 /// @brief Construct an empty vector
1494 constexpr inline_vector() = default;
1495
1496 /// @brief Default destructor
1497 ~inline_vector() = default;
1498
1499 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
1500 // initialize the base class"
1501 /// @brief Copy construct from a vector with a different capacity
1502 /// @tparam OtherCapacity The capacity of the other vector
1503 /// @tparam U Dummy template parameter the same as @c T for constraints
1504 /// @param other The other vector
1505 /// @pre @c other.size()<=capacity(), else @c ARENE_PRECONDITION violation
1506 template <
1507 size_type OtherCapacity,
1508 typename U = T,
1509 constraints<
1510 std::enable_if_t<std::is_same<U, T>::value>,
1511 std::enable_if_t<std::is_copy_constructible<U>::value>,
1512 std::enable_if_t<OtherCapacity != Capacity>> = nullptr>
1513 constexpr explicit inline_vector(inline_vector<T, OtherCapacity> const& other
1514 ) noexcept(std::is_nothrow_copy_constructible<T>::value)
1515 : inline_vector(other.begin(), other.end()) {}
1516 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
1517
1518 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
1519 // initialize the base class"
1520 /// @brief Move construct from a vector with a different capacity
1521 /// @tparam OtherCapacity The capacity of the other vector
1522 /// @param other The other vector
1523 /// @pre @c other.size()<=Capacity, else @c ARENE_PRECONDITION violation
1524 template <size_type OtherCapacity, constraints<std::enable_if_t<OtherCapacity != Capacity>> = nullptr>
1525 constexpr explicit inline_vector(inline_vector<T, OtherCapacity>&& other
1526 ) noexcept(std::is_nothrow_move_constructible<T>::value)
1527 : inline_vector(typename interface_base::move_construction_tag{}, std::move(other)) {}
1528 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
1529
1530 /// @brief Default copy constructor
1531 constexpr inline_vector(inline_vector const&) = default;
1532
1533 /// @brief Default move constructor
1534 constexpr inline_vector(inline_vector&&) = default;
1535
1536 /// @brief Default copy assignment
1537 constexpr auto operator=(inline_vector const&) -> inline_vector& = default;
1538
1539 /// @brief Default move assignment
1540 constexpr auto operator=(inline_vector&&) -> inline_vector& = default;
1541
1542 // parasoft-begin-suppress AUTOSAR-A2_10_1-e "False Positive: This identifier does not hide anything"
1543 /// @brief Default construct a vector
1544 /// @return optional<inline_vector> holding the default-constructed vector
1545 static constexpr auto try_construct() noexcept -> optional<inline_vector> { return {in_place}; }
1546 // parasoft-end-suppress AUTOSAR-A2_10_1-e
1547
1548 // parasoft-begin-suppress AUTOSAR-A2_10_1-e "False Positive: This identifier does not hide anything"
1549 // parasoft-begin-suppress AUTOSAR-A13_3_1-a-2 "Constrained via SFINAE, permitted by A13-3-1 Permit #1"
1550 /// @brief Construct a vector initialized with the specified parameters
1551 /// @tparam InitElement The type of the elements in the initializer list with which to initialize the vector
1552 /// @param init_list The initializer list with which to initialize the vector
1553 /// @return optional<inline_vector> holding the vector if the number of elements in the source container is less than
1554 /// or equal to the @c Capacity, otherwise returns an empty optional
1555 template <
1556 typename InitElement,
1557 constraints<std::enable_if_t<std::is_constructible<
1558 inline_vector,
1559 typename std::initializer_list<InitElement>::const_iterator,
1560 typename std::initializer_list<InitElement>::const_iterator>::value>> = nullptr>
1561 static constexpr auto try_construct(std::initializer_list<InitElement> const& init_list) noexcept(
1562 std::is_nothrow_constructible<
1563 inline_vector,
1564 typename std::initializer_list<InitElement>::const_iterator,
1565 typename std::initializer_list<InitElement>::const_iterator>::value
1566 ) -> optional<inline_vector> {
1567 if (init_list.size() > capacity()) {
1568 return {};
1569 }
1570 return {in_place, init_list.begin(), init_list.end()};
1571 }
1572 // parasoft-end-suppress AUTOSAR-A13_3_1-a-2
1573
1574 // parasoft-begin-suppress AUTOSAR-A13_3_1-a-2 "Constrained via SFINAE, permitted by A13-3-1 Permit #1"
1575 /// @brief Construct a vector initialized with the specified paramters
1576 /// @tparam Container The type of the container with which to initialize the vector
1577 /// @param container The container with which to initialize the vector
1578 /// @return optional<inline_vector> holding the vector if the number of elements in the source container is less than
1579 /// or equal to the @c Capacity, otherwise returns an empty optional
1580 template <
1581 typename Container,
1582 constraints<
1583 std::enable_if_t<std::is_constructible<inline_vector, Container const&>::value>,
1584 std::enable_if_t<inline_vector_detail::is_inline_vector_of_t_v<T, Container>>> = nullptr>
1585 static constexpr auto try_construct(Container const& container
1586 ) noexcept(std::is_nothrow_constructible<inline_vector, Container const&>::value) -> optional<inline_vector> {
1587 if (container.size() > capacity()) {
1588 return {};
1589 }
1590 return {in_place, container};
1591 }
1592 // parasoft-end-suppress AUTOSAR-A13_3_1-a-2
1593
1594 /// @brief Construct a vector initialized with the specified paramters
1595 /// @tparam Container The type of the container with which to initialize the vector
1596 /// @param container The container with which to initialize the vector
1597 /// @return optional<inline_vector> holding the vector if the number of elements in the source container is less than
1598 /// or equal to the @c Capacity, otherwise returns an empty optional
1599 template <
1600 typename Container,
1601 constraints<
1602 std::enable_if_t<std::is_constructible<inline_vector, Container&&>::value>,
1603 std::enable_if_t<inline_vector_detail::is_inline_vector_of_t_v<T, Container>>> = nullptr>
1604 static constexpr auto try_construct(Container&& container
1605 ) noexcept(std::is_nothrow_constructible<inline_vector, Container&&>::value) -> optional<inline_vector> {
1606 if (container.size() > capacity()) {
1607 return {};
1608 }
1609 return {in_place, std::forward<Container>(container)};
1610 }
1611
1612 // parasoft-begin-suppress AUTOSAR-A13_3_1-a-2 "Constrained via SFINAE, permitted by A13-3-1 Permit #1"
1613 /// @brief Construct a vector with the specified number of default-constructed elements
1614 /// @tparam U Dummy template parameter the same as @c T for constraints
1615 /// @param count The number of elements to construct in the vector
1616 /// @return optional<inline_vector> holding the vector if the @c count is less than or equal to the @c Capacity,
1617 /// otherwise returns an empty optional
1618 template <
1619 typename U = T,
1620 constraints<
1621 std::enable_if_t<std::is_same<U, T>::value>,
1622 std::enable_if_t<std::is_default_constructible<U>::value>> = nullptr>
1623 static constexpr auto try_construct(size_type count) noexcept(std::is_nothrow_default_constructible<T>::value)
1624 -> optional<inline_vector> {
1625 if (count > capacity()) {
1626 return {};
1627 }
1628 return {in_place, count};
1629 }
1630 // parasoft-end-suppress AUTOSAR-A13_3_1-a-2
1631
1632 /// @brief Construct a vector with the specified number of elements copied from the provided source
1633 /// @tparam U Dummy template parameter the same as @c T for constraints
1634 /// @param count The number of elements to construct in the vector
1635 /// @param source The element to copy
1636 /// @return optional<inline_vector> holding the vector if the @c count is less than or equal to the @c Capacity,
1637 /// otherwise returns an empty optional
1638 template <
1639 typename U = T,
1640 constraints<std::enable_if_t<std::is_same<U, T>::value>, std::enable_if_t<std::is_copy_constructible<U>::value>> =
1641 nullptr>
1642 static constexpr auto try_construct(size_type count, T const& source) noexcept(
1643 std::is_nothrow_copy_constructible<T>::value
1644 ) -> optional<inline_vector> {
1645 if (count > capacity()) {
1646 return {};
1647 }
1648 return {in_place, count, source};
1649 }
1650
1651 /// @brief Construct a vector from a bidrectional iterator range
1652 /// @tparam Iterator The type of the iterator
1653 /// @tparam U Dummy template parameter the same as @c T for constraints
1654 /// @param first The start of the range
1655 /// @param last The end of the range
1656 /// @return optional<inline_vector> holding the resulting vector if the number of elements in the range is less than
1657 /// or equal to @c Capacity, an empty optional otherwise
1658 template <
1659 typename Iterator,
1660 typename U = T,
1661 constraints<
1662 std::enable_if_t<is_bidirectional_iterator_v<Iterator>>,
1663 std::enable_if_t<std::is_same<U, T>::value>,
1664 std::enable_if_t<std::is_constructible<U, typename std::iterator_traits<Iterator>::reference>::value>> =
1665 nullptr>
1666 static constexpr auto try_construct(Iterator first, Iterator last) noexcept(
1667 denotes_nothrow_iterable_range_v<Iterator> &&
1668 std::is_nothrow_constructible<T, typename std::iterator_traits<Iterator>::reference>::value
1669 ) -> optional<inline_vector> {
1670 if (static_cast<size_type>(arene::base::distance(first, last)) > capacity()) {
1671 return {};
1672 }
1673 return {in_place, first, last};
1674 }
1675
1676 /// @brief Construct a vector from an input iterator range
1677 /// @tparam Iterator The type of the iterator
1678 /// @tparam U Dummy template parameter the same as @c T for constraints
1679 /// @param first The start of the range
1680 /// @param last The end of the range
1681 /// @return optional<inline_vector> holding the resulting vector if the number of elements in the range is less than
1682 /// or equal to @c Capacity, an empty optional otherwise
1683 template <
1684 typename Iterator,
1685 typename U = T,
1686 constraints<
1687 std::enable_if_t<is_input_iterator_v<Iterator>>,
1688 std::enable_if_t<!is_bidirectional_iterator_v<Iterator>>,
1689 std::enable_if_t<std::is_same<U, T>::value>,
1690 std::enable_if_t<std::is_constructible<U, typename std::iterator_traits<Iterator>::reference>::value>> =
1691 nullptr>
1692 static constexpr auto try_construct(Iterator first, Iterator last) noexcept(
1693 denotes_nothrow_iterable_range_v<Iterator> &&
1694 std::is_nothrow_constructible<T, typename std::iterator_traits<Iterator>::reference>::value
1695 ) -> optional<inline_vector> {
1696 optional<inline_vector> res{in_place};
1697 for (auto& elem : make_subrange(first, last)) {
1698 if (res->size() == interface_base::capacity()) {
1699 return {};
1700 }
1701 res->internal_emplace_back(elem);
1702 }
1703 return res;
1704 }
1705 // parasoft-end-suppress AUTOSAR-A2_10_1-e
1706
1707 /// @brief Assign to the vector from the elements of an initializer list. Assigns
1708 /// over existing elements, constructs additional elements, and destroys any
1709 /// excess.
1710 /// @param source_values The source values
1711 /// @pre @c source_values.size()<=Capacity, else @c ARENE_PRECONDITION violation
1712 auto operator=(std::initializer_list<T> source_values
1713 ) noexcept(std::is_nothrow_copy_constructible<T>::value && std::is_nothrow_copy_assignable<T>::value)
1714 -> inline_vector& {
1715 this->assign(source_values);
1716 return *this;
1717 }
1718
1719 /// @brief Copy-assign to the vector from the elements of a vector with a different
1720 /// capacity. Assigns over existing elements, constructs additional elements,
1721 /// and destroys any excess.
1722 /// @param other The source vector
1723 /// @pre @c other.size()<=Capacity, else @c ARENE_PRECONDITION violation
1724 template <
1725 typename U = T,
1726 size_type OtherCapacity,
1727 constraints<
1728 std::enable_if_t<OtherCapacity != Capacity>,
1729 std::enable_if_t<std::is_copy_constructible<U>::value>,
1730 std::enable_if_t<std::is_copy_assignable<U>::value>> = nullptr>
1731 auto operator=(inline_vector<U, OtherCapacity> const& other
1732 ) noexcept(std::is_nothrow_copy_constructible<U>::value && std::is_nothrow_copy_assignable<U>::value)
1733 -> inline_vector& {
1734 this->assign(other.begin(), other.end());
1735 return *this;
1736 }
1737
1738 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "False positive: Elements are moved via move_iterator"
1739 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "False positive: Elements are moved via move_iterator"
1740 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "False positive: Elements are moved via move_iterator"
1741 /// @brief Move-assign to the vector from the elements of a vector with a different
1742 /// capacity. Assigns over existing elements, constructs additional elements,
1743 /// and destroys any excess.
1744 /// @param other The source vector
1745 /// @pre @c other.size()<=Capacity, else @c ARENE_PRECONDITION violation
1746 template <size_type OtherCapacity, constraints<std::enable_if_t<OtherCapacity != Capacity>> = nullptr>
1747 auto operator=(inline_vector<T, OtherCapacity>&& other
1748 ) noexcept(std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value)
1749 -> inline_vector& {
1750 this->assign(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()));
1751 return *this;
1752 }
1753 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
1754 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
1755 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
1756
1757 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False Positive: 'swap' does not hide anything"
1758 /// @brief swaps all the elements between this vector and another.
1759 ///
1760 /// @tparam U the type of the elements in the array. Must satisfy @c is_swappable_v .
1761 /// @param other the vector to swap with.
1762 /// @post The elements in @c this and @c other are exchanged 1:1 up to the @c size() of the smallest vector. Relative
1763 /// order is maintained. The remaining elements from the originally larger vector are move-constructed into the
1764 /// originally smaller vector maintaining relative order, and the elements in the originally larger vector are
1765 /// destroyed.
1766 ///
1767 template <typename U = value_type, constraints<std::enable_if_t<is_swappable_v<U>>> = nullptr>
1768 constexpr void swap(inline_vector& other
1769 ) noexcept(is_nothrow_swappable_v<value_type> && std::is_nothrow_move_constructible<value_type>::value) {
1770 this->do_swap(other);
1771 }
1772 // parasoft-end-suppress AUTOSAR-A2_10_1-d
1773
1774 // parasoft-begin-suppress AUTOSAR-A2_7_2-a-2 "False positive: no commented-out code"
1775 // parasoft-begin-suppress AUTOSAR-M3_3_2-a-2 "False positive: inline function used in multiple translation units"
1776 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
1777 /// @brief swaps all the elements between two vectors.
1778 ///
1779 /// @tparam U the type of the elements in the vector. Must satisfy @c is_swappable_v .
1780 /// @param lhs the left hand vector to swap.
1781 /// @param rhs the right hand vector to swap.
1782 /// @post Equivalent to having called @c lhs.swap(rhs);
1783 /// @see inline_vector::swap.
1784 ///
1785 template <typename U = value_type, constraints<std::enable_if_t<is_swappable_v<U>>> = nullptr>
1786 friend constexpr void swap(inline_vector& lhs, inline_vector& rhs) noexcept(noexcept(lhs.swap(rhs))) {
1787 lhs.swap(rhs);
1788 }
1789 // parasoft-end-suppress AUTOSAR-M3_3_2-a-2
1790 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
1791 // parasoft-end-suppress AUTOSAR-A2_7_2-a-2
1792
1793 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "False positive: It is allowed to declare comparison operators as
1794 // friend functions"
1795 // parasoft-begin-suppress AUTOSAR-M3_3_2-a-2 "False positive: inline function used in multiple translation units"
1796 /// @brief Compare two vectors for equality.
1797 ///
1798 /// @tparam U dummy parameter to disable if @c value_type is three-way-comparable
1799 /// @param lhs The first vector
1800 /// @param rhs The second vector
1801 /// @return bool equivalent to @c arene::base::equal(lhs.begin(),lhs.end(),rhs.begin(),rhs.end()) .
1802 template <typename U = value_type, constraints<std::enable_if_t<is_equality_comparable_v<U>>> = nullptr>
1803 friend constexpr auto operator==(inline_vector const& lhs, inline_vector const& rhs) noexcept -> bool {
1804 return ::arene::base::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
1805 }
1806 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
1807 // parasoft-end-suppress AUTOSAR-M3_3_2-a-2
1808
1809 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "False positive: It is allowed to declare comparison operators as
1810 // friend functions"
1811 // parasoft-begin-suppress AUTOSAR-M3_3_2-a-2 "False positive: inline function used in multiple translation units"
1812 /// @brief Compare two vectors for lexicographical ordering.
1813 ///
1814 /// @tparam U dummy parameter to disable if @c value_type is not less-than-comparable
1815 /// @param lhs The first vector
1816 /// @param rhs The second vector
1817 /// @return bool equivalent to @c arene::base::lexicographical_compare(lhs.begin(),lhs.end(),rhs.begin(),rhs.end()) .
1818 template <typename U = value_type, constraints<std::enable_if_t<is_less_than_comparable_v<U>>> = nullptr>
1819 friend constexpr auto operator<(inline_vector const& lhs, inline_vector const& rhs) noexcept -> bool {
1820 return ::arene::base::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
1821 }
1822 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
1823 // parasoft-end-suppress AUTOSAR-M3_3_2-a-2
1824};
1825// parasoft-end-suppress AUTOSAR-A10_1_1-a-2
1826// parasoft-end-suppress AUTOSAR-A12_1_5-a
1827
1828} // namespace base
1829} // namespace arene
1830
1831// parasoft-end-suppress AUTOSAR-M2_10_1-a-2
1832
1833#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_VECTOR_HPP_
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10