merge(3p/abseil_cpp): Merge upstream at 'ccdbb5941'
Change-Id: I6e85fc7b5f76bba1f1eef15e600a8acb64e97ef5
This commit is contained in:
commit
543379ce45
97 changed files with 3546 additions and 2316 deletions
65
third_party/abseil_cpp/absl/strings/cord.cc
vendored
65
third_party/abseil_cpp/absl/strings/cord.cc
vendored
|
|
@ -705,6 +705,37 @@ Cord::Cord(absl::string_view src) {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T, Cord::EnableIfString<T>>
|
||||
Cord::Cord(T&& src) {
|
||||
if (
|
||||
// String is short: copy data to avoid external block overhead.
|
||||
src.size() <= kMaxBytesToCopy ||
|
||||
// String is wasteful: copy data to avoid pinning too much unused memory.
|
||||
src.size() < src.capacity() / 2
|
||||
) {
|
||||
if (src.size() <= InlineRep::kMaxInline) {
|
||||
contents_.set_data(src.data(), src.size(), false);
|
||||
} else {
|
||||
contents_.set_tree(NewTree(src.data(), src.size(), 0));
|
||||
}
|
||||
} else {
|
||||
struct StringReleaser {
|
||||
void operator()(absl::string_view /* data */) {}
|
||||
std::string data;
|
||||
};
|
||||
const absl::string_view original_data = src;
|
||||
CordRepExternal* rep =
|
||||
static_cast<CordRepExternal*>(absl::cord_internal::NewExternalRep(
|
||||
original_data, StringReleaser{std::move(src)}));
|
||||
// Moving src may have invalidated its data pointer, so adjust it.
|
||||
rep->base =
|
||||
static_cast<StringReleaser*>(GetExternalReleaser(rep))->data.data();
|
||||
contents_.set_tree(rep);
|
||||
}
|
||||
}
|
||||
|
||||
template Cord::Cord(std::string&& src);
|
||||
|
||||
// The destruction code is separate so that the compiler can determine
|
||||
// that it does not need to call the destructor on a moved-from Cord.
|
||||
void Cord::DestroyCordSlow() {
|
||||
|
|
@ -742,6 +773,18 @@ Cord& Cord::operator=(absl::string_view src) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, Cord::EnableIfString<T>>
|
||||
Cord& Cord::operator=(T&& src) {
|
||||
if (src.size() <= kMaxBytesToCopy) {
|
||||
*this = absl::string_view(src);
|
||||
} else {
|
||||
*this = Cord(std::move(src));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template Cord& Cord::operator=(std::string&& src);
|
||||
|
||||
// TODO(sanjay): Move to Cord::InlineRep section of file. For now,
|
||||
// we keep it here to make diffs easier.
|
||||
void Cord::InlineRep::AppendArray(const char* src_data, size_t src_size) {
|
||||
|
|
@ -853,6 +896,17 @@ void Cord::Append(const Cord& src) { AppendImpl(src); }
|
|||
|
||||
void Cord::Append(Cord&& src) { AppendImpl(std::move(src)); }
|
||||
|
||||
template <typename T, Cord::EnableIfString<T>>
|
||||
void Cord::Append(T&& src) {
|
||||
if (src.size() <= kMaxBytesToCopy) {
|
||||
Append(absl::string_view(src));
|
||||
} else {
|
||||
Append(Cord(std::move(src)));
|
||||
}
|
||||
}
|
||||
|
||||
template void Cord::Append(std::string&& src);
|
||||
|
||||
void Cord::Prepend(const Cord& src) {
|
||||
CordRep* src_tree = src.contents_.tree();
|
||||
if (src_tree != nullptr) {
|
||||
|
|
@ -882,6 +936,17 @@ void Cord::Prepend(absl::string_view src) {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T, Cord::EnableIfString<T>>
|
||||
inline void Cord::Prepend(T&& src) {
|
||||
if (src.size() <= kMaxBytesToCopy) {
|
||||
Prepend(absl::string_view(src));
|
||||
} else {
|
||||
Prepend(Cord(std::move(src)));
|
||||
}
|
||||
}
|
||||
|
||||
template void Cord::Prepend(std::string&& src);
|
||||
|
||||
static CordRep* RemovePrefixFrom(CordRep* node, size_t n) {
|
||||
if (n >= node->length) return nullptr;
|
||||
if (n == 0) return Ref(node);
|
||||
|
|
|
|||
27
third_party/abseil_cpp/absl/strings/cord.h
vendored
27
third_party/abseil_cpp/absl/strings/cord.h
vendored
|
|
@ -147,11 +147,8 @@ class Cord {
|
|||
// Creates a Cord from a `std::string&&` rvalue. These constructors are
|
||||
// templated to avoid ambiguities for types that are convertible to both
|
||||
// `absl::string_view` and `std::string`, such as `const char*`.
|
||||
//
|
||||
// Note that these functions reserve the right to use the `string&&`'s
|
||||
// memory and that they will do so in the future.
|
||||
template <typename T, EnableIfString<T> = 0>
|
||||
explicit Cord(T&& src) : Cord(absl::string_view(src)) {}
|
||||
explicit Cord(T&& src);
|
||||
template <typename T, EnableIfString<T> = 0>
|
||||
Cord& operator=(T&& src);
|
||||
|
||||
|
|
@ -1048,11 +1045,8 @@ inline Cord& Cord::operator=(Cord&& x) noexcept {
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, Cord::EnableIfString<T>>
|
||||
inline Cord& Cord::operator=(T&& src) {
|
||||
*this = absl::string_view(src);
|
||||
return *this;
|
||||
}
|
||||
extern template Cord::Cord(std::string&& src);
|
||||
extern template Cord& Cord::operator=(std::string&& src);
|
||||
|
||||
inline size_t Cord::size() const {
|
||||
// Length is 1st field in str.rep_
|
||||
|
|
@ -1098,19 +1092,8 @@ inline void Cord::Append(absl::string_view src) {
|
|||
contents_.AppendArray(src.data(), src.size());
|
||||
}
|
||||
|
||||
template <typename T, Cord::EnableIfString<T>>
|
||||
inline void Cord::Append(T&& src) {
|
||||
// Note that this function reserves the right to reuse the `string&&`'s
|
||||
// memory and that it will do so in the future.
|
||||
Append(absl::string_view(src));
|
||||
}
|
||||
|
||||
template <typename T, Cord::EnableIfString<T>>
|
||||
inline void Cord::Prepend(T&& src) {
|
||||
// Note that this function reserves the right to reuse the `string&&`'s
|
||||
// memory and that it will do so in the future.
|
||||
Prepend(absl::string_view(src));
|
||||
}
|
||||
extern template void Cord::Append(std::string&& src);
|
||||
extern template void Cord::Prepend(std::string&& src);
|
||||
|
||||
inline int Cord::Compare(const Cord& rhs) const {
|
||||
if (!contents_.is_tree() && !rhs.contents_.is_tree()) {
|
||||
|
|
|
|||
|
|
@ -764,6 +764,12 @@ TEST_F(FormatConvertTest, LongDouble) {
|
|||
}
|
||||
}
|
||||
|
||||
// Regression tests
|
||||
//
|
||||
// Using a string literal because not all platforms support hex literals or it
|
||||
// might be out of range.
|
||||
doubles.push_back(std::strtold("-0xf.ffffffb5feafffbp-16324L", nullptr));
|
||||
|
||||
for (const char *fmt : kFormats) {
|
||||
for (char f : {'f', 'F', //
|
||||
'g', 'G', //
|
||||
|
|
|
|||
|
|
@ -224,13 +224,13 @@ class FractionalDigitGenerator {
|
|||
// This function will allocate enough stack space to perform the conversion.
|
||||
static void RunConversion(
|
||||
uint128 v, int exp, absl::FunctionRef<void(FractionalDigitGenerator)> f) {
|
||||
using Limits = std::numeric_limits<long double>;
|
||||
assert(-exp < 0);
|
||||
assert(-exp >= std::numeric_limits<long double>::min_exponent - 128);
|
||||
static_assert(
|
||||
StackArray::kMaxCapacity >=
|
||||
(128 - std::numeric_limits<long double>::min_exponent + 31) / 32,
|
||||
"");
|
||||
StackArray::RunWithCapacity((exp + 31) / 32,
|
||||
assert(-exp >= Limits::min_exponent - 128);
|
||||
static_assert(StackArray::kMaxCapacity >=
|
||||
(Limits::digits + 128 - Limits::min_exponent + 31) / 32,
|
||||
"");
|
||||
StackArray::RunWithCapacity((Limits::digits + exp + 31) / 32,
|
||||
[=](absl::Span<uint32_t> input) {
|
||||
f(FractionalDigitGenerator(input, v, exp));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
//
|
||||
// The `str_format` library is a typesafe replacement for the family of
|
||||
// `printf()` string formatting routines within the `<cstdio>` standard library
|
||||
// header. Like the `printf` family, the `str_format` uses a "format string" to
|
||||
// header. Like the `printf` family, `str_format` uses a "format string" to
|
||||
// perform argument substitutions based on types. See the `FormatSpec` section
|
||||
// below for format string documentation.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/cord.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
|
|
@ -353,6 +354,7 @@ TEST(StrFormat, BehavesAsDocumented) {
|
|||
EXPECT_EQ(StrFormat("%s", "C"), "C");
|
||||
EXPECT_EQ(StrFormat("%s", std::string("C++")), "C++");
|
||||
EXPECT_EQ(StrFormat("%s", string_view("view")), "view");
|
||||
EXPECT_EQ(StrFormat("%s", absl::Cord("cord")), "cord");
|
||||
// Integral Conversion
|
||||
// These format integral types: char, int, long, uint64_t, etc.
|
||||
EXPECT_EQ(StrFormat("%d", char{10}), "10");
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/base/macros.h"
|
||||
#include "absl/strings/internal/str_split_internal.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue