From 72e09a54d993b192db32be14c65adf7e9bd08c31 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 25 Jun 2019 12:32:44 -0700 Subject: Export of internal Abseil changes. -- 2ee5dbb79b56539b580c3a36eec5a025d08b7022 by Eric Fiselier : Unconditionally apply no-sanitize attributes. We currently fail to apply the attributes in open-source land because the build system doesn't define ADDRESS_SANITIZER like we expect. The attributes should have no effect when the sanitizers are disabled. PiperOrigin-RevId: 255024122 -- 5a123175146de14d04013862aa378f28f8eff73c by CJ Johnson : Updates the InputIterator-accepting member functions of InlinedVector to be cleaner/easier to read PiperOrigin-RevId: 254994794 -- a4bdb61407a76317810785a34e49f996699ab4a4 by Abseil Team : Added back c_move_backward which was previously deleted by mistake. PiperOrigin-RevId: 254990809 -- bc427ca5f7fb88a70ba3a676bb9c7ff829c65ae9 by CJ Johnson : Removes DestroyAndDeallocate() function from the internal details of InlinedVector because it ended up not being particularly useful PiperOrigin-RevId: 254981201 GitOrigin-RevId: 2ee5dbb79b56539b580c3a36eec5a025d08b7022 Change-Id: I825c6c0a2fcf13ed6e60d71224037a57d7068d55 --- absl/algorithm/container.h | 10 ++++++++++ absl/algorithm/container_test.cc | 13 +++++++++++++ absl/base/attributes.h | 6 +++--- absl/container/inlined_vector.h | 29 ++++++++++++++++++----------- absl/container/internal/inlined_vector.h | 16 +++++----------- 5 files changed, 49 insertions(+), 25 deletions(-) diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 752e47b23939..c84de461ac28 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h @@ -510,6 +510,16 @@ OutputIterator c_move(C&& src, OutputIterator dest) { container_algorithm_internal::c_end(src), dest); } +// c_move_backward() +// +// Container-based version of the `std::move_backward()` function to +// move a container's elements into an iterator in reverse order. +template +BidirectionalIterator c_move_backward(C&& src, BidirectionalIterator dest) { + return std::move_backward(container_algorithm_internal::c_begin(src), + container_algorithm_internal::c_end(src), dest); +} + // c_swap_ranges() // // Container-based version of the `std::swap_ranges()` function to diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc index 04282b8947a0..86bf9d3ea327 100644 --- a/absl/algorithm/container_test.cc +++ b/absl/algorithm/container_test.cc @@ -636,6 +636,19 @@ TEST(MutatingTest, Move) { Pointee(5))); } +TEST(MutatingTest, MoveBackward) { + std::vector> actual; + actual.emplace_back(absl::make_unique(1)); + actual.emplace_back(absl::make_unique(2)); + actual.emplace_back(absl::make_unique(3)); + actual.emplace_back(absl::make_unique(4)); + actual.emplace_back(absl::make_unique(5)); + auto subrange = absl::MakeSpan(actual.data(), 3); + absl::c_move_backward(subrange, actual.end()); + EXPECT_THAT(actual, ElementsAre(IsNull(), IsNull(), Pointee(1), Pointee(2), + Pointee(3))); +} + TEST(MutatingTest, MoveWithRvalue) { auto MakeRValueSrc = [] { std::vector> src; diff --git a/absl/base/attributes.h b/absl/base/attributes.h index 48195d6170d0..a7da62af73e5 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -232,7 +232,7 @@ // out of bounds or does other scary things with memory. // NOTE: GCC supports AddressSanitizer(asan) since 4.8. // https://gcc.gnu.org/gcc-4.8/changes.html -#if defined(__GNUC__) && defined(ADDRESS_SANITIZER) +#if defined(__GNUC__) #define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) #else #define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS @@ -246,7 +246,7 @@ // This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals // with initialized-ness rather than addressability issues. // NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. -#if defined(__GNUC__) && defined(MEMORY_SANITIZER) +#if defined(__clang__) #define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) #else #define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY @@ -257,7 +257,7 @@ // Tells the ThreadSanitizer to not instrument a given function. // NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. // https://gcc.gnu.org/gcc-4.8/changes.html -#if defined(__GNUC__) && defined(THREAD_SANITIZER) +#if defined(__GNUC__) #define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) #else #define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 784b07f446a5..e67885c2fc5d 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -507,12 +507,13 @@ class InlinedVector { template * = nullptr> void assign(InputIterator first, InputIterator last) { - size_type assign_index = 0; - for (; (assign_index < size()) && (first != last); - static_cast(++assign_index), static_cast(++first)) { - *(data() + assign_index) = *first; + size_type i = 0; + for (; i < size() && first != last; ++i, static_cast(++first)) { + at(i) = *first; } - erase(data() + assign_index, data() + size()); + + erase(data() + i, data() + size()); + std::copy(first, last, std::back_inserter(*this)); } @@ -595,12 +596,15 @@ class InlinedVector { template * = nullptr> iterator insert(const_iterator pos, InputIterator first, InputIterator last) { - size_type initial_insert_index = std::distance(cbegin(), pos); - for (size_type insert_index = initial_insert_index; first != last; - static_cast(++insert_index), static_cast(++first)) { - insert(data() + insert_index, *first); + assert(pos >= begin()); + assert(pos <= end()); + + size_type index = std::distance(cbegin(), pos); + for (size_type i = index; first != last; ++i, static_cast(++first)) { + insert(data() + i, *first); } - return iterator(data() + initial_insert_index); + + return iterator(data() + index); } // `InlinedVector::emplace()` @@ -677,6 +681,7 @@ class InlinedVector { // by `1` (unless the inlined vector is empty, in which case this is a no-op). void pop_back() noexcept { assert(!empty()); + AllocatorTraits::destroy(*storage_.GetAllocPtr(), data() + (size() - 1)); storage_.SubtractSize(1); } @@ -731,7 +736,9 @@ 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 { - storage_.DestroyAndDeallocate(); + inlined_vector_internal::DestroyElements(storage_.GetAllocPtr(), data(), + size()); + storage_.DeallocateIfAllocated(); storage_.SetInlinedSize(0); } diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index a84b5255a82e..c2802c823a8d 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -275,7 +275,11 @@ class Storage { explicit Storage(const allocator_type& alloc) : metadata_(alloc, /* empty and inlined */ 0) {} - ~Storage() { DestroyAndDeallocate(); } + ~Storage() { + pointer data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); + inlined_vector_internal::DestroyElements(GetAllocPtr(), data, GetSize()); + DeallocateIfAllocated(); + } size_type GetSize() const { return GetSizeAndIsAllocated() >> 1; } @@ -377,8 +381,6 @@ class Storage { data_ = other_storage.data_; } - void DestroyAndDeallocate(); - template void Initialize(ValueAdapter values, size_type new_size); @@ -432,14 +434,6 @@ class Storage { Data data_; }; -template -void Storage::DestroyAndDeallocate() { - inlined_vector_internal::DestroyElements( - GetAllocPtr(), (GetIsAllocated() ? GetAllocatedData() : GetInlinedData()), - GetSize()); - DeallocateIfAllocated(); -} - template template auto Storage::Initialize(ValueAdapter values, size_type new_size) -- cgit 1.4.1