35 #ifndef ABSL_CONTAINER_INLINED_VECTOR_H_ 36 #define ABSL_CONTAINER_INLINED_VECTOR_H_ 43 #include <initializer_list> 46 #include <type_traits> 67 template <
typename T,
size_t N,
typename A = std::allocator<T>>
70 N > 0,
"InlinedVector cannot be instantiated with `0` inlined elements.");
75 template <
typename Iterator>
79 template <
typename Iterator>
138 template <
typename ForwardIterator,
148 template <
typename InputIterator,
153 std::copy(first, last, std::back_inserter(*
this));
193 if (other.storage_.GetIsAllocated()) {
199 other.storage_.SetInlinedSize(0);
202 std::make_move_iterator(other.storage_.GetInlinedData()),
203 std::make_move_iterator(other.storage_.GetInlinedData() +
226 if (other.storage_.GetIsAllocated()) {
232 other.storage_.SetInlinedSize(0);
237 std::make_move_iterator(other.end()),
243 std::make_move_iterator(other.storage_.GetInlinedData()),
244 std::make_move_iterator(other.storage_.GetInlinedData() +
274 return (std::numeric_limits<size_type>::max)() / 2;
331 "`InlinedVector::at(size_type)` failed bounds check");
341 "`InlinedVector::at(size_type) const` failed bounds check");
451 assign(list.begin(), list.end());
460 assign(other_data, other_data + other.
size());
473 if (other.storage_.GetIsAllocated()) {
478 other.storage_.SetInlinedSize(0);
482 if (
size() < other.size()) {
483 auto mid = std::make_move_iterator(other.begin() +
size());
484 std::copy(std::make_move_iterator(other.begin()), mid,
begin());
487 auto new_end = std::copy(std::make_move_iterator(other.begin()),
488 std::make_move_iterator(other.end()),
begin());
501 std::fill_n(
begin(), n, v);
522 void assign(std::initializer_list<value_type> list) {
523 assign(list.begin(), list.end());
528 template <
typename ForwardIterator,
529 EnableIfAtLeastForwardIterator<ForwardIterator>* =
nullptr>
530 void assign(ForwardIterator first, ForwardIterator last) {
531 auto length = std::distance(first, last);
534 if (static_cast<size_type>(
length) <=
size()) {
541 for (; out !=
end(); ++first, ++
out) *out = *first;
553 template <
typename InputIterator,
554 DisableIfAtLeastForwardIterator<InputIterator>* =
nullptr>
555 void assign(InputIterator first, InputIterator last) {
557 for (; (assign_index <
size()) && (first != last);
558 static_cast<void>(++assign_index), static_cast<void>(++first)) {
559 *(
data() + assign_index) = *first;
562 std::copy(first, last, std::back_inserter(*
this));
640 return insert(pos, list.begin(), list.end());
649 template <
typename ForwardIterator,
650 EnableIfAtLeastForwardIterator<ForwardIterator>* =
nullptr>
652 ForwardIterator last) {
659 template <
typename InputIterator,
660 DisableIfAtLeastForwardIterator<InputIterator>* =
nullptr>
663 for (
size_type insert_index = initial_insert_index; first != last;
664 static_cast<void>(++insert_index), static_cast<void>(++first)) {
674 template <
typename... Args>
676 assert(pos >=
begin());
677 assert(pos <=
end());
683 T new_t = T(std::forward<Args>(args)...);
686 if (range.first == range.second) {
701 template <
typename... Args>
715 return Construct(space + s, std::forward<Args>(args)...);
753 assert(pos >=
begin());
767 assert(
begin() <= from);
775 ptrdiff_t erase_gap = std::distance(range_start, range_end);
785 std::move(range_end, space + s, range_start);
786 Destroy(space + s - erase_gap, space + s);
836 const auto s =
size();
845 assign(std::make_move_iterator(temp.begin()),
846 std::make_move_iterator(temp.end()));
870 template <
typename H,
typename TheT,
size_t TheN,
typename TheA>
891 template <
typename... Args>
898 template <
typename Iterator>
900 for (; src != src_last; ++dst, ++src)
Construct(dst, *src);
903 template <
typename... Args>
905 for (; dst != dst_last; ++dst)
Construct(dst, args...);
910 for (
pointer cur = from; cur !=
to; ++cur) {
920 std::memset(reinterpret_cast<void*>(from), 0xab,
len);
922 #endif // !defined(NDEBUG) 932 size_type target = (std::max)(static_cast<size_type>(N), s + delta);
937 while (new_capacity < target) {
945 std::make_move_iterator(
data() + s), new_data);
968 while (new_capacity < required_size) {
977 std::make_move_iterator(
data() + index), new_data);
979 std::make_move_iterator(
data() + s),
980 new_data + index + n);
985 start_raw =
begin() + index;
986 start_used = start_raw;
993 size_type slots_in_used_space = raw_space - pos;
994 size_type new_elements_in_used_space = (std::min)(n, slots_in_used_space);
995 size_type new_elements_in_raw_space = n - new_elements_in_used_space;
997 slots_in_used_space - new_elements_in_used_space;
1000 std::make_move_iterator(pos + old_elements_in_used_space),
1001 std::make_move_iterator(raw_space),
1002 raw_space + new_elements_in_raw_space);
1003 std::move_backward(pos, pos + old_elements_in_used_space, raw_space);
1010 start_raw = pos + new_elements_in_used_space;
1013 return std::make_pair(start_used, start_raw);
1016 template <
typename... Args>
1026 Construct(new_data + s, std::forward<Args>(args)...);
1028 std::make_move_iterator(
data() + s), new_data);
1036 if (n > static_cast<size_type>(N)) {
1051 if (n > static_cast<size_type>(N)) {
1065 template <
typename ForwardIt>
1071 auto length = std::distance(first, last);
1084 assert(position >=
begin() && position <=
end());
1088 std::pair<iterator, iterator> it_pair =
ShiftRight(position, n);
1089 std::fill(it_pair.first, it_pair.second, copy);
1092 return it_pair.first;
1095 template <
typename ForwardIt>
1101 assert(position >=
begin() && position <=
end());
1104 return const_cast<iterator>(position);
1106 auto n = std::distance(first, last);
1107 std::pair<iterator, iterator> it_pair =
ShiftRight(position, n);
1108 size_type used_spots = it_pair.second - it_pair.first;
1109 auto open_spot =
std::next(first, used_spots);
1110 std::copy(first, open_spot, it_pair.first);
1112 return it_pair.first;
1121 if (is_allocated && other_is_allocated) {
1130 if (!is_allocated && !other_is_allocated) {
1140 assert(a_size >= b_size);
1157 assert(b->
size() == a_size);
1158 assert(a->
size() == b_size);
1179 static_cast<void>(b_size);
1201 assert(b->
size() == a_size);
1202 assert(a->
size() == b_size);
1216 template <
typename T,
size_t N,
typename A>
1225 template <
typename T,
size_t N,
typename A>
1228 auto a_data = a.
data();
1229 auto a_size = a.
size();
1230 auto b_data = b.
data();
1231 auto b_size = b.
size();
1232 return absl::equal(a_data, a_data + a_size, b_data, b_data + b_size);
1238 template <
typename T,
size_t N,
typename A>
1248 template <
typename T,
size_t N,
typename A>
1249 bool operator<(const absl::InlinedVector<T, N, A>&
a,
1251 auto a_data = a.data();
1252 auto a_size = a.size();
1253 auto b_data =
b.data();
1254 auto b_size =
b.size();
1255 return std::lexicographical_compare(a_data, a_data + a_size, b_data,
1263 template <
typename T,
size_t N,
typename A>
1273 template <
typename T,
size_t N,
typename A>
1274 bool operator<=(const absl::InlinedVector<T, N, A>&
a,
1283 template <
typename T,
size_t N,
typename A>
1293 template <
typename H,
typename TheT,
size_t TheN,
typename TheA>
1295 auto a_data = a.
data();
1296 auto a_size = a.
size();
1297 return H::combine(H::combine_contiguous(
std::move(h), a_data, a_size),
1303 #endif // ABSL_CONTAINER_INLINED_VECTOR_H_
void Destroy(pointer from, pointer to)
void UninitializedFill(pointer dst, pointer dst_last, const Args &... args)
InlinedVector() noexcept(noexcept(allocator_type()))
const_iterator cend() const noexcept
const_reverse_iterator rend() const noexcept
void UninitializedCopy(Iterator src, Iterator src_last, pointer dst)
const_reverse_iterator crend() const noexcept
void SetInlinedSize(size_type size)
size_type max_size() const noexcept
InlinedVector(std::initializer_list< value_type > list, const allocator_type &alloc=allocator_type())
typename Storage::reference reference
void EnlargeBy(size_type delta)
typename allocator_type::size_type size_type
iterator insert(const_iterator pos, std::initializer_list< value_type > list)
iterator insert(const_iterator pos, size_type n, const_reference v)
InlinedVector & operator=(InlinedVector &&other)
typename Storage::allocator_type allocator_type
std::reverse_iterator< const_iterator > const_reverse_iterator
typename allocator_type::value_type && rvalue_reference
size_type GetSize() const
typename allocator_type::const_reference const_reference
iterator insert(const_iterator pos, InputIterator first, InputIterator last)
typename Storage::const_iterator const_iterator
typename allocator_type::value_type value_type
iterator insert(const_iterator pos, ForwardIterator first, ForwardIterator last)
pointer GetAllocatedData()
typename allocator_type::reference reference
void ThrowStdOutOfRange(const std::string &what_arg)
void InitAssign(size_type n, const_reference v)
typename Storage::AllocatorTraits AllocatorTraits
bool GetIsAllocated() const
InlinedVector(const InlinedVector &other, const allocator_type &alloc)
#define ABSL_PREDICT_FALSE(x)
reference operator[](size_type i)
std::allocator_traits< allocator_type > AllocatorTraits
typename Storage::reverse_iterator reverse_iterator
void assign(InputIterator first, InputIterator last)
reference GrowAndEmplaceBack(Args &&... args)
InlinedVector & operator=(const InlinedVector &other)
const_reverse_iterator rbegin() const noexcept
InlinedVector(InlinedVector &&other) noexcept(absl::allocator_is_nothrow< allocator_type >::value||std::is_nothrow_move_constructible< value_type >::value)
typename Storage::const_reverse_iterator const_reverse_iterator
typename Storage::const_reference const_reference
friend H AbslHashValue(H h, const absl::InlinedVector< TheT, TheN, TheA > &a)
void SwapSizeAndIsAllocated(Storage *other)
iterator InsertWithCount(const_iterator position, size_type n, const_reference v)
const_pointer const_iterator
reference at(size_type i)
void assign(ForwardIterator first, ForwardIterator last)
void reserve(size_type n)
void ResetAllocation(pointer new_data, size_type new_capacity, size_type new_size)
reference emplace_back(Args &&... args)
InlinedVector(const InlinedVector &other)
bool operator>(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
void AppendForwardRange(ForwardIt first, ForwardIt last)
typename std::enable_if< B, T >::type enable_if_t
const_reference at(size_type i) const
InlinedVector(ForwardIterator first, ForwardIterator last, const allocator_type &alloc=allocator_type())
static std::function< void(void *, Slot *)> destroy
std::reverse_iterator< iterator > reverse_iterator
iterator insert(const_iterator pos, const_reference v)
InlinedVector(InputIterator first, InputIterator last, const allocator_type &alloc=allocator_type())
InlinedVector(size_type n, const_reference v, const allocator_type &alloc=allocator_type())
typename Storage::value_type value_type
allocator_type get_allocator() const
bool operator==(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
const_pointer data() const noexcept
AllocList * next[kMaxLevel]
iterator erase(const_iterator from, const_iterator to)
void SwapAllocatedSizeAndCapacity(Storage *other)
bool operator>=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::forward_iterator_tag > IsAtLeastForwardIterator
std::pair< iterator, iterator > ShiftRight(const_iterator position, size_type n)
typename Storage::size_type size_type
void swap(InlinedVector &other)
bool operator!=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
allocator_type * GetAllocPtr()
size_type capacity() const noexcept
reverse_iterator rbegin() noexcept
bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, Pred &&pred)
const_reference back() const
size_type size() const noexcept
InlinedVector(size_type n, const allocator_type &alloc=allocator_type())
const_reference operator[](size_type i) const
void SetAllocatedSize(size_type size)
void swap(absl::InlinedVector< T, N, A > &a, absl::InlinedVector< T, N, A > &b) noexcept(noexcept(a.swap(b)))
void AddSize(size_type count)
static std::function< void(void *, Slot *, Slot)> construct
typename allocator_type::pointer pointer
void InitAssign(size_type n)
void SetAllocatedCapacity(size_type capacity)
typename Storage::difference_type difference_type
void DestroyElements(AllocatorType *alloc_ptr, ValueType *destroy_first, SizeType destroy_size)
size_type GetAllocatedCapacity() const
InlinedVector(InlinedVector &&other, const allocator_type &alloc) noexcept(absl::allocator_is_nothrow< allocator_type >::value)
typename allocator_type::difference_type difference_type
void assign(size_type n, const_reference v)
void SwapImpl(InlinedVector &other)
typename allocator_type::const_pointer const_pointer
typename Storage::pointer pointer
typename Storage::iterator iterator
#define ABSL_PREDICT_TRUE(x)
void resize(size_type n, const_reference v)
const_iterator end() const noexcept
const_reverse_iterator crbegin() const noexcept
InlinedVector & operator=(std::initializer_list< value_type > list)
void assign(std::initializer_list< value_type > list)
void SetAllocatedData(pointer data)
absl::enable_if_t< !inlined_vector_internal::IsAtLeastForwardIterator< Iterator >::value > DisableIfAtLeastForwardIterator
InlinedVector(const allocator_type &alloc) noexcept
iterator InsertWithForwardRange(const_iterator position, ForwardIt first, ForwardIt last)
typename Storage::rvalue_reference rvalue_reference
absl::enable_if_t< inlined_vector_internal::IsAtLeastForwardIterator< Iterator >::value > EnableIfAtLeastForwardIterator
iterator insert(const_iterator pos, rvalue_reference v)
iterator emplace(const_iterator pos, Args &&... args)
reference Construct(pointer p, Args &&... args)
const_iterator cbegin() const noexcept
std::allocator< int > alloc
void push_back(rvalue_reference v)
iterator begin() noexcept
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
bool empty() const noexcept
typename Storage::const_pointer const_pointer
const_reference front() const
const_iterator begin() const noexcept
reverse_iterator rend() noexcept
void push_back(const_reference v)
iterator erase(const_iterator pos)