summaryrefslogtreecommitdiff
path: root/absl/container/internal/inlined_vector.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/container/internal/inlined_vector.h')
-rw-r--r--absl/container/internal/inlined_vector.h44
1 files changed, 41 insertions, 3 deletions
diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h
index 79533a41..f4eb92ec 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