Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
external_vector.hpp
Go to the documentation of this file.
1// Copyright 2026, 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_EXTERNAL_VECTOR_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_EXTERNAL_VECTOR_HPP_
7
8// parasoft-begin-suppress AUTOSAR-A16_2_2-a "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
9#include "arene/base/byte/byte.hpp"
10#include "arene/base/constraints/constraints.hpp"
11#include "arene/base/contracts/contract.hpp"
12#include "arene/base/detail/wrapped_iterator.hpp" // IWYU pragma: keep
13#include "arene/base/inline_container/detail/comparison_interface.hpp"
14#include "arene/base/inline_container/detail/try_construct_interface.hpp"
15#include "arene/base/inline_container/detail/unsafe_element_storage.hpp"
16#include "arene/base/inline_container/vector.hpp"
17#include "arene/base/iterator/advance.hpp"
18#include "arene/base/memory/construct_at.hpp"
19#include "arene/base/memory/destroy_at.hpp"
20#include "arene/base/span/span.hpp"
21#include "arene/base/stdlib_choice/cstddef.hpp"
22#include "arene/base/stdlib_choice/declval.hpp"
23#include "arene/base/stdlib_choice/enable_if.hpp"
24#include "arene/base/stdlib_choice/forward.hpp"
25#include "arene/base/stdlib_choice/ignore.hpp"
26#include "arene/base/stdlib_choice/initializer_list.hpp"
27#include "arene/base/stdlib_choice/is_assignable.hpp"
28#include "arene/base/stdlib_choice/is_constructible.hpp"
29#include "arene/base/stdlib_choice/is_copy_assignable.hpp"
30#include "arene/base/stdlib_choice/is_copy_constructible.hpp"
31#include "arene/base/stdlib_choice/is_default_constructible.hpp"
32#include "arene/base/stdlib_choice/is_move_assignable.hpp"
33#include "arene/base/stdlib_choice/is_move_constructible.hpp"
34#include "arene/base/stdlib_choice/iterator_traits.hpp"
35#include "arene/base/stdlib_choice/move_iterator.hpp"
36#include "arene/base/type_manipulation/non_constructible_dummy.hpp"
37#include "arene/base/type_traits/conditional.hpp"
38#include "arene/base/type_traits/denotes_range.hpp"
39#include "arene/base/type_traits/iterator_category_traits.hpp"
40#include "arene/base/utility/alignment.hpp"
41#include "arene/base/utility/forward_like.hpp"
42#include "arene/base/utility/swap.hpp"
43
44// parasoft-end-suppress AUTOSAR-A16_2_2-a
45
46// parasoft-begin-suppress AUTOSAR-A7_1_5-a "Trailing return syntax permitted by A7-1-5 Permit #1 v1.0.0"
47// parasoft-begin-suppress AUTOSAR-M2_10_1-a "Similar names permitted by M2-10-1 Permit #1"
48// parasoft-begin-suppress CERT_C-EXP37-a "False positive: The rule does not mention naming all parameters"
49// parasoft-begin-suppress AUTOSAR-A1_1_1-b-2 "False positive: This is all conforming code"
50
51namespace arene {
52namespace base {
53
54/// @brief a container similar to @c std::vector<T> that uses an external buffer
55/// for storage
56/// @tparam T value type of the container
57///
58/// A container where storage for the values is provided as a buffer, which is
59/// external to the class. The lifetime of the external buffer must bound the
60/// lifetime of @c external_vector (i.e. the external buffer must outlive the
61/// @c external_vector that uses it).
62///
63template <typename T>
64class external_vector;
65
66namespace external_vector_detail {
67
68/// @brief @c try_construct_policy for @c external_vector
69/// @tparam T container value type
70///
71template <class T>
72class try_construct_policy {
73 public:
74 /// @brief value type stored by the @c external_vector
75 using value_type = T;
76 /// @brief size type of the @c external_vector
77 using size_type = std::size_t;
78
79 /// @brief obtain the value capacity of a byte buffer
80 /// @param buffer external buffer of bytes
81 /// @pre the alignment of @c buffer matches the alignment of @c value_type
82 /// @pre the size of @c buffer is an exact multiple of @c sizeof(value_type)
83 /// @return number of values that can be placed in @c buffer
84 ///
85 static auto capacity_of(span<byte> buffer) noexcept -> size_type {
86 ARENE_PRECONDITION(is_aligned<alignof(value_type)>(buffer.data()));
87 ARENE_PRECONDITION((buffer.size() % sizeof(value_type)) == 0U);
88
89 return buffer.size() / sizeof(value_type);
90 }
91};
92
93/// @brief storage base class for @c external_vector
94/// @tparam T value type of the @c external_vector
95///
96/// Handles element construction and destruction for an @c external_vector into
97/// an externally provided buffer. This class provides a minimal interface to
98/// the underlying storage; @c vector_interface provides the bulk of
99/// "vector"-type functionality for @c external_vector.
100///
101template <class T>
102class storage_base {
103 /// @brief tag type used to protect construction of iterators
104 class iterator_passkey {
105 public:
106 /// @brief default constructor
107 explicit iterator_passkey() = default;
108 };
109
110 public:
111 /// @brief value type stored by this class
112 using value_type = T;
113 /// @brief size type
114 using size_type = std::size_t;
115 /// @brief type of a pointer to a stored value
116 using pointer = value_type*;
117 /// @brief type of a const pointer to a stored value
118 using const_pointer = value_type const*;
119 /// @brief iterator type
120 using iterator = detail::wrapped_iterator<pointer, iterator_passkey>;
121 /// @brief const iterator type
122 using const_iterator = detail::wrapped_iterator<const_pointer, iterator_passkey>;
123 /// @brief difference type
124 using difference_type = typename std::iterator_traits<iterator>::difference_type;
125
126 private:
127 /// @brief underlying element type that allows a value to exist or not exist
128 using element_type = inline_container::detail::unsafe_element_storage<value_type>;
129
130 /// @brief view to external storage
131 span<element_type> storage_;
132 /// @brief number of active values
133 size_type size_;
134
135 /// @brief convert a span of bytes into a span of elements
136 /// @param buffer external buffer of bytes
137 ///
138 /// Starts the lifetime of elements in the external buffer of bytes.
139 ///
140 /// @return span of elements
141 ///
142 static auto make_storage_array(span<byte> buffer) noexcept -> span<element_type> {
143 auto const count = try_construct_policy<T>::capacity_of(buffer);
144
145 // NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
146 auto* const start = (count == 0U) ? nullptr : new (buffer.data()) element_type[count]{};
147
148 return {start, count};
149 }
150
151 public:
152 /// @brief construct an empty @c storage_base
153 /// @param buffer external buffer of bytes
154 /// @post <tt> size() == 0 </tt>
155 ///
156 /// Initializes a @c storage_base to enable storage of @c value_type values in
157 /// @c buffer.
158 ///
159 explicit storage_base(span<byte> buffer) noexcept
160 : storage_{make_storage_array(buffer)},
161 size_{0U} {}
162
163 /// @brief destroy values stored in the external buffer
164 ///
165 ~storage_base() { storage_shrink_to(0U); }
166
167 /// @brief copying is managed externally from this type
168 storage_base(storage_base const&) = delete;
169 /// @brief moving is managed externally from this type
170 storage_base(storage_base&&) = delete;
171 /// @brief copying is managed externally from this type
172 auto operator=(storage_base const&) -> storage_base& = delete;
173 /// @brief moving is managed externally from this type
174 auto operator=(storage_base&&) -> storage_base& = delete;
175
176 /// @brief Obtain a span over the stored values
177 /// @return A @c span<value_type> for the initialized values
178 auto storage_values() noexcept -> span<value_type> {
179 if (storage_capacity() == 0U) {
180 return {};
181 }
182 return {&storage_.front().object, size_};
183 }
184 /// @brief Obtain a @c const span over the stored values
185 /// @return A <c>span<const value_type></c> for the initialized values
186 auto storage_values() const noexcept -> span<value_type const> {
187 if (storage_capacity() == 0U) {
188 return {};
189 }
190 return {&storage_.front().object, size_};
191 }
192
193 /// @brief obtain the number of values that can be stored
194 /// @return number of values that can be stored
195 ///
196 auto storage_capacity() const noexcept -> size_type { return storage_.size(); }
197
198 /// @brief obtain the number of values active in storage
199 /// @return number of values active in storage
200 ///
201 auto stored_size() const noexcept -> size_type { return size_; }
202
203 /// @brief append a value to the end, constructed in place from the
204 /// supplied arguments
205 /// @tparam Args argument types
206 /// @param args constructor arguments
207 /// @pre <tt> size() < capacity() </tt>
208 template <class... Args, constraints<std::enable_if_t<std::is_constructible<value_type, Args...>::value>> = nullptr>
209 void storage_emplace_back(Args&&... args) noexcept(std::is_nothrow_constructible<value_type, Args...>::value) {
210 ARENE_PRECONDITION(size_ < storage_capacity());
211
212 auto& location = storage_[size_];
213 destroy_at(&location.dummy);
214 std::ignore = construct_at(&location.object, std::forward<Args>(args)...);
215
216 ++size_;
217 }
218
219 /// @brief reduce size, removing values at the back
220 /// @param count target number of values
221 /// @pre <tt> count <= size() </tt>
222 /// @post <tt> size() == count </tt>
223 ///
224 auto storage_shrink_to(std::size_t count) noexcept -> void {
225 ARENE_PRECONDITION(count <= size_);
226
227 for (auto& location : storage_.subspan(count, size_ - count)) {
228 destroy_at(&location.object);
229 std::ignore = construct_at(&location.dummy);
230 }
231
232 size_ = count;
233 }
234
235 /// @brief swap contents with a different @c storage_base
236 /// @param other @c storage_base to swap contents with
237 /// @note does not swap individual elements but rather the underlying buffer
238 ///
239 auto swap(storage_base& other) noexcept -> void {
240 arene::base::swap(this->storage_, other.storage_);
241 arene::base::swap(this->size_, other.size_);
242 }
243
244 /// @brief check that buffer is not already used by this storage
245 /// @param buffer buffer to check against
246 ///
247 /// Some of the external_vector constructors have the precondition that there is no aliasing, but there is not a
248 /// portable way to check for aliasing in C++ today. This function performs a best-effort check that the data pointer
249 /// of the given buffer is not equal to the storage's data pointer, intended to help catch the case of a pointer/span
250 /// being accidentally reused.
251 ///
252 /// If a more expansive check is required, it will need to be platform-dependent and should be implemented in the
253 /// compiler_support package.
254 ///
255 /// @pre @c buffer.data() != storage_.data()
256 /// @return @c buffer
257 ///
258 auto verify_not_already_in_use(span<byte> buffer) const noexcept -> span<byte> {
259 ARENE_PRECONDITION(static_cast<void*>(buffer.data()) != static_cast<void*>(storage_.data()));
260 return buffer;
261 }
262};
263
264/// @brief Base class for @c vector_interface that redirects via the @c storage_base base class of the derived class to
265/// access the external storage
266/// @tparam ValueType The type of the value stored in the container
267template <typename ValueType>
268class external_storage_base {
269 protected:
270 /// @brief Passkey to allow access to the storage
271 class storage_access_tag {
272 public:
273 /// @brief Explicit default constructor to require named initialization
274 explicit storage_access_tag() = default;
275 };
276
277 private:
278 /// @brief The type of the derived class
279 using derived_external_vector = external_vector<ValueType>;
280
281 /// @brief Get the storage from the derived @c external_vector
282 /// @return A reference to the storage class
283 auto get_storage() const noexcept -> storage_base<ValueType> const& {
284 return derived_external_vector::get_storage(storage_access_tag{}, this);
285 }
286
287 /// @brief Get the storage from the derived @c external_vector
288 /// @return A reference to the storage class
289 auto get_storage() noexcept -> storage_base<ValueType>& {
290 return derived_external_vector::get_storage(storage_access_tag{}, this);
291 }
292
293 public:
294 /// @brief The type of the stored values
295 using value_type = ValueType;
296 /// @brief The type used for sizes of the vector
297 using size_type = std::size_t;
298
299 protected:
300 /// @brief Get the maximum number of items that can be stored in this vector
301 /// @return The maximum number of items that can be stored in this vector
302 auto capacity() const noexcept -> size_type { return get_storage().storage_capacity(); }
303 /// @brief Get the maximum number of items that can be stored in this vector
304 /// @return The maximum number of items that can be stored in this vector
305 auto max_size() const noexcept -> size_type { return capacity(); }
306
307 /// @brief Get a @c span for the initialized values in the vector
308 /// @return A @c span for the initialized values in the vector
309 auto values() noexcept -> span<value_type> { return get_storage().storage_values(); }
310 /// @brief Get a @c span for the initialized values in the vector
311 /// @return A @c span for the initialized values in the vector
312 auto values() const noexcept -> span<value_type const> { return get_storage().storage_values(); }
313
314 /// @brief Construct a new element at the end of the existing range, from the supplied arguments.
315 /// @tparam Args The types of the arguments
316 /// @param args The constructor arguments
317 template <typename... Args>
318 void internal_emplace_back(Args&&... args) noexcept(std::is_nothrow_constructible<ValueType, Args...>::value) {
319 get_storage().storage_emplace_back(std::forward<Args>(args)...);
320 }
321
322 /// @brief If the current size is more than @c new_size, reduce the size to @c new_size.
323 /// @param new_size The new size limit
324 void shrink_to(size_type new_size) noexcept { get_storage().storage_shrink_to(new_size); }
325};
326
327} // namespace external_vector_detail
328
329// parasoft-begin-suppress AUTOSAR-A10_1_1-a "False positive: Only inherits from a single non-interface base classes"
330// parasoft-begin-suppress AUTOSAR-M14_5_3-a "False positive: Copy assignment is defined or deleted as appropriate"
331// parasoft-begin-suppress AUTOSAR-A12_1_6-a "False positive: storage_base called as appropriate"
332
333// parasoft-begin-suppress AUTOSAR-A7_3_1-a "'storage_base::swap' is not part
334// of the public interface and is not hidden. 'storage_base' is a private base.
335
336// parasoft-begin-suppress AUTOSAR-A10_2_1-b "'storage_base::swap' is not part
337// of the public interface and is not hidden. 'storage_base' is a private base.
338
339/// @brief a container similar to @c std::vector<T> that uses an external buffer
340/// for storage
341/// @tparam T value type of the container
342///
343/// A container where storage for the values is provided as a buffer, which is
344/// external to the class. The lifetime of the external buffer must bound the
345/// lifetime of @c external_vector (i.e. the external buffer must outlive the
346/// @c external_vector that uses it).
347///
348template <class T>
349// NOLINTNEXTLINE(hicpp-special-member-functions) : false positive
351 : external_vector_detail::storage_base<T>
358 /// @brief storage base type
359 using storage_base = external_vector_detail::storage_base<T>;
360
361 /// @brief The type of the interface base class
363
364 /// @brief comparison base type
366
367 /// @brief try_construct interface base type
372
373 /// @brief helper that provides a type to use in defining move or copy assignment
374 /// @tparam Enable @c true if defining the actual move/copy assignment
375 /// operator, @c false for the deleted overload
376 /// @tparam U qualified value type, <tt> T const & </tt> for copy assignment,
377 /// <tt> T&& </tt> for move assignment
378 /// @tparam Pred defaulted parameter that determines the result type
379 ///
380 /// Trait used when defining move or copy assignment operators.
381 ///
382 /// If @c Enable is @c true and the value type is copy/move
383 /// constructible and assignable, the result is @c external_vector.
384 /// If @c Enable is @c true and the value type is *not* copy/move
385 /// constructible and assignable, the result is @c non_constructible_dummy.
386 ///
387 /// If @c Enable is @c false and the value type is copy/move
388 /// constructible and assignable, the result is @c non_constructible_dummy.
389 /// If @c Enable is @c false and the value type is *not* copy/move
390 /// constructible and assignable, the result is @c external_vector.
391 ///
392 /// @note The result type has the reference and qualifiers properties of @c U.
393 ///
394 template <bool Enable, class U, bool Pred = std::is_constructible<T, U>::value && std::is_assignable<T&, U>::value>
395 using enable_if_assignable_t = decltype(arene::base::forward_like<U>( //
397 Enable,
400 ));
401
402 public:
403 // Alias in typedefs from base class
404 using typename interface_base::const_iterator;
405 using typename interface_base::const_pointer;
406 using typename interface_base::const_reference;
408 using typename interface_base::difference_type;
409 using typename interface_base::iterator;
410 using typename interface_base::pointer;
411 using typename interface_base::reference;
412 using typename interface_base::reverse_iterator;
413 using typename interface_base::size_type;
414 using typename interface_base::value_type;
415
416 using interface_base::assign;
419
420 /// @brief default destructor
421 ///
422 /// Detroys values stored in the external buffer.
423 ///
424 ~external_vector() = default;
425
426 /// @brief construct an empty @c external_vector
427 /// @param buffer external buffer of bytes
428 /// @pre the alignment of @c buffer matches the alignment of @c value_type
429 /// @pre the size of @c buffer is an exact multiple of @c sizeof(value_type)
430 /// @post <tt> size() == 0 </tt>
431 /// @post <tt> capacity() == buffer.size() / sizeof(value_type) </tt>
432 ///
433 /// Constructs an empty @c external_vector that is configured to use @c buffer
434 /// as external storage.
435 ///
436 explicit external_vector(span<byte> buffer) noexcept
439 comparison_base{this},
441
442 // parasoft-begin-suppress AUTOSAR-A12_1_1-a "False positive: All these constructors delegate to another, which does
443 // initialize the base class"
444
445 /// @brief construct an empty @c external_vector
446 /// @post <tt> size() == 0 </tt>
447 /// @post <tt> capacity() == 0 </tt>
448 ///
449 /// Constructs an empty @c external_vector without initializing any external
450 /// storage.
451 ///
453 : external_vector{span<byte>{}} {}
454
455 /// @brief construct an @c external_vector from a range
456 /// @tparam I input iterator type
457 /// @param buffer external buffer of bytes
458 /// @param first beginning of the range of values
459 /// @param last end of the range of values
460 /// @pre the alignment of @c buffer matches the alignment of @c value_type
461 /// @pre the size of @c buffer is an exact multiple of @c sizeof(value_type)
462 /// @pre <tt> std::distance(first, last) </tt> does not exceed the number of
463 /// values that can be stored in @c buffer
464 ///
465 /// Constructs an @c external_vector from range <tt> [first, last) </tt>.
466 ///
467 template <
468 class I,
472 nullptr>
476 )
478 // this is likely to be replaced with 'vector_interface'
479 while (first != last) {
480 std::ignore = this->emplace_back(*first);
482 }
483 }
484
485 /// @brief construct an @c external_vector with default constructed values
486 /// @tparam U dummy used to constrain this constructor to value types that are
487 /// default constructible
488 /// @param buffer external buffer of bytes
489 /// @param count size of the @c external_vector
490 /// @pre the alignment of @c buffer matches the alignment of @c value_type
491 /// @pre the size of @c buffer is an exact multiple of @c sizeof(value_type)
492 /// @pre @c count does not exceed the number of values that can be stored in
493 /// @c buffer
494 ///
495 /// Constructs an @c external_vector containing @c count number of default
496 /// constructed values.
497 ///
498 template <class U = value_type, constraints<std::enable_if_t<std::is_default_constructible<U>::value>> = nullptr>
506
507 /// @brief construct an @c external_vector with copies of a value
508 /// @tparam U dummy used to constrain this constructor to value types that are
509 /// copy constructible
510 /// @param buffer external buffer of bytes
511 /// @param count size of the @c external_vector
512 /// @param value value to copy into the @c external_vector
513 /// @pre the alignment of @c buffer matches the alignment of @c value_type
514 /// @pre the size of @c buffer is an exact multiple of @c sizeof(value_type)
515 /// @pre @c count does not exceed the number of values that can be stored in
516 /// @c buffer
517 ///
518 /// Constructs an @c external_vector containing @c count number of copies of
519 /// @c value.
520 ///
521 template <class U = value_type, constraints<std::enable_if_t<std::is_copy_constructible<U>::value>> = nullptr>
524 )
526 while (count != 0U) {
527 std::ignore = this->emplace_back(value);
528 --count;
529 }
530 }
531
532 // parasoft-begin-suppress AUTOSAR-A8_4_6-a "False positive: contents of 'other' are moved via use of 'move_iterator'"
533 // parasoft-begin-suppress AUTOSAR-A8_4_5-a "False positive: contents of 'other' are moved via use of 'move_iterator'"
534 // parasoft-begin-suppress AUTOSAR-A12_8_4-a "False positive: contents of 'other' are moved via use of
535 // 'move_iterator'"
536
537 /// @brief construct an @c external_vector from another @c external_vector
538 /// @tparam U dummy used to constrain this constructor to value types that are
539 /// move constructible
540 /// @param buffer external buffer of bytes
541 /// @param other another @c external_vector
542 /// @pre the alignment of @c buffer matches the alignment of @c value_type
543 /// @pre the size of @c buffer is an exact multiple of @c sizeof(value_type)
544 /// @pre @c other.size() does not exceed the number of values that can be
545 /// stored in @c buffer
546 /// @pre @c buffer does not alias with the buffer managed by @c other
547 ///
548 /// Constructs an @c external_vector from @c other, moving values from the
549 /// external buffer managed by @c other to @c buffer.
550 ///
551 /// @post @c other is in a valid but unspecified state
552 ///
553 template <class U = value_type, constraints<std::enable_if_t<std::is_move_constructible<U>::value>> = nullptr>
562
563 // parasoft-end-suppress AUTOSAR-A8_4_6-a
564 // parasoft-end-suppress AUTOSAR-A8_4_5-a
565 // parasoft-end-suppress AUTOSAR-A12_8_4-a
566
567 /// @brief construct an @c external_vector from another @c external_vector
568 /// @tparam U dummy used to constrain this constructor to value types that are
569 /// copy constructible
570 /// @param buffer external buffer of bytes
571 /// @param other another @c external_vector
572 /// @pre the alignment of @c buffer matches the alignment of @c value_type
573 /// @pre the size of @c buffer is an exact multiple of @c sizeof(value_type)
574 /// @pre @c other.size() does not exceed the number of values that can be
575 /// stored in @c buffer
576 /// @pre @c buffer does not alias with the buffer managed by @c other
577 ///
578 /// Constructs an @c external_vector from @c other, copying values from the
579 /// external buffer managed by @c other to @c buffer.
580 ///
581 /// @post <tt> std::equal(this->begin(), this->end(), other.begin(), other.end()) </tt> is @c true
582 ///
583 template <class U = value_type, constraints<std::enable_if_t<std::is_copy_constructible<U>::value>> = nullptr>
588
589 /// @brief construct an @c external_vector from a list of values
590 /// @tparam U dummy used to constrain this constructor to value types that are
591 /// copy constructible
592 /// @param buffer external buffer of bytes
593 /// @param init_list values to copy
594 /// @pre the alignment of @c buffer matches the alignment of @c value_type
595 /// @pre the size of @c buffer is an exact multiple of @c sizeof(value_type)
596 /// @pre @c init_list.size() does not exceed the number of values that can be
597 /// stored in @c buffer
598 ///
599 /// Constructs an @c external_vector with copies of values in @c init_list.
600 ///
601 template <class U = value_type, constraints<std::enable_if_t<std::is_copy_constructible<U>::value>> = nullptr>
606
607 // parasoft-begin-suppress AUTOSAR-A8_4_6-a "The contents of 'other' are semantically moved via use of
608 // 'move_iterator'" parasoft-begin-suppress AUTOSAR-A8_4_5-a "The contents of 'other' are semantically moved via use
609 // of 'move_iterator'" parasoft-begin-suppress AUTOSAR-A12_8_4-a "The contents of 'other' are semantically moved via
610 // use of 'move_iterator'"
611
612 // parasoft-begin-suppress AUTOSAR-A8_4_6-a "The contents of 'other' are semantically moved via swap"
613 // parasoft-begin-suppress AUTOSAR-A8_4_5-a "The contents of 'other' are semantically moved via swap"
614 // parasoft-begin-suppress AUTOSAR-A12_8_4-a "The contents of 'other' are semantically moved via swap"
615
616 /// @brief construct an @c external_vector from another @c external_vector
617 /// @param other @c external_vector to move from
618 ///
619 /// Constructs an @c external_vector by moving contents from @c other. This
620 /// does not invoke any constructors of @c value_type.
621 ///
622 /// @post @c other is in a valid but unspecified state
623 ///
628
629 // parasoft-end-suppress AUTOSAR-A8_4_6-a
630 // parasoft-end-suppress AUTOSAR-A8_4_5-a
631 // parasoft-end-suppress AUTOSAR-A12_8_4-a
632
633 /// @brief deleted copy constructor
635
636 // parasoft-end-suppress AUTOSAR-A12_1_1-a
637
638 /// @brief deleted move assignment operator
639 /// @note The argument type resolves to @c external_vector&& if
640 /// <tt> std::is_move_constructible<value_type>::value && std::is_move_assignable<value_type>::value </tt>
641 /// is @c false
642 /// @note The move assignment operator is deleted if
643 /// <tt> std::is_move_constructible<value_type>::value && std::is_move_assignable<value_type>::value </tt>
644 /// is @c false
645 ///
647
648 // parasoft-begin-suppress AUTOSAR-A8_4_6-a "The contents of 'other' are semantically moved via make_move_iterator"
649 // parasoft-begin-suppress AUTOSAR-A8_4_5-a "The contents of 'other' are semantically moved via make_move_iterator"
650 // parasoft-begin-suppress AUTOSAR-A12_8_4-a "The contents of 'other' are semantically moved via make_move_iterator"
651
652 /// @brief move assignment operator
653 /// @param other @c external_vector to move values from
654 /// @return @c *this
655 ///
656 /// Replaces the contents of the container with values from @c other. The
657 /// first <tt> std::min(size(), other.size()) </tt> values are move assigned;
658 /// remaining values are move constructed.
659 ///
660 /// @pre <tt> capacity() <= other.size() </tt>
661 /// @post @c other is in a valid but unspecified state
662 ///
663 /// @note The argument type resolves to @c external_vector&& if
664 /// <tt> std::is_move_constructible<value_type>::value && std::is_move_assignable<value_type>::value </tt>
665 /// is @c true
666 /// @note This assignment operator is deleted if
667 /// <tt> std::is_move_constructible<value_type>::value && std::is_move_assignable<value_type>::value </tt>
668 /// is @c false
669 ///
670 auto operator=(enable_if_assignable_t<true, value_type&&> other) noexcept(
672 ) -> external_vector& {
673 this->assign(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()));
674 return *this;
675 }
676
677 // parasoft-end-suppress AUTOSAR-A8_4_6-a
678 // parasoft-end-suppress AUTOSAR-A8_4_5-a
679 // parasoft-end-suppress AUTOSAR-A12_8_4-a
680
681 /// @brief deleted copy assignment operator
682 /// @note The argument type resolves to <tt> external_vector const& </tt> if
683 /// <tt> std::is_copy_constructible<value_type>::value && std::is_copy_assignable<value_type>::value </tt>
684 /// is @c false
685 /// @note The copy assignment operator is deleted if
686 /// <tt> std::is_copy_constructible<value_type>::value && std::is_copy_assignable<value_type>::value </tt>
687 /// is @c false
688 ///
689 auto operator=(enable_if_assignable_t<false, value_type const&>) -> external_vector& = delete;
690
691 /// @brief copy assignment operator
692 /// @param other @c external_vector to copy values from
693 /// @return @c *this
694 ///
695 /// Replaces the contents of the container with values from @c other. The
696 /// first <tt> std::min(size(), other.size()) </tt> values are copy assigned;
697 /// remaining values are copy constructed.
698 ///
699 /// @pre <tt> capacity() <= other.size() </tt>
700 /// @post <tt> std::equal(this->begin(), this->end(), other.begin(), other.end()) </tt> is @c true
701 ///
702 /// @note The argument type resolves to <tt> external_vector const& </tt> if
703 /// <tt> std::is_copy_constructible<value_type>::value && std::is_copy_assignable<value_type>::value </tt>
704 /// is @c true
705 /// @note This assignment operator is deleted if
706 /// <tt> std::is_copy_constructible<value_type>::value && std::is_copy_assignable<value_type>::value </tt>
707 /// is @c false
708 ///
709 auto operator=(enable_if_assignable_t<true, value_type const&> other) noexcept(
711 ) -> external_vector& {
712 this->assign(other.begin(), other.end());
713 return *this;
714 }
715
716 /// @brief assignment from a list of values
717 /// @tparam U dummy used to constrain this assignment operator to value types
718 /// that are copy constructible and copy assignable
719 /// @param init_list values to copy
720 /// @return @c *this
721 ///
722 /// Replaces the contents of the container with values from @c other. The
723 /// first <tt> std::min(size(), other.size()) </tt> values are copy assigned;
724 /// remaining values are copy constructed.
725 ///
726 /// @pre <tt> capacity() <= other.size() </tt>
727 /// @post <tt> std::equal(this->begin(), this->end(), other.begin(), other.end()) </tt> is @c true
728 ///
729 template <
730 class U = value_type,
732 nullptr>
735 ) -> external_vector& {
736 // GCC8 constraint failure without instantiating the trait here
737 // parasoft-begin-suppress CERT_C-PRE31-c "False positive: static_assert is
738 // a compile-time assert and can have no side-effects"
739 static_assert(is_random_access_iterator_v<decltype(init_list.begin())>, "");
740 // parasoft-end-suppress CERT_C-PRE31-c
741 this->assign(init_list.begin(), init_list.end());
742 return *this;
743 }
744
745 /// @brief swap contents with a different @c external_vector
746 /// @param other @c external_vector to swap contents with
747 /// @note does not swap individual elements but rather the underlying buffer
748 /// associated with each @c external_vector
749 ///
750 auto swap(external_vector& other) noexcept -> void { storage_base::swap(other); }
751
752 // parasoft-begin-suppress AUTOSAR-A7_1_1-a "Declaring 'lhs' or 'rhs' as reference to const changes semantics"
753 // parasoft-begin-suppress AUTOSAR-M7_1_2-c "Declaring 'lhs' or 'rhs' as reference to const changes semantics"
754 // parasoft-begin-suppress AUTOSAR-A8_4_9-a "Declaring 'lhs' or 'rhs' as reference to const changes semantics"
755 // parasoft-begin-suppress AUTOSAR-A11_3_1-a "Hidden friends permitted by A11-3-1 Permit #2"
756 // parasoft-begin-suppress AUTOSAR-A0_1_3-a "False positive: 'swap' is namespace scope and used in other
757 // translation units"
758
759 // parasoft-begin-suppress AUTOSAR-A2_7_2-a "False positive: no commented-out code, this is documentation"
760 /// @brief swaps all the elements between two @c external_vector values
761 /// @param lhs the left hand vector to swap
762 /// @param rhs the right hand vector to swap
763 /// @post equivalent to having called @c lhs.swap(rhs);
764 /// @see external_vector::swap.
765 ///
766 // parasoft-end-suppress AUTOSAR-A2_7_2-a
767 friend auto swap(external_vector& lhs, external_vector& rhs) noexcept -> void { lhs.swap(rhs); }
768
769 // parasoft-end-suppress AUTOSAR-A7_1_1-a
770 // parasoft-end-suppress AUTOSAR-M7_1_2-c
771 // parasoft-end-suppress AUTOSAR-A8_4_9-a
772 // parasoft-end-suppress AUTOSAR-A11_3_1-a
773 // parasoft-end-suppress AUTOSAR-A0_1_3-a
774
775 /// @brief Internal function to get access to the storage for an @c external_vector
776 /// @param self The pointer to the internal base class
777 /// @return A reference to the storage class
778 static auto get_storage(
781 ) noexcept -> storage_base const& {
782 return *static_cast<storage_base const*>(static_cast<external_vector const*>(self));
783 }
784
785 /// @brief Internal function to get access to the storage for an @c external_vector
786 /// @param self The pointer to the internal base class
787 /// @return A reference to the storage class
788 static auto get_storage(
791 ) noexcept -> storage_base& {
792 return *static_cast<storage_base*>(static_cast<external_vector*>(self));
793 }
794};
795// parasoft-end-suppress AUTOSAR-A10_1_1-a
796// parasoft-end-suppress AUTOSAR-M14_5_3-a
797// parasoft-end-suppress AUTOSAR-A7_3_1-a
798// parasoft-end-suppress AUTOSAR-A10_2_1-b
799// parasoft-end-suppress AUTOSAR-A12_1_6-a
800
801} // namespace base
802} // namespace arene
803#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_EXTERNAL_VECTOR_HPP_
~external_vector()=default
default destructor
auto operator=(enable_if_assignable_t< false, value_type && >) -> external_vector &=delete
deleted move assignment operator
external_vector(span< byte > buffer) noexcept
construct an empty external_vector
Definition external_vector.hpp:436
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10