diff options
Diffstat (limited to 'absl/container/internal/inlined_vector.h')
-rw-r--r-- | absl/container/internal/inlined_vector.h | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index 79533a41f3d2..f4eb92ec169a 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -52,6 +52,16 @@ void DestroyElements(AllocatorType* alloc_ptr, ValueType* destroy_first, #endif // NDEBUG } +template <typename AllocatorType> +struct StorageView { + using pointer = typename AllocatorType::pointer; + using size_type = typename AllocatorType::size_type; + + pointer data; + size_type size; + size_type capacity; +}; + template <typename T, size_t N, typename A> class Storage { public: @@ -70,9 +80,15 @@ class Storage { using const_reverse_iterator = std::reverse_iterator<const_iterator>; using AllocatorTraits = absl::allocator_traits<allocator_type>; + using StorageView = inlined_vector_internal::StorageView<allocator_type>; + + Storage() : metadata_() {} + explicit Storage(const allocator_type& alloc) : metadata_(alloc, /* empty and inlined */ 0) {} + ~Storage() { DestroyAndDeallocate(); } + size_type GetSize() const { return GetSizeAndIsAllocated() >> 1; } bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; } @@ -97,6 +113,13 @@ class Storage { return data_.allocated.allocated_capacity; } + StorageView MakeStorageView() { + return GetIsAllocated() ? StorageView{GetAllocatedData(), GetSize(), + GetAllocatedCapacity()} + : StorageView{GetInlinedData(), GetSize(), + static_cast<size_type>(N)}; + } + allocator_type* GetAllocPtr() { return std::addressof(metadata_.template get<0>()); } @@ -113,9 +136,8 @@ class Storage { void AddSize(size_type count) { GetSizeAndIsAllocated() += count << 1; } - void SetAllocatedData(pointer data) { data_.allocated.allocated_data = data; } - - void SetAllocatedCapacity(size_type capacity) { + void SetAllocatedData(pointer data, size_type capacity) { + data_.allocated.allocated_data = data; data_.allocated.allocated_capacity = capacity; } @@ -129,6 +151,8 @@ class Storage { swap(data_.allocated, other->data_.allocated); } + void DestroyAndDeallocate(); + private: size_type& GetSizeAndIsAllocated() { return metadata_.template get<1>(); } @@ -159,6 +183,20 @@ class Storage { Data data_; }; +template <typename T, size_t N, typename A> +void Storage<T, N, A>::DestroyAndDeallocate() { + namespace ivi = inlined_vector_internal; + + StorageView storage_view = MakeStorageView(); + + ivi::DestroyElements(GetAllocPtr(), storage_view.data, storage_view.size); + + if (GetIsAllocated()) { + AllocatorTraits::deallocate(*GetAllocPtr(), storage_view.data, + storage_view.capacity); + } +} + } // namespace inlined_vector_internal } // namespace absl |