5#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_VECTOR_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_VECTOR_HPP_
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"
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"
80template <
typename T, std::size_t Capacity>
83namespace inline_vector_detail {
90 class iterator_passkey {
93 constexpr explicit iterator_passkey()
noexcept =
default;
100 using size_type = std::size_t;
102 using value_type = T;
104 using reference = value_type&;
106 using const_reference = value_type
const&;
108 using pointer = value_type*;
110 using const_pointer = value_type
const*;
112 using iterator = ::arene::base::detail::wrapped_iterator<pointer, iterator_passkey>;
114 using const_iterator = ::arene::base::detail::wrapped_iterator<const_pointer, iterator_passkey>;
116 using reverse_iterator = ::arene::base::reverse_iterator<iterator>;
118 using const_reverse_iterator = ::arene::base::reverse_iterator<const_iterator>;
120 using difference_type =
typename iterator::difference_type;
129constexpr bool allow_constexpr_vector_v =
130 std::is_trivially_default_constructible<T>::value && std::is_trivially_move_assignable<T>::value;
136template <
typename T, std::size_t Capacity,
bool = std::is_trivially_destructible<T>::value>
138class inline_vector_internal_non_constexpr_storage {
141 inline_vector_internal_non_constexpr_storage(inline_vector_internal_non_constexpr_storage
const&) =
delete;
143 inline_vector_internal_non_constexpr_storage(inline_vector_internal_non_constexpr_storage&&) =
delete;
146 auto operator=(inline_vector_internal_non_constexpr_storage
const&)
147 -> inline_vector_internal_non_constexpr_storage& =
delete;
149 auto operator=(inline_vector_internal_non_constexpr_storage&&)
150 -> inline_vector_internal_non_constexpr_storage& =
delete;
155 using size_type = std::size_t;
159 using value_type = T;
163 constexpr inline_vector_internal_non_constexpr_storage() =
default;
166 ~inline_vector_internal_non_constexpr_storage() {
168 for (
auto& value : values()) {
176 constexpr auto values()
noexcept -> span<value_type> {
179 return {&values_.front().object, std::min(size_, Capacity)};
184 constexpr auto values()
const noexcept -> span<value_type
const> {
187 return {&values_.front().object, std::min(size_, Capacity)};
192 constexpr void shrink_to(size_type new_size)
noexcept {
193 if (new_size <
this->size_) {
195 for (
auto& value : values().last(size_ - new_size)) {
210 using element_storage = inline_container::detail::unsafe_element_storage<T>;
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");
222 arene::base::array<element_storage, Capacity> values_{};
233template <
typename T, std::size_t Capacity>
235class inline_vector_internal_non_constexpr_storage<T, Capacity,
true> {
239 using size_type = std::size_t;
243 using value_type = T;
248 constexpr auto values()
noexcept -> span<value_type> {
251 return {&values_.front().object, std::min(size_, Capacity)};
256 constexpr auto values()
const noexcept -> span<value_type
const> {
259 return {&values_.front().object, std::min(size_, Capacity)};
264 constexpr void shrink_to(size_type new_size)
noexcept {
265 if (new_size <
this->size_) {
277 using element_storage = inline_container::detail::unsafe_element_storage<T>;
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");
289 arene::base::array<element_storage, Capacity> values_{};
303template <
typename T, std::size_t Capacity,
bool = Capacity != 0 && allow_constexpr_vector_v<T>>
305class inline_vector_internal_storage :
public inline_vector_internal_non_constexpr_storage<T, Capacity> {
307 using non_constexpr_storage_base = inline_vector_internal_non_constexpr_storage<T, Capacity>;
312 using copy_constructor_arg =
313 conditional_t<std::is_copy_constructible<T>::value, inline_vector_internal_storage, non_constructible_dummy>;
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>;
326 using move_constructor_arg =
327 conditional_t<std::is_move_constructible<T>::value, inline_vector_internal_storage, non_constructible_dummy>;
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>;
340 using size_type =
typename non_constexpr_storage_base::size_type;
344 using value_type =
typename non_constexpr_storage_base::value_type;
349 static constexpr std::integral_constant<std::size_t, Capacity> capacity{};
353 static constexpr std::integral_constant<std::size_t, Capacity> max_size{};
357 constexpr inline_vector_internal_storage() =
default;
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);
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));
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];
417 for (; idx < other_values.size(); ++idx) {
418 internal_emplace_back(other_values[idx]);
420 this->shrink_to(idx);
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]);
451 for (; idx < other_values.size(); ++idx) {
452 internal_emplace_back(std::move(other_values[idx]));
454 this->shrink_to(idx);
465 ~inline_vector_internal_storage() =
default;
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)...);
488template <
typename T, std::size_t Capacity>
489class inline_vector_internal_storage<T, Capacity,
true> {
493 using size_type = std::size_t;
497 using value_type = T;
502 static constexpr std::integral_constant<size_type, Capacity> capacity{};
506 static constexpr std::integral_constant<size_type, Capacity> max_size{};
511 constexpr auto values()
noexcept -> span<value_type> {
514 return {&values_.front(), std::min(size_, Capacity)};
518 constexpr auto values()
const noexcept -> span<value_type
const> {
521 return {&values_.front(), std::min(size_, Capacity)};
528 template <
typename... Args>
529 constexpr void internal_emplace_back(Args&&... args)
noexcept(std::is_nothrow_constructible<T, Args...>::value) {
531 values_[size_] = T(std::forward<Args>(args)...);
538 constexpr void shrink_to(size_type new_size)
noexcept {
539 if (new_size < size_) {
549 arene::base::array<value_type, Capacity> values_{};
557class inline_vector_internal_storage<T, 0,
false> {
561 using size_type = std::size_t;
565 using value_type = T;
570 static constexpr std::integral_constant<size_type, 0> capacity{};
574 static constexpr std::integral_constant<size_type, 0> max_size{};
579 static constexpr auto values()
noexcept -> span<value_type> {
return {}; }
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");
588 static constexpr void shrink_to(size_type new_size)
noexcept { ARENE_PRECONDITION(new_size == 0U); }
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;
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;
599template <
typename T, std::size_t Capacity>
600constexpr std::integral_constant<std::size_t, Capacity> inline_vector_internal_storage<T, Capacity,
true>::capacity;
602template <
typename T, std::size_t Capacity>
603constexpr std::integral_constant<std::size_t, Capacity> inline_vector_internal_storage<T, Capacity,
true>::max_size;
606constexpr std::integral_constant<std::size_t, 0> inline_vector_internal_storage<T, 0,
false>::capacity;
609constexpr std::integral_constant<std::size_t, 0> inline_vector_internal_storage<T, 0,
false>::max_size;
681template <
typename Storage>
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 {
688 using vector_base_type = vector_base<
typename Storage::value_type>;
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;
704 using Storage::capacity;
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]);
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]));
726 other.shrink_to(swap_count);
728 for (vector_interface::size_type i{swap_count}; i < size(); ++i) {
729 other.internal_emplace_back(std::move(our_values[i]));
731 this->shrink_to(swap_count);
736 class move_construction_tag {
739 explicit move_construction_tag() =
default;
743 constexpr vector_interface(vector_interface
const&) =
default;
745 constexpr vector_interface(vector_interface&&) =
default;
748 constexpr auto operator=(vector_interface
const&) -> vector_interface& =
default;
750 constexpr auto operator=(vector_interface&&) -> vector_interface& =
default;
754 constexpr vector_interface()
noexcept =
default;
757 ~vector_interface() =
default;
766 typename U = value_type,
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());
775 for (
auto& value : initial_values) {
778 this->internal_emplace_back(value);
790 typename U = value_type,
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();
813 typename U = value_type,
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
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);
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
844 : vector_interface() {
845 for (
auto&& elem : make_subrange(first, last)) {
846 push_back(std::forward<
decltype(elem)>(elem));
860 std::enable_if_t<arene::base::is_bidirectional_iterator_v<Iterator>>,
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
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));
885 template <
typename SourceContainer>
886 constexpr explicit vector_interface(move_construction_tag, SourceContainer&& other)
noexcept(
887 std::is_nothrow_move_constructible<value_type>::value
889 : vector_interface() {
890 ARENE_PRECONDITION(other.size() <= capacity());
892 for (
auto& elem : other) {
894 this->internal_emplace_back(std::move(elem));
904 constexpr auto empty()
const noexcept ->
bool {
return size() == 0U; }
907 constexpr auto size()
const noexcept -> size_type {
return this->values().size(); }
912 constexpr auto back()
noexcept -> reference {
return this->values().back(); }
916 constexpr auto back()
const noexcept -> const_reference {
return this->values().back(); }
921 constexpr auto front()
noexcept -> reference {
return this->values().front(); }
925 constexpr auto front()
const noexcept -> const_reference {
return this->values().front(); }
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
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++;
952 while (first != last) {
956 this->shrink_to(idx);
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
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());
979 Iterator current_source{first};
980 for (
auto& elem_to_overwrite :
this->values()) {
982 if (current_source == last) {
985 elem_to_overwrite = *current_source;
991 for (
auto&& source_elem : make_subrange(current_source, last)) {
992 this->internal_emplace_back(std::forward<
decltype(source_elem)>(source_elem));
994 this->shrink_to(source_size);
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
1005 assign(source_values.begin(), source_values.end());
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
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;
1022 resize(count, value);
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();
1034 this->shrink_to(count);
1043 constexpr void resize(size_type count, value_type
const& value)
noexcept(
1044 std::is_nothrow_copy_constructible<value_type>::value
1046 ARENE_PRECONDITION(count <=
this->capacity());
1047 while (size() < count) {
1048 this->internal_emplace_back(value);
1050 this->shrink_to(count);
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);
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));
1077 template <
typename... Args>
1078 constexpr auto emplace_back(Args&&... args)
noexcept(std::is_nothrow_constructible<value_type, Args&&...>::value)
1080 ARENE_PRECONDITION(size() <
this->capacity());
1081 this->internal_emplace_back(std::forward<Args>(args)...);
1086 constexpr void clear()
noexcept {
this->shrink_to(size_type{}); }
1090 constexpr auto data()
noexcept -> pointer {
return this->values().data(); }
1094 constexpr auto data()
const noexcept -> const_pointer {
return this->values().data(); }
1101 constexpr auto operator[](size_type index)
noexcept -> reference {
return this->values()[index]; }
1107 constexpr auto operator[](size_type index)
const noexcept -> const_reference {
return this->values()[index]; }
1112 constexpr auto begin()
noexcept -> iterator {
1113 return {
typename vector_base_type::iterator_passkey{},
this->values().begin().base()};
1117 constexpr auto end()
noexcept -> iterator {
1118 return {
typename vector_base_type::iterator_passkey{},
this->values().end().base()};
1123 constexpr auto begin()
const noexcept -> const_iterator {
return cbegin(); }
1126 constexpr auto end()
const noexcept -> const_iterator {
return cend(); }
1130 constexpr auto cbegin()
const noexcept -> const_iterator {
1131 return {
typename vector_base_type::iterator_passkey{},
this->values().cbegin().base()};
1135 constexpr auto cend()
const noexcept -> const_iterator {
1136 return {
typename vector_base_type::iterator_passkey{},
this->values().cend().base()};
1141 constexpr auto rbegin()
noexcept -> reverse_iterator {
return reverse_iterator(end()); }
1144 constexpr auto rend()
noexcept -> reverse_iterator {
return reverse_iterator(begin()); }
1148 constexpr auto rbegin()
const noexcept -> const_reverse_iterator {
return crbegin(); }
1151 constexpr auto rend()
const noexcept -> const_reverse_iterator {
return crend(); }
1155 constexpr auto crbegin()
const noexcept -> const_reverse_iterator {
return const_reverse_iterator(cend()); }
1158 constexpr auto crend()
const noexcept -> const_reverse_iterator {
return const_reverse_iterator(cbegin()); }
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
1171 return internal_insert(pos, 1U, std::move(value));
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
1185 return internal_insert(pos, 1U, value);
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
1200 return internal_insert(pos, count, value);
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
1221 return internal_insert(pos, first, last);
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
1239 return internal_insert(pos, 1U, value_type(std::forward<Args>(args)...));
1247 constexpr auto erase(const_iterator pos)
noexcept(std::is_nothrow_move_assignable<value_type>::value) -> iterator {
1248 return erase(pos, pos + 1);
1256 constexpr auto erase(const_iterator first, const_iterator last)
noexcept(
1257 std::is_nothrow_move_assignable<value_type>::value
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);
1266 this->shrink_to(size() -
static_cast<size_type>(count));
1272 constexpr void pop_back()
noexcept {
1273 ARENE_PRECONDITION(!empty());
1274 this->shrink_to(size() - size_type{1U});
1280 constexpr auto free_space()
const noexcept -> std::size_t {
return this->capacity() - size(); }
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;
1302 difference_type
const original_end_offset{
static_cast<difference_type>(size())};
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());
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)]));
1316 old_elem = original_end_offset - move_construct_count - 1;
1317 vector_interface::difference_type move_target{original_end_offset - 1};
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)]);
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();
1343 template <
typename Arg>
1344 constexpr auto internal_insert(const_iterator pos, size_type count, Arg&& arg) -> iterator {
1347 class fixed_source {
1352 constexpr explicit fixed_source(Arg& arg)
noexcept
1354 constexpr void reset_index(difference_type)
noexcept {}
1355 constexpr auto next()
const noexcept -> Arg&& {
return std::forward<Arg>(arg_); }
1357 return internal_do_insert(pos, count, fixed_source{arg});
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);
1377 class iterator_source {
1382 constexpr explicit iterator_source(Iterator base)
1386 constexpr void reset_index(difference_type index) { current_ = ::arene::base::next(base_, index); }
1387 constexpr auto next() ->
decltype(*current_) {
return *current_++; }
1389 return internal_do_insert(pos, insert_count, iterator_source{first});
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);
1423template <
typename T,
typename Container>
1424constexpr bool is_inline_vector_of_t_v =
false;
1430template <
typename T, std::size_t Capacity>
1431constexpr bool is_inline_vector_of_t_v<T, inline_vector<T, Capacity>> =
true;
1442template <
typename T, std::size_t Capacity>
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");
1450 using interface_base =
1451 inline_vector_detail::vector_interface<inline_vector_detail::inline_vector_internal_storage<T, Capacity>>;
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;
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;
1494 constexpr inline_vector() =
default;
1497 ~inline_vector() =
default;
1507 size_type OtherCapacity,
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()) {}
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)) {}
1531 constexpr inline_vector(inline_vector
const&) =
default;
1534 constexpr inline_vector(inline_vector&&) =
default;
1537 constexpr auto operator=(inline_vector
const&) -> inline_vector& =
default;
1540 constexpr auto operator=(inline_vector&&) -> inline_vector& =
default;
1545 static constexpr auto try_construct()
noexcept -> optional<inline_vector> {
return {in_place}; }
1556 typename InitElement,
1557 constraints<std::enable_if_t<std::is_constructible<
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<
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()) {
1570 return {in_place, init_list.begin(), init_list.end()};
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()) {
1590 return {in_place, container};
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()) {
1609 return {in_place, std::forward<Container>(container)};
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()) {
1628 return {in_place, count};
1640 constraints<std::enable_if_t<std::is_same<U, T>::value>, std::enable_if_t<std::is_copy_constructible<U>::value>> =
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()) {
1648 return {in_place, count, source};
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>> =
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()) {
1673 return {in_place, first, last};
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>> =
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()) {
1701 res->internal_emplace_back(elem);
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)
1715 this->assign(source_values);
1726 size_type OtherCapacity,
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)
1734 this->assign(other.begin(), other.end());
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)
1750 this->assign(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()));
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);
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))) {
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());
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());
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10