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_
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"
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"
66namespace external_vector_detail {
72class try_construct_policy {
77 using size_type = std::size_t;
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);
89 return buffer.size() /
sizeof(value_type);
104 class iterator_passkey {
107 explicit iterator_passkey() =
default;
112 using value_type = T;
114 using size_type = std::size_t;
116 using pointer = value_type*;
118 using const_pointer = value_type
const*;
120 using iterator = detail::wrapped_iterator<pointer, iterator_passkey>;
122 using const_iterator = detail::wrapped_iterator<const_pointer, iterator_passkey>;
124 using difference_type =
typename std::iterator_traits<iterator>::difference_type;
128 using element_type = inline_container::detail::unsafe_element_storage<value_type>;
131 span<element_type> storage_;
142 static auto make_storage_array(span<byte> buffer)
noexcept -> span<element_type> {
143 auto const count = try_construct_policy<T>::capacity_of(buffer);
146 auto*
const start = (count == 0U) ?
nullptr :
new (buffer.data()) element_type[count]{};
148 return {start, count};
159 explicit storage_base(span<byte> buffer)
noexcept
160 : storage_{make_storage_array(buffer)},
165 ~storage_base() { storage_shrink_to(0U); }
168 storage_base(storage_base
const&) =
delete;
170 storage_base(storage_base&&) =
delete;
172 auto operator=(storage_base
const&) -> storage_base& =
delete;
174 auto operator=(storage_base&&) -> storage_base& =
delete;
178 auto storage_values()
noexcept -> span<value_type> {
179 if (storage_capacity() == 0U) {
182 return {&storage_.front().object, size_};
186 auto storage_values()
const noexcept -> span<value_type
const> {
187 if (storage_capacity() == 0U) {
190 return {&storage_.front().object, size_};
196 auto storage_capacity()
const noexcept -> size_type {
return storage_.size(); }
201 auto stored_size()
const noexcept -> size_type {
return size_; }
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());
212 auto& location = storage_[size_];
213 destroy_at(&location.dummy);
214 std::ignore = construct_at(&location.object, std::forward<Args>(args)...);
224 auto storage_shrink_to(std::size_t count)
noexcept ->
void {
225 ARENE_PRECONDITION(count <= size_);
227 for (
auto& location : storage_.subspan(count, size_ - count)) {
228 destroy_at(&location.object);
229 std::ignore = construct_at(&location.dummy);
239 auto swap(storage_base& other)
noexcept ->
void {
240 arene::base::swap(
this->storage_, other.storage_);
241 arene::base::swap(
this->size_, other.size_);
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()));
267template <
typename ValueType>
268class external_storage_base {
271 class storage_access_tag {
274 explicit storage_access_tag() =
default;
283 auto get_storage()
const noexcept -> storage_base<ValueType>
const& {
284 return derived_external_vector::get_storage(storage_access_tag{},
this);
289 auto get_storage()
noexcept -> storage_base<ValueType>& {
290 return derived_external_vector::get_storage(storage_access_tag{},
this);
295 using value_type = ValueType;
297 using size_type = std::size_t;
302 auto capacity()
const noexcept -> size_type {
return get_storage().storage_capacity(); }
305 auto max_size()
const noexcept -> size_type {
return capacity(); }
309 auto values()
noexcept -> span<value_type> {
return get_storage().storage_values(); }
312 auto values()
const noexcept -> span<value_type
const> {
return get_storage().storage_values(); }
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)...);
324 void shrink_to(size_type new_size)
noexcept { get_storage().storage_shrink_to(new_size); }
351 : external_vector_detail::storage_base<T>
359 using storage_base = external_vector_detail::storage_base<T>;
501 while (
count != 0U) {
526 while (
count != 0U) {
670 auto operator=(enable_if_assignable_t<
true, value_type&&> other)
noexcept(
673 this->assign(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()));
709 auto operator=(enable_if_assignable_t<
true, value_type
const&> other)
noexcept(
712 this->assign(other.begin(), other.end());
~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