Export of internal Abseil changes

--
f73e17cb24f7878933fc100bd9bfc39fce190b64 by Derek Mauro <dmauro@google.com>:

Internal change

PiperOrigin-RevId: 394306402

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

Release a few more absl::Cord unit tests that were accidentally omitted from the OSS release before.

PiperOrigin-RevId: 394016464

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

Fix typo in identifier

PiperOrigin-RevId: 394000560

--
d87206c7c8e045b03d74b91e47ef3db0eb47a17b by Derek Mauro <dmauro@google.com>:

Fix typo: RandenHwAes

PiperOrigin-RevId: 393879427

--
980a3402eea77b0c77fb20dd124203002ff791ba by Derek Mauro <dmauro@google.com>:

Adds macros `ABSL_LTS_RELEASE_VERSION` and `ABSL_LTS_RELEASE_PATCH_LEVEL`
to allow projects to detect if an LTS version is being used.

Fixes #1006

PiperOrigin-RevId: 393807178

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

Change `alloc` to `allocator` to match the fact that other identifiers are full words

PiperOrigin-RevId: 393794869

--
ad754bbcf7b78f5d51ed5f39193ac3159429b2b4 by Derek Mauro <dmauro@google.com>:

Remove self-include of cord_rep_btree.h

PiperOrigin-RevId: 393792085

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

Fix trivial typo in comment.

PiperOrigin-RevId: 393770527

--
7a58ca5d708038d222c6a2b6ff5076b4ceffd370 by Tomas Dzetkulic <dzetkulic@google.com>:

Update Cord::AppendArray resize policy.

PiperOrigin-RevId: 393362184

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

Add a new top level profiling/ directory to the Abseil library

PiperOrigin-RevId: 393358109

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

Switch to the more common enable_if pattern of ` = 0` in InlinedVector

PiperOrigin-RevId: 393301549

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

Clean up typedefs in internal/inlined_vector.h

PiperOrigin-RevId: 393181754
GitOrigin-RevId: f73e17cb24f7878933fc100bd9bfc39fce190b64
Change-Id: I0c4cd4d71d97bd1bf651701b6302ea3d9ac59b66
pull/1013/head
Abseil Team 3 years ago committed by dinord
parent 665ac5b425
commit 4bb9e39c88
  1. 2
      CMake/install_test_project/CMakeLists.txt
  2. 9
      CMake/install_test_project/simple.cc
  3. 3
      README.md
  4. 1
      absl/CMakeLists.txt
  5. 29
      absl/base/config.h
  6. 177
      absl/container/inlined_vector.h
  7. 669
      absl/container/internal/inlined_vector.h
  8. 17
      absl/profiling/BUILD.bazel
  9. 14
      absl/profiling/CMakeLists.txt
  10. 2
      absl/random/internal/randen_hwaes.cc
  11. 11
      absl/strings/cord.cc
  12. 53
      absl/strings/cord_test.cc
  13. 1
      absl/strings/internal/cord_rep_btree.h
  14. 2
      absl/strings/internal/str_format/bind.h
  15. 7
      create_lts.py

@ -22,4 +22,4 @@ add_executable(simple simple.cc)
find_package(absl REQUIRED) find_package(absl REQUIRED)
target_link_libraries(simple absl::strings) target_link_libraries(simple absl::strings absl::config)

@ -14,8 +14,17 @@
// limitations under the License. // limitations under the License.
#include <iostream> #include <iostream>
#include "absl/base/config.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#if !defined(ABSL_LTS_RELEASE_VERSION) || ABSL_LTS_RELEASE_VERSION != 99998877
#error ABSL_LTS_RELEASE_VERSION is not set correctly.
#endif
#if !defined(ABSL_LTS_RELEASE_PATCH_LEVEL) || ABSL_LTS_RELEASE_PATCH_LEVEL != 0
#error ABSL_LTS_RELEASE_PATCH_LEVEL is not set correctly.
#endif
int main(int argc, char** argv) { int main(int argc, char** argv) {
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
std::cout << absl::Substitute("Arg $0: $1\n", i, argv[i]); std::cout << absl::Substitute("Arg $0: $1\n", i, argv[i]);

@ -92,6 +92,9 @@ Abseil contains the following C++ library components:
available within C++14 and C++17 versions of the C++ `<type_traits>` library. available within C++14 and C++17 versions of the C++ `<type_traits>` library.
* [`numeric`](absl/numeric/) * [`numeric`](absl/numeric/)
<br /> The `numeric` library contains C++11-compatible 128-bit integers. <br /> The `numeric` library contains C++11-compatible 128-bit integers.
* [`profiling`](absl/profiling/)
<br /> The `profiling` library contains utility code for profiling C++
entities. It is currently a private dependency of other Abseil libraries.
* [`status`](absl/status/) * [`status`](absl/status/)
<br /> The `status` contains abstractions for error handling, specifically <br /> The `status` contains abstractions for error handling, specifically
`absl::Status` and `absl::StatusOr<T>`. `absl::Status` and `absl::StatusOr<T>`.

@ -25,6 +25,7 @@ add_subdirectory(hash)
add_subdirectory(memory) add_subdirectory(memory)
add_subdirectory(meta) add_subdirectory(meta)
add_subdirectory(numeric) add_subdirectory(numeric)
add_subdirectory(profiling)
add_subdirectory(random) add_subdirectory(random)
add_subdirectory(status) add_subdirectory(status)
add_subdirectory(strings) add_subdirectory(strings)

@ -66,6 +66,35 @@
#include "absl/base/options.h" #include "absl/base/options.h"
#include "absl/base/policy_checks.h" #include "absl/base/policy_checks.h"
// Abseil long-term support (LTS) releases will define
// `ABSL_LTS_RELEASE_VERSION` to the integer representing the date string of the
// LTS release version, and will define `ABSL_LTS_RELEASE_PATCH_LEVEL` to the
// integer representing the patch-level for that release.
//
// For example, for LTS release version "20300401.2", this would give us
// ABSL_LTS_RELEASE_VERSION == 20300401 && ABSL_LTS_RELEASE_PATCH_LEVEL == 2
//
// These symbols will not be defined in non-LTS code.
//
// Abseil recommends that clients live-at-head. Therefore, if you are using
// these symbols to assert a minimum version requirement, we recommend you do it
// as
//
// #if defined(ABSL_LTS_RELEASE_VERSION) && ABSL_LTS_RELEASE_VERSION < 20300401
// #error Project foo requires Abseil LTS version >= 20300401
// #endif
//
// The `defined(ABSL_LTS_RELEASE_VERSION)` part of the check excludes
// live-at-head clients from the minimum version assertion.
//
// See https://abseil.io/about/releases for more information on Abseil release
// management.
//
// LTS releases can be obtained from
// https://github.com/abseil/abseil-cpp/releases.
#undef ABSL_LTS_RELEASE_VERSION
#undef ABSL_LTS_RELEASE_PATCH_LEVEL
// Helper macro to convert a CPP variable to a string literal. // Helper macro to convert a CPP variable to a string literal.
#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x #define ABSL_INTERNAL_DO_TOKEN_STR(x) #x
#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) #define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x)

@ -72,37 +72,43 @@ class InlinedVector {
using Storage = inlined_vector_internal::Storage<T, N, A>; using Storage = inlined_vector_internal::Storage<T, N, A>;
using AllocatorTraits = typename Storage::AllocatorTraits; template <typename TheA>
using RValueReference = typename Storage::RValueReference; using AllocatorTraits = inlined_vector_internal::AllocatorTraits<TheA>;
using MoveIterator = typename Storage::MoveIterator; template <typename TheA>
using IsMemcpyOk = typename Storage::IsMemcpyOk; using MoveIterator = inlined_vector_internal::MoveIterator<TheA>;
template <typename TheA>
template <typename Iterator> using IsMemcpyOk = inlined_vector_internal::IsMemcpyOk<TheA>;
template <typename TheA, typename Iterator>
using IteratorValueAdapter = using IteratorValueAdapter =
typename Storage::template IteratorValueAdapter<Iterator>; inlined_vector_internal::IteratorValueAdapter<TheA, Iterator>;
using CopyValueAdapter = typename Storage::CopyValueAdapter; template <typename TheA>
using DefaultValueAdapter = typename Storage::DefaultValueAdapter; using CopyValueAdapter = inlined_vector_internal::CopyValueAdapter<TheA>;
template <typename TheA>
using DefaultValueAdapter =
inlined_vector_internal::DefaultValueAdapter<TheA>;
template <typename Iterator> template <typename Iterator>
using EnableIfAtLeastForwardIterator = absl::enable_if_t< using EnableIfAtLeastForwardIterator = absl::enable_if_t<
inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value>; inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>;
template <typename Iterator> template <typename Iterator>
using DisableIfAtLeastForwardIterator = absl::enable_if_t< using DisableIfAtLeastForwardIterator = absl::enable_if_t<
!inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value>; !inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>;
public: public:
using allocator_type = typename Storage::allocator_type; using allocator_type = A;
using value_type = typename Storage::value_type; using value_type = inlined_vector_internal::ValueType<A>;
using pointer = typename Storage::pointer; using pointer = inlined_vector_internal::Pointer<A>;
using const_pointer = typename Storage::const_pointer; using const_pointer = inlined_vector_internal::ConstPointer<A>;
using size_type = typename Storage::size_type; using size_type = inlined_vector_internal::SizeType<A>;
using difference_type = typename Storage::difference_type; using difference_type = inlined_vector_internal::DifferenceType<A>;
using reference = typename Storage::reference; using reference = inlined_vector_internal::Reference<A>;
using const_reference = typename Storage::const_reference; using const_reference = inlined_vector_internal::ConstReference<A>;
using iterator = typename Storage::iterator; using iterator = inlined_vector_internal::Iterator<A>;
using const_iterator = typename Storage::const_iterator; using const_iterator = inlined_vector_internal::ConstIterator<A>;
using reverse_iterator = typename Storage::reverse_iterator; using reverse_iterator = inlined_vector_internal::ReverseIterator<A>;
using const_reverse_iterator = typename Storage::const_reverse_iterator; using const_reverse_iterator =
inlined_vector_internal::ConstReverseIterator<A>;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// InlinedVector Constructors and Destructor // InlinedVector Constructors and Destructor
@ -111,28 +117,28 @@ class InlinedVector {
// Creates an empty inlined vector with a value-initialized allocator. // Creates an empty inlined vector with a value-initialized allocator.
InlinedVector() noexcept(noexcept(allocator_type())) : storage_() {} InlinedVector() noexcept(noexcept(allocator_type())) : storage_() {}
// Creates an empty inlined vector with a copy of `alloc`. // Creates an empty inlined vector with a copy of `allocator`.
explicit InlinedVector(const allocator_type& alloc) noexcept explicit InlinedVector(const allocator_type& allocator) noexcept
: storage_(alloc) {} : storage_(allocator) {}
// Creates an inlined vector with `n` copies of `value_type()`. // Creates an inlined vector with `n` copies of `value_type()`.
explicit InlinedVector(size_type n, explicit InlinedVector(size_type n,
const allocator_type& alloc = allocator_type()) const allocator_type& allocator = allocator_type())
: storage_(alloc) { : storage_(allocator) {
storage_.Initialize(DefaultValueAdapter(), n); storage_.Initialize(DefaultValueAdapter<A>(), n);
} }
// Creates an inlined vector with `n` copies of `v`. // Creates an inlined vector with `n` copies of `v`.
InlinedVector(size_type n, const_reference v, InlinedVector(size_type n, const_reference v,
const allocator_type& alloc = allocator_type()) const allocator_type& allocator = allocator_type())
: storage_(alloc) { : storage_(allocator) {
storage_.Initialize(CopyValueAdapter(v), n); storage_.Initialize(CopyValueAdapter<A>(std::addressof(v)), n);
} }
// Creates an inlined vector with copies of the elements of `list`. // Creates an inlined vector with copies of the elements of `list`.
InlinedVector(std::initializer_list<value_type> list, InlinedVector(std::initializer_list<value_type> list,
const allocator_type& alloc = allocator_type()) const allocator_type& allocator = allocator_type())
: InlinedVector(list.begin(), list.end(), alloc) {} : InlinedVector(list.begin(), list.end(), allocator) {}
// Creates an inlined vector with elements constructed from the provided // Creates an inlined vector with elements constructed from the provided
// forward iterator range [`first`, `last`). // forward iterator range [`first`, `last`).
@ -141,35 +147,36 @@ class InlinedVector {
// this constructor with two integral arguments and a call to the above // this constructor with two integral arguments and a call to the above
// `InlinedVector(size_type, const_reference)` constructor. // `InlinedVector(size_type, const_reference)` constructor.
template <typename ForwardIterator, template <typename ForwardIterator,
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr> EnableIfAtLeastForwardIterator<ForwardIterator> = 0>
InlinedVector(ForwardIterator first, ForwardIterator last, InlinedVector(ForwardIterator first, ForwardIterator last,
const allocator_type& alloc = allocator_type()) const allocator_type& allocator = allocator_type())
: storage_(alloc) { : storage_(allocator) {
storage_.Initialize(IteratorValueAdapter<ForwardIterator>(first), storage_.Initialize(IteratorValueAdapter<A, ForwardIterator>(first),
std::distance(first, last)); std::distance(first, last));
} }
// Creates an inlined vector with elements constructed from the provided input // Creates an inlined vector with elements constructed from the provided input
// iterator range [`first`, `last`). // iterator range [`first`, `last`).
template <typename InputIterator, template <typename InputIterator,
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr> DisableIfAtLeastForwardIterator<InputIterator> = 0>
InlinedVector(InputIterator first, InputIterator last, InlinedVector(InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type()) const allocator_type& allocator = allocator_type())
: storage_(alloc) { : storage_(allocator) {
std::copy(first, last, std::back_inserter(*this)); std::copy(first, last, std::back_inserter(*this));
} }
// Creates an inlined vector by copying the contents of `other` using // Creates an inlined vector by copying the contents of `other` using
// `other`'s allocator. // `other`'s allocator.
InlinedVector(const InlinedVector& other) InlinedVector(const InlinedVector& other)
: InlinedVector(other, *other.storage_.GetAllocPtr()) {} : InlinedVector(other, other.storage_.GetAllocator()) {}
// Creates an inlined vector by copying the contents of `other` using `alloc`. // Creates an inlined vector by copying the contents of `other` using the
InlinedVector(const InlinedVector& other, const allocator_type& alloc) // provided `allocator`.
: storage_(alloc) { InlinedVector(const InlinedVector& other, const allocator_type& allocator)
: storage_(allocator) {
if (other.empty()) { if (other.empty()) {
// Empty; nothing to do. // Empty; nothing to do.
} else if (IsMemcpyOk::value && !other.storage_.GetIsAllocated()) { } else if (IsMemcpyOk<A>::value && !other.storage_.GetIsAllocated()) {
// Memcpy-able and do not need allocation. // Memcpy-able and do not need allocation.
storage_.MemcpyFrom(other.storage_); storage_.MemcpyFrom(other.storage_);
} else { } else {
@ -194,8 +201,8 @@ class InlinedVector {
InlinedVector(InlinedVector&& other) noexcept( InlinedVector(InlinedVector&& other) noexcept(
absl::allocator_is_nothrow<allocator_type>::value || absl::allocator_is_nothrow<allocator_type>::value ||
std::is_nothrow_move_constructible<value_type>::value) std::is_nothrow_move_constructible<value_type>::value)
: storage_(*other.storage_.GetAllocPtr()) { : storage_(other.storage_.GetAllocator()) {
if (IsMemcpyOk::value) { if (IsMemcpyOk<A>::value) {
storage_.MemcpyFrom(other.storage_); storage_.MemcpyFrom(other.storage_);
other.storage_.SetInlinedSize(0); other.storage_.SetInlinedSize(0);
@ -206,11 +213,11 @@ class InlinedVector {
other.storage_.SetInlinedSize(0); other.storage_.SetInlinedSize(0);
} else { } else {
IteratorValueAdapter<MoveIterator> other_values( IteratorValueAdapter<A, MoveIterator<A>> other_values(
MoveIterator(other.storage_.GetInlinedData())); MoveIterator<A>(other.storage_.GetInlinedData()));
inlined_vector_internal::ConstructElements( inlined_vector_internal::ConstructElements<A>(
storage_.GetAllocPtr(), storage_.GetInlinedData(), &other_values, storage_.GetAllocator(), storage_.GetInlinedData(), other_values,
other.storage_.GetSize()); other.storage_.GetSize());
storage_.SetInlinedSize(other.storage_.GetSize()); storage_.SetInlinedSize(other.storage_.GetSize());
@ -218,20 +225,22 @@ class InlinedVector {
} }
// Creates an inlined vector by moving in the contents of `other` with a copy // Creates an inlined vector by moving in the contents of `other` with a copy
// of `alloc`. // of `allocator`.
// //
// NOTE: if `other`'s allocator is not equal to `alloc`, even if `other` // NOTE: if `other`'s allocator is not equal to `allocator`, even if `other`
// contains allocated memory, this move constructor will still allocate. Since // contains allocated memory, this move constructor will still allocate. Since
// allocation is performed, this constructor can only be `noexcept` if the // allocation is performed, this constructor can only be `noexcept` if the
// specified allocator is also `noexcept`. // specified allocator is also `noexcept`.
InlinedVector(InlinedVector&& other, const allocator_type& alloc) noexcept( InlinedVector(
absl::allocator_is_nothrow<allocator_type>::value) InlinedVector&& other,
: storage_(alloc) { const allocator_type& allocator)
if (IsMemcpyOk::value) { noexcept(absl::allocator_is_nothrow<allocator_type>::value)
: storage_(allocator) {
if (IsMemcpyOk<A>::value) {
storage_.MemcpyFrom(other.storage_); storage_.MemcpyFrom(other.storage_);
other.storage_.SetInlinedSize(0); other.storage_.SetInlinedSize(0);
} else if ((*storage_.GetAllocPtr() == *other.storage_.GetAllocPtr()) && } else if ((storage_.GetAllocator() == other.storage_.GetAllocator()) &&
other.storage_.GetIsAllocated()) { other.storage_.GetIsAllocated()) {
storage_.SetAllocatedData(other.storage_.GetAllocatedData(), storage_.SetAllocatedData(other.storage_.GetAllocatedData(),
other.storage_.GetAllocatedCapacity()); other.storage_.GetAllocatedCapacity());
@ -239,8 +248,8 @@ class InlinedVector {
other.storage_.SetInlinedSize(0); other.storage_.SetInlinedSize(0);
} else { } else {
storage_.Initialize( storage_.Initialize(IteratorValueAdapter<A, MoveIterator<A>>(
IteratorValueAdapter<MoveIterator>(MoveIterator(other.data())), MoveIterator<A>(other.data())),
other.size()); other.size());
} }
} }
@ -442,7 +451,7 @@ class InlinedVector {
// `InlinedVector::get_allocator()` // `InlinedVector::get_allocator()`
// //
// Returns a copy of the inlined vector's allocator. // Returns a copy of the inlined vector's allocator.
allocator_type get_allocator() const { return *storage_.GetAllocPtr(); } allocator_type get_allocator() const { return storage_.GetAllocator(); }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// InlinedVector Member Mutators // InlinedVector Member Mutators
@ -476,16 +485,16 @@ class InlinedVector {
// unspecified state. // unspecified state.
InlinedVector& operator=(InlinedVector&& other) { InlinedVector& operator=(InlinedVector&& other) {
if (ABSL_PREDICT_TRUE(this != std::addressof(other))) { if (ABSL_PREDICT_TRUE(this != std::addressof(other))) {
if (IsMemcpyOk::value || other.storage_.GetIsAllocated()) { if (IsMemcpyOk<A>::value || other.storage_.GetIsAllocated()) {
inlined_vector_internal::DestroyElements(storage_.GetAllocPtr(), data(), inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(),
size()); data(), size());
storage_.DeallocateIfAllocated(); storage_.DeallocateIfAllocated();
storage_.MemcpyFrom(other.storage_); storage_.MemcpyFrom(other.storage_);
other.storage_.SetInlinedSize(0); other.storage_.SetInlinedSize(0);
} else { } else {
storage_.Assign(IteratorValueAdapter<MoveIterator>( storage_.Assign(IteratorValueAdapter<A, MoveIterator<A>>(
MoveIterator(other.storage_.GetInlinedData())), MoveIterator<A>(other.storage_.GetInlinedData())),
other.size()); other.size());
} }
} }
@ -497,7 +506,7 @@ class InlinedVector {
// //
// Replaces the contents of the inlined vector with `n` copies of `v`. // Replaces the contents of the inlined vector with `n` copies of `v`.
void assign(size_type n, const_reference v) { void assign(size_type n, const_reference v) {
storage_.Assign(CopyValueAdapter(v), n); storage_.Assign(CopyValueAdapter<A>(std::addressof(v)), n);
} }
// Overload of `InlinedVector::assign(...)` that replaces the contents of the // Overload of `InlinedVector::assign(...)` that replaces the contents of the
@ -511,9 +520,9 @@ class InlinedVector {
// //
// NOTE: this overload is for iterators that are "forward" category or better. // NOTE: this overload is for iterators that are "forward" category or better.
template <typename ForwardIterator, template <typename ForwardIterator,
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr> EnableIfAtLeastForwardIterator<ForwardIterator> = 0>
void assign(ForwardIterator first, ForwardIterator last) { void assign(ForwardIterator first, ForwardIterator last) {
storage_.Assign(IteratorValueAdapter<ForwardIterator>(first), storage_.Assign(IteratorValueAdapter<A, ForwardIterator>(first),
std::distance(first, last)); std::distance(first, last));
} }
@ -522,7 +531,7 @@ class InlinedVector {
// //
// NOTE: this overload is for iterators that are "input" category. // NOTE: this overload is for iterators that are "input" category.
template <typename InputIterator, template <typename InputIterator,
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr> DisableIfAtLeastForwardIterator<InputIterator> = 0>
void assign(InputIterator first, InputIterator last) { void assign(InputIterator first, InputIterator last) {
size_type i = 0; size_type i = 0;
for (; i < size() && first != last; ++i, static_cast<void>(++first)) { for (; i < size() && first != last; ++i, static_cast<void>(++first)) {
@ -541,7 +550,7 @@ class InlinedVector {
// is larger than `size()`, new elements are value-initialized. // is larger than `size()`, new elements are value-initialized.
void resize(size_type n) { void resize(size_type n) {
ABSL_HARDENING_ASSERT(n <= max_size()); ABSL_HARDENING_ASSERT(n <= max_size());
storage_.Resize(DefaultValueAdapter(), n); storage_.Resize(DefaultValueAdapter<A>(), n);
} }
// Overload of `InlinedVector::resize(...)` that resizes the inlined vector to // Overload of `InlinedVector::resize(...)` that resizes the inlined vector to
@ -551,7 +560,7 @@ class InlinedVector {
// is larger than `size()`, new elements are copied-constructed from `v`. // is larger than `size()`, new elements are copied-constructed from `v`.
void resize(size_type n, const_reference v) { void resize(size_type n, const_reference v) {
ABSL_HARDENING_ASSERT(n <= max_size()); ABSL_HARDENING_ASSERT(n <= max_size());
storage_.Resize(CopyValueAdapter(v), n); storage_.Resize(CopyValueAdapter<A>(std::addressof(v)), n);
} }
// `InlinedVector::insert(...)` // `InlinedVector::insert(...)`
@ -564,7 +573,7 @@ class InlinedVector {
// Overload of `InlinedVector::insert(...)` that inserts `v` at `pos` using // Overload of `InlinedVector::insert(...)` that inserts `v` at `pos` using
// move semantics, returning an `iterator` to the newly inserted element. // move semantics, returning an `iterator` to the newly inserted element.
iterator insert(const_iterator pos, RValueReference v) { iterator insert(const_iterator pos, value_type&& v) {
return emplace(pos, std::move(v)); return emplace(pos, std::move(v));
} }
@ -577,7 +586,8 @@ class InlinedVector {
if (ABSL_PREDICT_TRUE(n != 0)) { if (ABSL_PREDICT_TRUE(n != 0)) {
value_type dealias = v; value_type dealias = v;
return storage_.Insert(pos, CopyValueAdapter(dealias), n); return storage_.Insert(pos, CopyValueAdapter<A>(std::addressof(dealias)),
n);
} else { } else {
return const_cast<iterator>(pos); return const_cast<iterator>(pos);
} }
@ -596,14 +606,15 @@ class InlinedVector {
// //
// NOTE: this overload is for iterators that are "forward" category or better. // NOTE: this overload is for iterators that are "forward" category or better.
template <typename ForwardIterator, template <typename ForwardIterator,
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr> EnableIfAtLeastForwardIterator<ForwardIterator> = 0>
iterator insert(const_iterator pos, ForwardIterator first, iterator insert(const_iterator pos, ForwardIterator first,
ForwardIterator last) { ForwardIterator last) {
ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos >= begin());
ABSL_HARDENING_ASSERT(pos <= end()); ABSL_HARDENING_ASSERT(pos <= end());
if (ABSL_PREDICT_TRUE(first != last)) { if (ABSL_PREDICT_TRUE(first != last)) {
return storage_.Insert(pos, IteratorValueAdapter<ForwardIterator>(first), return storage_.Insert(pos,
IteratorValueAdapter<A, ForwardIterator>(first),
std::distance(first, last)); std::distance(first, last));
} else { } else {
return const_cast<iterator>(pos); return const_cast<iterator>(pos);
@ -616,7 +627,7 @@ class InlinedVector {
// //
// NOTE: this overload is for iterators that are "input" category. // NOTE: this overload is for iterators that are "input" category.
template <typename InputIterator, template <typename InputIterator,
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr> DisableIfAtLeastForwardIterator<InputIterator> = 0>
iterator insert(const_iterator pos, InputIterator first, InputIterator last) { iterator insert(const_iterator pos, InputIterator first, InputIterator last) {
ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos >= begin());
ABSL_HARDENING_ASSERT(pos <= end()); ABSL_HARDENING_ASSERT(pos <= end());
@ -640,8 +651,8 @@ class InlinedVector {
value_type dealias(std::forward<Args>(args)...); value_type dealias(std::forward<Args>(args)...);
return storage_.Insert(pos, return storage_.Insert(pos,
IteratorValueAdapter<MoveIterator>( IteratorValueAdapter<A, MoveIterator<A>>(
MoveIterator(std::addressof(dealias))), MoveIterator<A>(std::addressof(dealias))),
1); 1);
} }
@ -661,7 +672,7 @@ class InlinedVector {
// Overload of `InlinedVector::push_back(...)` for inserting `v` at `end()` // Overload of `InlinedVector::push_back(...)` for inserting `v` at `end()`
// using move semantics. // using move semantics.
void push_back(RValueReference v) { void push_back(value_type&& v) {
static_cast<void>(emplace_back(std::move(v))); static_cast<void>(emplace_back(std::move(v)));
} }
@ -671,7 +682,7 @@ class InlinedVector {
void pop_back() noexcept { void pop_back() noexcept {
ABSL_HARDENING_ASSERT(!empty()); ABSL_HARDENING_ASSERT(!empty());
AllocatorTraits::destroy(*storage_.GetAllocPtr(), data() + (size() - 1)); AllocatorTraits<A>::destroy(storage_.GetAllocator(), data() + (size() - 1));
storage_.SubtractSize(1); storage_.SubtractSize(1);
} }
@ -710,7 +721,7 @@ class InlinedVector {
// Destroys all elements in the inlined vector, setting the size to `0` and // Destroys all elements in the inlined vector, setting the size to `0` and
// deallocating any held memory. // deallocating any held memory.
void clear() noexcept { void clear() noexcept {
inlined_vector_internal::DestroyElements(storage_.GetAllocPtr(), data(), inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), data(),
size()); size());
storage_.DeallocateIfAllocated(); storage_.DeallocateIfAllocated();

File diff suppressed because it is too large Load Diff

@ -0,0 +1,17 @@
# Copyright 2021 The Abseil Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
package(default_visibility = ["//visibility:private"])
licenses(["notice"])

@ -0,0 +1,14 @@
# Copyright 2021 The Abseil Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

@ -31,7 +31,7 @@
// a hardware accelerated implementation of randen, or whether it // a hardware accelerated implementation of randen, or whether it
// will contain stubs that exit the process. // will contain stubs that exit the process.
#if ABSL_HAVE_ACCELERATED_AES #if ABSL_HAVE_ACCELERATED_AES
// The following plaforms have implemented RandenHwAws. // The following plaforms have implemented RandenHwAes.
#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) || \ #if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) || \
defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \ defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \
defined(ABSL_ARCH_AARCH64) defined(ABSL_ARCH_AARCH64)

@ -689,13 +689,10 @@ void Cord::InlineRep::AppendArray(absl::string_view src,
return; return;
} }
// Note: we don't concern ourselves if src aliases data stored in the // Allocate flat to be a perfect fit on first append exceeding inlined size.
// inlined data of 'this', as we update the InlineData only at the end. // Subsequent growth will use amortized growth until we reach maximum flat
// We are going from an inline size to beyond inline size. Make the new size // size.
// either double the inlined size, or the added size + 10%. rep = CordRepFlat::New(inline_length + src.size());
const size_t size1 = inline_length * 2 + src.size();
const size_t size2 = inline_length + src.size() / 10;
rep = CordRepFlat::New(std::max<size_t>(size1, size2));
appended = std::min(src.size(), rep->flat()->Capacity() - inline_length); appended = std::min(src.size(), rep->flat()->Capacity() - inline_length);
memcpy(rep->flat()->Data(), data_.as_chars(), inline_length); memcpy(rep->flat()->Data(), data_.as_chars(), inline_length);
memcpy(rep->flat()->Data() + inline_length, src.data(), appended); memcpy(rep->flat()->Data() + inline_length, src.data(), appended);

@ -1385,6 +1385,59 @@ TEST_P(CordTest, DiabolicalGrowth) {
cord.EstimatedMemoryUsage()); cord.EstimatedMemoryUsage());
} }
// The following tests check support for >4GB cords in 64-bit binaries, and
// 2GB-4GB cords in 32-bit binaries. This function returns the large cord size
// that's appropriate for the binary.
// Construct a huge cord with the specified valid prefix.
static absl::Cord MakeHuge(absl::string_view prefix) {
absl::Cord cord;
if (sizeof(size_t) > 4) {
// In 64-bit binaries, test 64-bit Cord support.
const size_t size =
static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 314;
cord.Append(absl::MakeCordFromExternal(
absl::string_view(prefix.data(), size),
[](absl::string_view s) { DoNothing(s, nullptr); }));
} else {
// Cords are limited to 32-bit lengths in 32-bit binaries. The following
// tests check for use of "signed int" to represent Cord length/offset.
// However absl::string_view does not allow lengths >= (1u<<31), so we need
// to append in two parts;
const size_t s1 = (1u << 31) - 1;
// For shorter cord, `Append` copies the data rather than allocating a new
// node. The threshold is currently set to 511, so `s2` needs to be bigger
// to not trigger the copy.
const size_t s2 = 600;
cord.Append(absl::MakeCordFromExternal(
absl::string_view(prefix.data(), s1),
[](absl::string_view s) { DoNothing(s, nullptr); }));
cord.Append(absl::MakeCordFromExternal(
absl::string_view("", s2),
[](absl::string_view s) { DoNothing(s, nullptr); }));
}
return cord;
}
TEST_P(CordTest, HugeCord) {
absl::Cord cord = MakeHuge("huge cord");
EXPECT_LE(cord.size(), cord.EstimatedMemoryUsage());
EXPECT_GE(cord.size() + 100, cord.EstimatedMemoryUsage());
}
// Tests that Append() works ok when handed a self reference
TEST_P(CordTest, AppendSelf) {
// We run the test until data is ~16K
// This guarantees it covers small, medium and large data.
std::string control_data = "Abc";
absl::Cord data(control_data);
while (control_data.length() < 0x4000) {
data.Append(data);
control_data.append(control_data);
ASSERT_EQ(control_data, data);
}
}
TEST_P(CordTest, MakeFragmentedCordFromInitializerList) { TEST_P(CordTest, MakeFragmentedCordFromInitializerList) {
absl::Cord fragmented = absl::Cord fragmented =
absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"}); absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"});

@ -23,7 +23,6 @@
#include "absl/base/internal/raw_logging.h" #include "absl/base/internal/raw_logging.h"
#include "absl/base/optimization.h" #include "absl/base/optimization.h"
#include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_flat.h" #include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/types/span.h" #include "absl/types/span.h"

@ -100,7 +100,7 @@ class FormatSpecTemplate
// We use the 'unavailable' attribute to give a better compiler error than // We use the 'unavailable' attribute to give a better compiler error than
// just 'method is deleted'. // just 'method is deleted'.
// To avoid checking the format twice, we just check that the format is // To avoid checking the format twice, we just check that the format is
// constexpr. If is it valid, then the overload below will kick in. // constexpr. If it is valid, then the overload below will kick in.
// We add the template here to make this overload have lower priority. // We add the template here to make this overload have lower priority.
template <typename = void> template <typename = void>
FormatSpecTemplate(const char* s) // NOLINT FormatSpecTemplate(const char* s) // NOLINT

@ -95,6 +95,13 @@ def main(argv):
'datestamp={} is not in the YYYYMMDD format'.format(datestamp)) 'datestamp={} is not in the YYYYMMDD format'.format(datestamp))
# Replacement directives go here. # Replacement directives go here.
ReplaceStringsInFile(
'absl/base/config.h', {
'#undef ABSL_LTS_RELEASE_VERSION':
'#define ABSL_LTS_RELEASE_VERSION {}'.format(datestamp),
'#undef ABSL_LTS_RELEASE_PATCH_LEVEL':
'#define ABSL_LTS_RELEASE_PATCH_LEVEL 0'
})
ReplaceStringsInFile( ReplaceStringsInFile(
'absl/base/options.h', { 'absl/base/options.h', {
'#define ABSL_OPTION_USE_INLINE_NAMESPACE 0': '#define ABSL_OPTION_USE_INLINE_NAMESPACE 0':

Loading…
Cancel
Save