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. 181
      absl/container/inlined_vector.h
  7. 707
      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)
target_link_libraries(simple absl::strings)
target_link_libraries(simple absl::strings absl::config)

@ -14,8 +14,17 @@
// limitations under the License.
#include <iostream>
#include "absl/base/config.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) {
for (int i = 0; i < argc; ++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.
* [`numeric`](absl/numeric/)
<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/)
<br /> The `status` contains abstractions for error handling, specifically
`absl::Status` and `absl::StatusOr<T>`.

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

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

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
// will contain stubs that exit the process.
#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) || \
defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \
defined(ABSL_ARCH_AARCH64)

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

@ -1385,6 +1385,59 @@ TEST_P(CordTest, DiabolicalGrowth) {
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) {
absl::Cord fragmented =
absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"});

@ -23,7 +23,6 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/base/optimization.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/string_view.h"
#include "absl/types/span.h"

@ -100,7 +100,7 @@ class FormatSpecTemplate
// We use the 'unavailable' attribute to give a better compiler error than
// just 'method is deleted'.
// 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.
template <typename = void>
FormatSpecTemplate(const char* s) // NOLINT

@ -95,6 +95,13 @@ def main(argv):
'datestamp={} is not in the YYYYMMDD format'.format(datestamp))
# 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(
'absl/base/options.h', {
'#define ABSL_OPTION_USE_INLINE_NAMESPACE 0':

Loading…
Cancel
Save