15 #ifndef ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
16 #define ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
25 #include <type_traits>
28 #include "absl/base/attributes.h"
29 #include "absl/base/macros.h"
30 #include "absl/container/internal/compressed_tuple.h"
31 #include "absl/memory/memory.h"
32 #include "absl/meta/type_traits.h"
33 #include "absl/types/span.h"
37 namespace inlined_vector_internal {
40 #if !defined(__clang__) && defined(__GNUC__)
41 #pragma GCC diagnostic push
42 #pragma GCC diagnostic ignored "-Warray-bounds"
74 template <
typename Iterator>
76 typename std::iterator_traits<Iterator>::iterator_category,
77 std::forward_iterator_tag>;
96 template <
typename A,
bool IsTriviallyDestructible =
100 template <
typename A>
111 template <
typename A>
115 static_cast<void>(allocator);
116 static_cast<void>(destroy_first);
117 static_cast<void>(destroy_size);
121 template <
typename A>
127 template <
typename A,
142 template <
typename A,
typename ValueAdapter>
155 template <
typename A,
typename ValueAdapter>
159 values.AssignNext(assign_first +
i);
163 template <
typename A>
170 template <
typename A,
typename Iterator>
189 template <
typename A>
204 template <
typename A>
216 template <
typename A>
261 template <
typename A>
281 template <
typename ValueAdapter>
297 template <
typename T,
size_t N,
typename A>
301 return current_capacity * 2;
382 template <
typename ValueAdapter>
385 template <
typename ValueAdapter>
388 template <
typename ValueAdapter>
391 template <
typename ValueAdapter>
395 template <
typename...
Args>
476 template <
typename...
Args>
483 template <
typename T,
size_t N,
typename A>
485 Pointer<A> data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData();
487 DeallocateIfAllocated();
490 template <
typename T,
size_t N,
typename A>
497 dst = GetInlinedData();
503 SizeType<A> requested_capacity = ComputeCapacity(GetInlinedCapacity(),
n);
506 SetAllocation(allocation);
512 reinterpret_cast<const char*
>(src),
n *
sizeof(
ValueType<A>));
515 ConstructElements<A>(GetAllocator(),
dst,
values,
n);
520 template <
typename T,
size_t N,
typename A>
521 template <
typename ValueAdapter>
529 if (
new_size > GetInlinedCapacity()) {
534 ComputeCapacity(GetInlinedCapacity(),
new_size);
537 construct_data = allocation.
data;
538 SetAllocation(allocation);
541 construct_data = GetInlinedData();
544 ConstructElements<A>(GetAllocator(), construct_data,
values,
new_size);
552 template <
typename T,
size_t N,
typename A>
553 template <
typename ValueAdapter>
568 destroy_loop = {storage_view.
data, storage_view.
size};
570 assign_loop = {storage_view.
data, storage_view.
size};
571 construct_loop = {storage_view.
data + storage_view.
size,
578 AssignElements<A>(assign_loop.
data(),
values, assign_loop.
size());
580 ConstructElements<A>(GetAllocator(), construct_loop.
data(),
values,
581 construct_loop.
size());
584 destroy_loop.
size());
587 DeallocateIfAllocated();
588 SetAllocation(
std::move(allocation_tx).Release());
595 template <
typename T,
size_t N,
typename A>
596 template <
typename ValueAdapter>
602 A&
alloc = GetAllocator();
627 ConstructElements<A>(
alloc, new_data, move_values,
size);
631 DeallocateIfAllocated();
632 SetAllocation(
std::move(allocation_tx).Release());
638 template <
typename T,
size_t N,
typename A>
639 template <
typename ValueAdapter>
646 SizeType<A> insert_end_index = insert_index + insert_count;
661 construction_tx.
Construct(new_data + insert_index,
values, insert_count);
663 move_construction_tx.
Construct(new_data, move_values, insert_index);
665 ConstructElements<A>(GetAllocator(), new_data + insert_end_index,
666 move_values, storage_view.
size - insert_index);
672 std::move(move_construction_tx).Commit();
673 DeallocateIfAllocated();
674 SetAllocation(
std::move(allocation_tx).Release());
686 (move_construction_destination_index - insert_count)));
688 storage_view.
data + move_construction_destination_index,
689 new_size - move_construction_destination_index};
691 Pointer<A> move_assignment_values = storage_view.
data + insert_index;
693 storage_view.
data + insert_end_index,
694 move_construction_destination_index - insert_end_index};
697 move_construction.
size()};
700 insert_assignment.
data() + insert_assignment.
size(),
701 insert_count - insert_assignment.
size()};
704 move_construction_values,
705 move_construction.
size());
708 destination = move_assignment.
data() + move_assignment.
size(),
709 last_destination = move_assignment.
data(),
710 source = move_assignment_values + move_assignment.
size();
714 if (destination < last_destination)
break;
718 AssignElements<A>(insert_assignment.
data(),
values,
719 insert_assignment.
size());
721 ConstructElements<A>(GetAllocator(), insert_construction.
data(),
values,
722 insert_construction.
size());
724 std::move(move_construction_tx).Commit();
726 AddSize(insert_count);
731 template <
typename T,
size_t N,
typename A>
732 template <
typename...
Args>
740 std::forward<Args>(
args)...);
745 return EmplaceBackSlow(std::forward<Args>(
args)...);
748 template <
typename T,
size_t N,
typename A>
749 template <
typename...
Args>
761 std::forward<Args>(
args)...);
764 ConstructElements<A>(GetAllocator(), allocation_tx.
GetData(), move_values,
775 DeallocateIfAllocated();
776 SetAllocation(
std::move(allocation_tx).Release());
782 template <
typename T,
size_t N,
typename A>
790 SizeType<A> erase_end_index = erase_index + erase_size;
795 AssignElements<A>(storage_view.
data + erase_index, move_values,
796 storage_view.
size - erase_end_index);
799 GetAllocator(), storage_view.
data + (storage_view.
size - erase_size),
802 SubtractSize(erase_size);
806 template <
typename T,
size_t N,
typename A>
818 ComputeCapacity(storage_view.
capacity, requested_capacity);
821 ConstructElements<A>(GetAllocator(), new_data, move_values,
827 DeallocateIfAllocated();
828 SetAllocation(
std::move(allocation_tx).Release());
832 template <
typename T,
size_t N,
typename A>
838 GetAllocatedCapacity()};
848 if (storage_view.size > GetInlinedCapacity()) {
849 SizeType<A> requested_capacity = storage_view.size;
850 construct_data = allocation_tx.
Allocate(requested_capacity);
851 if (allocation_tx.
GetCapacity() >= storage_view.capacity) {
856 construct_data = GetInlinedData();
860 ConstructElements<A>(GetAllocator(), construct_data, move_values,
864 SetAllocation({storage_view.data, storage_view.capacity});
872 storage_view.capacity);
875 SetAllocation(
std::move(allocation_tx).Release());
881 template <
typename T,
size_t N,
typename A>
886 if (GetIsAllocated() && other_storage_ptr->GetIsAllocated()) {
887 swap(
data_.allocated, other_storage_ptr->data_.allocated);
888 }
else if (!GetIsAllocated() && !other_storage_ptr->GetIsAllocated()) {
890 Storage* large_ptr = other_storage_ptr;
911 Storage* inlined_ptr = other_storage_ptr;
928 allocated_storage_view.
data, allocated_storage_view.capacity});
937 allocated_storage_view.capacity});
940 swap(GetSizeAndIsAllocated(), other_storage_ptr->GetSizeAndIsAllocated());
941 swap(GetAllocator(), other_storage_ptr->GetAllocator());
945 #if !defined(__clang__) && defined(__GNUC__)
946 #pragma GCC diagnostic pop
953 #endif // ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_