summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--absl/container/inlined_vector.h120
-rw-r--r--absl/container/internal/inlined_vector.h44
-rw-r--r--absl/debugging/BUILD.bazel1
-rw-r--r--absl/debugging/CMakeLists.txt1
4 files changed, 87 insertions, 79 deletions
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index c31c319c..046182dd 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -100,9 +100,8 @@ class InlinedVector {
// InlinedVector Constructors and Destructor
// ---------------------------------------------------------------------------
- // Creates an empty inlined vector with a default initialized allocator.
- InlinedVector() noexcept(noexcept(allocator_type()))
- : storage_(allocator_type()) {}
+ // Creates an empty inlined vector with a value-initialized allocator.
+ InlinedVector() noexcept(noexcept(allocator_type())) : storage_() {}
// Creates an empty inlined vector with a specified allocator.
explicit InlinedVector(const allocator_type& alloc) noexcept
@@ -112,22 +111,40 @@ class InlinedVector {
explicit InlinedVector(size_type n,
const allocator_type& alloc = allocator_type())
: storage_(alloc) {
- InitAssign(n);
+ if (n > static_cast<size_type>(N)) {
+ pointer new_data = AllocatorTraits::allocate(*storage_.GetAllocPtr(), n);
+ storage_.SetAllocatedData(new_data, n);
+ UninitializedFill(storage_.GetAllocatedData(),
+ storage_.GetAllocatedData() + n);
+ storage_.SetAllocatedSize(n);
+ } else {
+ UninitializedFill(storage_.GetInlinedData(),
+ storage_.GetInlinedData() + n);
+ storage_.SetInlinedSize(n);
+ }
}
// Creates an inlined vector with `n` copies of `v`.
InlinedVector(size_type n, const_reference v,
const allocator_type& alloc = allocator_type())
: storage_(alloc) {
- InitAssign(n, v);
+ if (n > static_cast<size_type>(N)) {
+ pointer new_data = AllocatorTraits::allocate(*storage_.GetAllocPtr(), n);
+ storage_.SetAllocatedData(new_data, n);
+ UninitializedFill(storage_.GetAllocatedData(),
+ storage_.GetAllocatedData() + n, v);
+ storage_.SetAllocatedSize(n);
+ } else {
+ UninitializedFill(storage_.GetInlinedData(),
+ storage_.GetInlinedData() + n, v);
+ storage_.SetInlinedSize(n);
+ }
}
// Creates an inlined vector of copies of the values in `list`.
InlinedVector(std::initializer_list<value_type> list,
const allocator_type& alloc = allocator_type())
- : storage_(alloc) {
- AppendForwardRange(list.begin(), list.end());
- }
+ : InlinedVector(list.begin(), list.end(), alloc) {}
// Creates an inlined vector with elements constructed from the provided
// forward iterator range [`first`, `last`).
@@ -140,7 +157,15 @@ class InlinedVector {
InlinedVector(ForwardIterator first, ForwardIterator last,
const allocator_type& alloc = allocator_type())
: storage_(alloc) {
- AppendForwardRange(first, last);
+ auto length = std::distance(first, last);
+ reserve(size() + length);
+ if (storage_.GetIsAllocated()) {
+ UninitializedCopy(first, last, storage_.GetAllocatedData() + size());
+ storage_.SetAllocatedSize(size() + length);
+ } else {
+ UninitializedCopy(first, last, storage_.GetInlinedData() + size());
+ storage_.SetInlinedSize(size() + length);
+ }
}
// Creates an inlined vector with elements constructed from the provided input
@@ -193,8 +218,8 @@ class InlinedVector {
if (other.storage_.GetIsAllocated()) {
// We can just steal the underlying buffer from the source.
// That leaves the source empty, so we clear its size.
- storage_.SetAllocatedData(other.storage_.GetAllocatedData());
- storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity());
+ storage_.SetAllocatedData(other.storage_.GetAllocatedData(),
+ other.storage_.GetAllocatedCapacity());
storage_.SetAllocatedSize(other.size());
other.storage_.SetInlinedSize(0);
} else {
@@ -227,8 +252,8 @@ class InlinedVector {
if (*storage_.GetAllocPtr() == *other.storage_.GetAllocPtr()) {
// We can just steal the allocation from the source.
storage_.SetAllocatedSize(other.size());
- storage_.SetAllocatedData(other.storage_.GetAllocatedData());
- storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity());
+ storage_.SetAllocatedData(other.storage_.GetAllocatedData(),
+ other.storage_.GetAllocatedCapacity());
other.storage_.SetInlinedSize(0);
} else {
// We need to use our own allocator
@@ -248,7 +273,7 @@ class InlinedVector {
}
}
- ~InlinedVector() { clear(); }
+ ~InlinedVector() {}
// ---------------------------------------------------------------------------
// InlinedVector Member Accessors
@@ -473,8 +498,8 @@ class InlinedVector {
if (other.storage_.GetIsAllocated()) {
clear();
storage_.SetAllocatedSize(other.size());
- storage_.SetAllocatedData(other.storage_.GetAllocatedData());
- storage_.SetAllocatedCapacity(other.storage_.GetAllocatedCapacity());
+ storage_.SetAllocatedData(other.storage_.GetAllocatedData(),
+ other.storage_.GetAllocatedCapacity());
other.storage_.SetInlinedSize(0);
} else {
if (storage_.GetIsAllocated()) clear();
@@ -793,16 +818,8 @@ class InlinedVector {
// Destroys all elements in the inlined vector, sets the size of `0` and
// deallocates the heap allocation if the inlined vector was allocated.
void clear() noexcept {
- const bool is_allocated = storage_.GetIsAllocated();
- pointer the_data =
- is_allocated ? storage_.GetAllocatedData() : storage_.GetInlinedData();
- inlined_vector_internal::DestroyElements(storage_.GetAllocPtr(), the_data,
- storage_.GetSize());
+ storage_.DestroyAndDeallocate();
storage_.SetInlinedSize(0);
- if (is_allocated) {
- AllocatorTraits::deallocate(*storage_.GetAllocPtr(), the_data,
- storage_.GetAllocatedCapacity());
- }
}
// `InlinedVector::reserve()`
@@ -883,8 +900,7 @@ class InlinedVector {
Destroy(storage_.GetInlinedData(), storage_.GetInlinedData() + size());
}
- storage_.SetAllocatedData(new_data);
- storage_.SetAllocatedCapacity(new_capacity);
+ storage_.SetAllocatedData(new_data, new_capacity);
storage_.SetAllocatedSize(new_size);
}
@@ -1032,53 +1048,6 @@ class InlinedVector {
return new_element;
}
- void InitAssign(size_type n) {
- if (n > static_cast<size_type>(N)) {
- pointer new_data = AllocatorTraits::allocate(*storage_.GetAllocPtr(), n);
- storage_.SetAllocatedData(new_data);
- storage_.SetAllocatedCapacity(n);
- UninitializedFill(storage_.GetAllocatedData(),
- storage_.GetAllocatedData() + n);
- storage_.SetAllocatedSize(n);
- } else {
- UninitializedFill(storage_.GetInlinedData(),
- storage_.GetInlinedData() + n);
- storage_.SetInlinedSize(n);
- }
- }
-
- void InitAssign(size_type n, const_reference v) {
- if (n > static_cast<size_type>(N)) {
- pointer new_data = AllocatorTraits::allocate(*storage_.GetAllocPtr(), n);
- storage_.SetAllocatedData(new_data);
- storage_.SetAllocatedCapacity(n);
- UninitializedFill(storage_.GetAllocatedData(),
- storage_.GetAllocatedData() + n, v);
- storage_.SetAllocatedSize(n);
- } else {
- UninitializedFill(storage_.GetInlinedData(),
- storage_.GetInlinedData() + n, v);
- storage_.SetInlinedSize(n);
- }
- }
-
- template <typename ForwardIt>
- void AppendForwardRange(ForwardIt first, ForwardIt last) {
- static_assert(absl::inlined_vector_internal::IsAtLeastForwardIterator<
- ForwardIt>::value,
- "");
-
- auto length = std::distance(first, last);
- reserve(size() + length);
- if (storage_.GetIsAllocated()) {
- UninitializedCopy(first, last, storage_.GetAllocatedData() + size());
- storage_.SetAllocatedSize(size() + length);
- } else {
- UninitializedCopy(first, last, storage_.GetInlinedData() + size());
- storage_.SetInlinedSize(size() + length);
- }
- }
-
iterator InsertWithCount(const_iterator position, size_type n,
const_reference v) {
assert(position >= begin() && position <= end());
@@ -1191,8 +1160,7 @@ class InlinedVector {
a->Destroy(a->storage_.GetInlinedData(),
a->storage_.GetInlinedData() + a_size);
- a->storage_.SetAllocatedData(b_data);
- a->storage_.SetAllocatedCapacity(b_capacity);
+ a->storage_.SetAllocatedData(b_data, b_capacity);
if (*a->storage_.GetAllocPtr() != *b->storage_.GetAllocPtr()) {
swap(*a->storage_.GetAllocPtr(), *b->storage_.GetAllocPtr());
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
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel
index e4aed5e4..913cfafb 100644
--- a/absl/debugging/BUILD.bazel
+++ b/absl/debugging/BUILD.bazel
@@ -61,6 +61,7 @@ cc_library(
":demangle_internal",
"//absl/base",
"//absl/base:core_headers",
+ "//absl/base:dynamic_annotations",
"//absl/base:malloc_internal",
],
)
diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt
index d813fede..001e2727 100644
--- a/absl/debugging/CMakeLists.txt
+++ b/absl/debugging/CMakeLists.txt
@@ -50,6 +50,7 @@ absl_cc_library(
absl::demangle_internal
absl::base
absl::core_headers
+ absl::dynamic_annotations
absl::malloc_internal
PUBLIC
)