Export of internal Abseil changes.

--
2ee5dbb79b56539b580c3a36eec5a025d08b7022 by Eric Fiselier <ericwf@google.com>:

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 <johnsoncj@google.com>:

Updates the InputIterator-accepting member functions of InlinedVector to be cleaner/easier to read

PiperOrigin-RevId: 254994794

--
a4bdb61407a76317810785a34e49f996699ab4a4 by Abseil Team <absl-team@google.com>:

Added back c_move_backward which was previously deleted by mistake.

PiperOrigin-RevId: 254990809

--
bc427ca5f7fb88a70ba3a676bb9c7ff829c65ae9 by CJ Johnson <johnsoncj@google.com>:

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
This commit is contained in:
Abseil Team 2019-06-25 12:32:44 -07:00 committed by Shaindel Schwartz
parent d65e19dfcd
commit 72e09a54d9
5 changed files with 49 additions and 25 deletions

View file

@ -510,6 +510,16 @@ OutputIterator c_move(C&& src, OutputIterator dest) {
container_algorithm_internal::c_end(src), dest); container_algorithm_internal::c_end(src), dest);
} }
// c_move_backward()
//
// Container-based version of the <algorithm> `std::move_backward()` function to
// move a container's elements into an iterator in reverse order.
template <typename C, typename BidirectionalIterator>
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() // c_swap_ranges()
// //
// Container-based version of the <algorithm> `std::swap_ranges()` function to // Container-based version of the <algorithm> `std::swap_ranges()` function to

View file

@ -636,6 +636,19 @@ TEST(MutatingTest, Move) {
Pointee(5))); Pointee(5)));
} }
TEST(MutatingTest, MoveBackward) {
std::vector<std::unique_ptr<int>> actual;
actual.emplace_back(absl::make_unique<int>(1));
actual.emplace_back(absl::make_unique<int>(2));
actual.emplace_back(absl::make_unique<int>(3));
actual.emplace_back(absl::make_unique<int>(4));
actual.emplace_back(absl::make_unique<int>(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) { TEST(MutatingTest, MoveWithRvalue) {
auto MakeRValueSrc = [] { auto MakeRValueSrc = [] {
std::vector<std::unique_ptr<int>> src; std::vector<std::unique_ptr<int>> src;

View file

@ -232,7 +232,7 @@
// out of bounds or does other scary things with memory. // out of bounds or does other scary things with memory.
// NOTE: GCC supports AddressSanitizer(asan) since 4.8. // NOTE: GCC supports AddressSanitizer(asan) since 4.8.
// https://gcc.gnu.org/gcc-4.8/changes.html // 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)) #define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#else #else
#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS #define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS
@ -246,7 +246,7 @@
// This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals // This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals
// with initialized-ness rather than addressability issues. // with initialized-ness rather than addressability issues.
// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. // 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)) #define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
#else #else
#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY #define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY
@ -257,7 +257,7 @@
// Tells the ThreadSanitizer to not instrument a given function. // Tells the ThreadSanitizer to not instrument a given function.
// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. // NOTE: GCC supports ThreadSanitizer(tsan) since 4.8.
// https://gcc.gnu.org/gcc-4.8/changes.html // 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)) #define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
#else #else
#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD #define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD

View file

@ -507,12 +507,13 @@ class InlinedVector {
template <typename InputIterator, template <typename InputIterator,
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr> DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
void assign(InputIterator first, InputIterator last) { void assign(InputIterator first, InputIterator last) {
size_type assign_index = 0; size_type i = 0;
for (; (assign_index < size()) && (first != last); for (; i < size() && first != last; ++i, static_cast<void>(++first)) {
static_cast<void>(++assign_index), static_cast<void>(++first)) { at(i) = *first;
*(data() + assign_index) = *first;
} }
erase(data() + assign_index, data() + size());
erase(data() + i, data() + size());
std::copy(first, last, std::back_inserter(*this)); std::copy(first, last, std::back_inserter(*this));
} }
@ -595,12 +596,15 @@ class InlinedVector {
template <typename InputIterator, template <typename InputIterator,
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr> DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
iterator insert(const_iterator pos, InputIterator first, InputIterator last) { iterator insert(const_iterator pos, InputIterator first, InputIterator last) {
size_type initial_insert_index = std::distance(cbegin(), pos); assert(pos >= begin());
for (size_type insert_index = initial_insert_index; first != last; assert(pos <= end());
static_cast<void>(++insert_index), static_cast<void>(++first)) {
insert(data() + insert_index, *first); size_type index = std::distance(cbegin(), pos);
for (size_type i = index; first != last; ++i, static_cast<void>(++first)) {
insert(data() + i, *first);
} }
return iterator(data() + initial_insert_index);
return iterator(data() + index);
} }
// `InlinedVector::emplace()` // `InlinedVector::emplace()`
@ -677,6 +681,7 @@ class InlinedVector {
// by `1` (unless the inlined vector is empty, in which case this is a no-op). // by `1` (unless the inlined vector is empty, in which case this is a no-op).
void pop_back() noexcept { void pop_back() noexcept {
assert(!empty()); assert(!empty());
AllocatorTraits::destroy(*storage_.GetAllocPtr(), data() + (size() - 1)); AllocatorTraits::destroy(*storage_.GetAllocPtr(), data() + (size() - 1));
storage_.SubtractSize(1); storage_.SubtractSize(1);
} }
@ -731,7 +736,9 @@ class InlinedVector {
// Destroys all elements in the inlined vector, sets the size of `0` and // Destroys all elements in the inlined vector, sets the size of `0` and
// deallocates the heap allocation if the inlined vector was allocated. // deallocates the heap allocation if the inlined vector was allocated.
void clear() noexcept { void clear() noexcept {
storage_.DestroyAndDeallocate(); inlined_vector_internal::DestroyElements(storage_.GetAllocPtr(), data(),
size());
storage_.DeallocateIfAllocated();
storage_.SetInlinedSize(0); storage_.SetInlinedSize(0);
} }

View file

@ -275,7 +275,11 @@ class Storage {
explicit Storage(const allocator_type& alloc) explicit Storage(const allocator_type& alloc)
: metadata_(alloc, /* empty and inlined */ 0) {} : 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; } size_type GetSize() const { return GetSizeAndIsAllocated() >> 1; }
@ -377,8 +381,6 @@ class Storage {
data_ = other_storage.data_; data_ = other_storage.data_;
} }
void DestroyAndDeallocate();
template <typename ValueAdapter> template <typename ValueAdapter>
void Initialize(ValueAdapter values, size_type new_size); void Initialize(ValueAdapter values, size_type new_size);
@ -432,14 +434,6 @@ class Storage {
Data data_; Data data_;
}; };
template <typename T, size_t N, typename A>
void Storage<T, N, A>::DestroyAndDeallocate() {
inlined_vector_internal::DestroyElements(
GetAllocPtr(), (GetIsAllocated() ? GetAllocatedData() : GetInlinedData()),
GetSize());
DeallocateIfAllocated();
}
template <typename T, size_t N, typename A> template <typename T, size_t N, typename A>
template <typename ValueAdapter> template <typename ValueAdapter>
auto Storage<T, N, A>::Initialize(ValueAdapter values, size_type new_size) auto Storage<T, N, A>::Initialize(ValueAdapter values, size_type new_size)