Export of internal Abseil changes

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

Internal change

PiperOrigin-RevId: 375779441

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

Internal change

PiperOrigin-RevId: 375520720

--
46857d17d4dbc6fbd13a27dd82e14ec814dd117a by Samuel Benzaquen <sbenza@google.com>:

Add an explicit template parameter barrier to absl::HashOf.

PiperOrigin-RevId: 375103300

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

Improve string_view API compliance with C++17 std::basic_string_view.

This adds missing overloads, default values, and constexpr specifiers.

PiperOrigin-RevId: 374885658

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

Update CI to GCC 11.1, Bazel 4.0.0, CMake 3.20.2, and
LLVM git:7bcc0a1e399d461af7ec013ff33bc330a2de6641

PiperOrigin-RevId: 374858288
GitOrigin-RevId: d74f30ef0da7139c30a24eb6c1776bc0c257e642
Change-Id: I657c815c83522b030495ff54ca327e7012ed151e
pull/969/head
Abseil Team 4 years ago committed by Dino Radaković
parent 7e8ec214f2
commit 18045c4e32
  1. 7
      absl/debugging/internal/stacktrace_x86-inl.inc
  2. 2
      absl/hash/hash.h
  3. 13
      absl/hash/hash_test.cc
  4. 37
      absl/strings/string_view.cc
  5. 130
      absl/strings/string_view.h
  6. 46
      absl/strings/string_view_test.cc
  7. 4
      ci/linux_docker_containers.sh

@ -132,9 +132,8 @@ static uintptr_t GetFP(const void *vuc) {
const uintptr_t bp = 0;
const uintptr_t sp = 0;
#endif
// Sanity-check that the base pointer is valid. It should be as long as
// SHRINK_WRAP_FRAME_POINTER is not set, but it's possible that some code in
// the process is compiled with --copt=-fomit-frame-pointer or
// Sanity-check that the base pointer is valid. It's possible that some
// code in the process is compiled with --copt=-fomit-frame-pointer or
// --copt=-momit-leaf-frame-pointer.
//
// TODO(bcmills): -momit-leaf-frame-pointer is currently the default
@ -247,7 +246,7 @@ static void **NextStackFrame(void **old_fp, const void *uc) {
// using an alternate signal stack.
//
// TODO(bcmills): The GetFP call should be completely unnecessary when
// SHRINK_WRAP_FRAME_POINTER is set (because we should be back in the thread's
// ENABLE_COMBINED_UNWINDER is set (because we should be back in the thread's
// stack by this point), but it is empirically still needed (e.g. when the
// stack includes a call to abort). unw_get_reg returns UNW_EBADREG for some
// frames. Figure out why GetValidFrameAddr and/or libunwind isn't doing what

@ -230,7 +230,7 @@ using Hash = absl::hash_internal::Hash<T>;
// The requirement that the arguments match in both type and value is critical.
// It means that `a == b` does not necessarily imply `HashOf(a) == HashOf(b)` if
// `a` and `b` have different types. For example, `HashOf(2) != HashOf(2.0)`.
template <typename... Types>
template <int&... ExplicitArgumentBarrier, typename... Types>
size_t HashOf(const Types&... values) {
auto tuple = std::tie(values...);
return absl::Hash<decltype(tuple)>{}(tuple);

@ -995,4 +995,17 @@ TEST(HashOf, MatchesHashOfTupleForMultipleArguments) {
absl::HashOf(std::make_tuple(hello, world)));
}
template <typename T>
std::true_type HashOfExplicitParameter(decltype(absl::HashOf<T>(0))) {
return {};
}
template <typename T>
std::false_type HashOfExplicitParameter(size_t) {
return {};
}
TEST(HashOf, CantPassExplicitTemplateParameters) {
EXPECT_FALSE(HashOfExplicitParameter<int>(0));
}
} // namespace

@ -78,8 +78,8 @@ std::ostream& operator<<(std::ostream& o, string_view piece) {
return o;
}
string_view::size_type string_view::find(string_view s, size_type pos) const
noexcept {
string_view::size_type string_view::find(string_view s,
size_type pos) const noexcept {
if (empty() || pos > length_) {
if (empty() && pos == 0 && s.empty()) return 0;
return npos;
@ -98,8 +98,8 @@ string_view::size_type string_view::find(char c, size_type pos) const noexcept {
return result != nullptr ? result - ptr_ : npos;
}
string_view::size_type string_view::rfind(string_view s, size_type pos) const
noexcept {
string_view::size_type string_view::rfind(string_view s,
size_type pos) const noexcept {
if (length_ < s.length_) return npos;
if (s.empty()) return std::min(length_, pos);
const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_;
@ -108,8 +108,8 @@ string_view::size_type string_view::rfind(string_view s, size_type pos) const
}
// Search range is [0..pos] inclusive. If pos == npos, search everything.
string_view::size_type string_view::rfind(char c, size_type pos) const
noexcept {
string_view::size_type string_view::rfind(char c,
size_type pos) const noexcept {
// Note: memrchr() is not available on Windows.
if (empty()) return npos;
for (size_type i = std::min(pos, length_ - 1);; --i) {
@ -121,9 +121,8 @@ string_view::size_type string_view::rfind(char c, size_type pos) const
return npos;
}
string_view::size_type string_view::find_first_of(string_view s,
size_type pos) const
noexcept {
string_view::size_type string_view::find_first_of(
string_view s, size_type pos) const noexcept {
if (empty() || s.empty()) {
return npos;
}
@ -138,9 +137,8 @@ string_view::size_type string_view::find_first_of(string_view s,
return npos;
}
string_view::size_type string_view::find_first_not_of(string_view s,
size_type pos) const
noexcept {
string_view::size_type string_view::find_first_not_of(
string_view s, size_type pos) const noexcept {
if (empty()) return npos;
// Avoid the cost of LookupTable() for a single-character search.
if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos);
@ -153,9 +151,8 @@ string_view::size_type string_view::find_first_not_of(string_view s,
return npos;
}
string_view::size_type string_view::find_first_not_of(char c,
size_type pos) const
noexcept {
string_view::size_type string_view::find_first_not_of(
char c, size_type pos) const noexcept {
if (empty()) return npos;
for (; pos < length_; ++pos) {
if (ptr_[pos] != c) {
@ -180,9 +177,8 @@ string_view::size_type string_view::find_last_of(string_view s,
return npos;
}
string_view::size_type string_view::find_last_not_of(string_view s,
size_type pos) const
noexcept {
string_view::size_type string_view::find_last_not_of(
string_view s, size_type pos) const noexcept {
if (empty()) return npos;
size_type i = std::min(pos, length_ - 1);
if (s.empty()) return i;
@ -198,9 +194,8 @@ string_view::size_type string_view::find_last_not_of(string_view s,
return npos;
}
string_view::size_type string_view::find_last_not_of(char c,
size_type pos) const
noexcept {
string_view::size_type string_view::find_last_not_of(
char c, size_type pos) const noexcept {
if (empty()) return npos;
size_type i = std::min(pos, length_ - 1);
for (;; --i) {

@ -62,6 +62,12 @@ ABSL_NAMESPACE_END
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp
#endif // ABSL_HAVE_BUILTIN(__builtin_memcmp)
#if defined(__cplusplus) && __cplusplus >= 201402L
#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR constexpr
#else
#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR
#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
@ -265,9 +271,7 @@ class string_view {
// string_view::size()
//
// Returns the number of characters in the `string_view`.
constexpr size_type size() const noexcept {
return length_;
}
constexpr size_type size() const noexcept { return length_; }
// string_view::length()
//
@ -334,7 +338,7 @@ class string_view {
//
// Removes the first `n` characters from the `string_view`. Note that the
// underlying string is not changed, only the view.
void remove_prefix(size_type n) {
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n) {
ABSL_HARDENING_ASSERT(n <= length_);
ptr_ += n;
length_ -= n;
@ -344,7 +348,7 @@ class string_view {
//
// Removes the last `n` characters from the `string_view`. Note that the
// underlying string is not changed, only the view.
void remove_suffix(size_type n) {
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_suffix(size_type n) {
ABSL_HARDENING_ASSERT(n <= length_);
length_ -= n;
}
@ -352,7 +356,7 @@ class string_view {
// string_view::swap()
//
// Swaps this `string_view` with another `string_view`.
void swap(string_view& s) noexcept {
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void swap(string_view& s) noexcept {
auto t = *this;
*this = s;
s = t;
@ -389,7 +393,7 @@ class string_view {
// `n`) as another string_view. This function throws `std::out_of_bounds` if
// `pos > size`.
// Use absl::ClippedSubstr if you need a truncating substr operation.
constexpr string_view substr(size_type pos, size_type n = npos) const {
constexpr string_view substr(size_type pos = 0, size_type n = npos) const {
return ABSL_PREDICT_FALSE(pos > length_)
? (base_internal::ThrowStdOutOfRange(
"absl::string_view::substr"),
@ -413,31 +417,31 @@ class string_view {
// Overload of `string_view::compare()` for comparing a substring of the
// 'string_view` and another `absl::string_view`.
int compare(size_type pos1, size_type count1, string_view v) const {
constexpr int compare(size_type pos1, size_type count1, string_view v) const {
return substr(pos1, count1).compare(v);
}
// Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a substring of another `absl::string_view`.
int compare(size_type pos1, size_type count1, string_view v, size_type pos2,
size_type count2) const {
constexpr int compare(size_type pos1, size_type count1, string_view v,
size_type pos2, size_type count2) const {
return substr(pos1, count1).compare(v.substr(pos2, count2));
}
// Overload of `string_view::compare()` for comparing a `string_view` and a
// a different C-style string `s`.
int compare(const char* s) const { return compare(string_view(s)); }
// a different C-style string `s`.
constexpr int compare(const char* s) const { return compare(string_view(s)); }
// Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a different string C-style string `s`.
int compare(size_type pos1, size_type count1, const char* s) const {
constexpr int compare(size_type pos1, size_type count1, const char* s) const {
return substr(pos1, count1).compare(string_view(s));
}
// Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a substring of a different C-style string `s`.
int compare(size_type pos1, size_type count1, const char* s,
size_type count2) const {
constexpr int compare(size_type pos1, size_type count1, const char* s,
size_type count2) const {
return substr(pos1, count1).compare(string_view(s, count2));
}
@ -454,48 +458,92 @@ class string_view {
// within the `string_view`.
size_type find(char c, size_type pos = 0) const noexcept;
// Overload of `string_view::find()` for finding a substring of a different
// C-style string `s` within the `string_view`.
size_type find(const char* s, size_type pos, size_type count) const {
return find(string_view(s, count), pos);
}
// Overload of `string_view::find()` for finding a different C-style string
// `s` within the `string_view`.
size_type find(const char* s, size_type pos = 0) const {
return find(string_view(s), pos);
}
// string_view::rfind()
//
// Finds the last occurrence of a substring `s` within the `string_view`,
// returning the position of the first character's match, or `npos` if no
// match was found.
size_type rfind(string_view s, size_type pos = npos) const
noexcept;
size_type rfind(string_view s, size_type pos = npos) const noexcept;
// Overload of `string_view::rfind()` for finding the last given character `c`
// within the `string_view`.
size_type rfind(char c, size_type pos = npos) const noexcept;
// Overload of `string_view::rfind()` for finding a substring of a different
// C-style string `s` within the `string_view`.
size_type rfind(const char* s, size_type pos, size_type count) const {
return rfind(string_view(s, count), pos);
}
// Overload of `string_view::rfind()` for finding a different C-style string
// `s` within the `string_view`.
size_type rfind(const char* s, size_type pos = npos) const {
return rfind(string_view(s), pos);
}
// string_view::find_first_of()
//
// Finds the first occurrence of any of the characters in `s` within the
// `string_view`, returning the start position of the match, or `npos` if no
// match was found.
size_type find_first_of(string_view s, size_type pos = 0) const
noexcept;
size_type find_first_of(string_view s, size_type pos = 0) const noexcept;
// Overload of `string_view::find_first_of()` for finding a character `c`
// within the `string_view`.
size_type find_first_of(char c, size_type pos = 0) const
noexcept {
size_type find_first_of(char c, size_type pos = 0) const noexcept {
return find(c, pos);
}
// Overload of `string_view::find_first_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
size_type find_first_of(const char* s, size_type pos,
size_type count) const {
return find_first_of(string_view(s, count), pos);
}
// Overload of `string_view::find_first_of()` for finding a different C-style
// string `s` within the `string_view`.
size_type find_first_of(const char* s, size_type pos = 0) const {
return find_first_of(string_view(s), pos);
}
// string_view::find_last_of()
//
// Finds the last occurrence of any of the characters in `s` within the
// `string_view`, returning the start position of the match, or `npos` if no
// match was found.
size_type find_last_of(string_view s, size_type pos = npos) const
noexcept;
size_type find_last_of(string_view s, size_type pos = npos) const noexcept;
// Overload of `string_view::find_last_of()` for finding a character `c`
// within the `string_view`.
size_type find_last_of(char c, size_type pos = npos) const
noexcept {
size_type find_last_of(char c, size_type pos = npos) const noexcept {
return rfind(c, pos);
}
// Overload of `string_view::find_last_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
size_type find_last_of(const char* s, size_type pos, size_type count) const {
return find_last_of(string_view(s, count), pos);
}
// Overload of `string_view::find_last_of()` for finding a different C-style
// string `s` within the `string_view`.
size_type find_last_of(const char* s, size_type pos = npos) const {
return find_last_of(string_view(s), pos);
}
// string_view::find_first_not_of()
//
// Finds the first occurrence of any of the characters not in `s` within the
@ -507,18 +555,43 @@ class string_view {
// that is not `c` within the `string_view`.
size_type find_first_not_of(char c, size_type pos = 0) const noexcept;
// Overload of `string_view::find_first_not_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
size_type find_first_not_of(const char* s, size_type pos,
size_type count) const {
return find_first_not_of(string_view(s, count), pos);
}
// Overload of `string_view::find_first_not_of()` for finding a different
// C-style string `s` within the `string_view`.
size_type find_first_not_of(const char* s, size_type pos = 0) const {
return find_first_not_of(string_view(s), pos);
}
// string_view::find_last_not_of()
//
// Finds the last occurrence of any of the characters not in `s` within the
// `string_view`, returning the start position of the last non-match, or
// `npos` if no non-match was found.
size_type find_last_not_of(string_view s,
size_type pos = npos) const noexcept;
size_type pos = npos) const noexcept;
// Overload of `string_view::find_last_not_of()` for finding a character
// that is not `c` within the `string_view`.
size_type find_last_not_of(char c, size_type pos = npos) const
noexcept;
size_type find_last_not_of(char c, size_type pos = npos) const noexcept;
// Overload of `string_view::find_last_not_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
size_type find_last_not_of(const char* s, size_type pos,
size_type count) const {
return find_last_not_of(string_view(s, count), pos);
}
// Overload of `string_view::find_last_not_of()` for finding a different
// C-style string `s` within the `string_view`.
size_type find_last_not_of(const char* s, size_type pos = npos) const {
return find_last_not_of(string_view(s), pos);
}
private:
static constexpr size_type kMaxSize =
@ -596,6 +669,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece);
ABSL_NAMESPACE_END
} // namespace absl
#undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR
#undef ABSL_INTERNAL_STRING_VIEW_MEMCMP
#endif // ABSL_USES_STD_STRING_VIEW

@ -449,6 +449,24 @@ TEST(StringViewTest, STL2) {
EXPECT_EQ(d.find('x', 4), absl::string_view::npos);
EXPECT_EQ(e.find('x', 7), absl::string_view::npos);
EXPECT_EQ(a.find(b.data(), 1, 0), 1);
EXPECT_EQ(a.find(c.data(), 9, 0), 9);
EXPECT_EQ(a.find(c.data(), absl::string_view::npos, 0),
absl::string_view::npos);
EXPECT_EQ(b.find(c.data(), absl::string_view::npos, 0),
absl::string_view::npos);
// empty string nonsense
EXPECT_EQ(d.find(b.data(), 4, 0), absl::string_view::npos);
EXPECT_EQ(e.find(b.data(), 7, 0), absl::string_view::npos);
EXPECT_EQ(a.find(b.data(), 1), absl::string_view::npos);
EXPECT_EQ(a.find(c.data(), 9), 23);
EXPECT_EQ(a.find(c.data(), absl::string_view::npos), absl::string_view::npos);
EXPECT_EQ(b.find(c.data(), absl::string_view::npos), absl::string_view::npos);
// empty string nonsense
EXPECT_EQ(d.find(b.data(), 4), absl::string_view::npos);
EXPECT_EQ(e.find(b.data(), 7), absl::string_view::npos);
EXPECT_EQ(a.rfind(b), 0);
EXPECT_EQ(a.rfind(b, 1), 0);
EXPECT_EQ(a.rfind(c), 23);
@ -490,6 +508,14 @@ TEST(StringViewTest, STL2) {
EXPECT_EQ(e.rfind('o'), absl::string_view::npos);
EXPECT_EQ(d.rfind('o', 4), absl::string_view::npos);
EXPECT_EQ(e.rfind('o', 7), absl::string_view::npos);
EXPECT_EQ(a.rfind(b.data(), 1, 0), 1);
EXPECT_EQ(a.rfind(c.data(), 22, 0), 22);
EXPECT_EQ(a.rfind(c.data(), 1, 0), 1);
EXPECT_EQ(a.rfind(c.data(), 0, 0), 0);
EXPECT_EQ(b.rfind(c.data(), 0, 0), 0);
EXPECT_EQ(d.rfind(b.data(), 4, 0), 0);
EXPECT_EQ(e.rfind(b.data(), 7, 0), 0);
}
// Continued from STL2
@ -678,6 +704,7 @@ TEST(StringViewTest, STL2Substr) {
EXPECT_EQ(a.substr(23, 3), c);
EXPECT_EQ(a.substr(23, 99), c);
EXPECT_EQ(a.substr(0), a);
EXPECT_EQ(a.substr(), a);
EXPECT_EQ(a.substr(3, 2), "de");
// empty string nonsense
EXPECT_EQ(d.substr(0, 99), e);
@ -1087,7 +1114,24 @@ TEST(StringViewTest, ConstexprCompiles) {
EXPECT_EQ(sp_npos, -1);
}
TEST(StringViewTest, ConstexprSubstr) {
constexpr char ConstexprMethodsHelper() {
#if defined(__cplusplus) && __cplusplus >= 201402L
absl::string_view str("123", 3);
str.remove_prefix(1);
str.remove_suffix(1);
absl::string_view bar;
str.swap(bar);
return bar.front();
#else
return '2';
#endif
}
TEST(StringViewTest, ConstexprMethods) {
// remove_prefix, remove_suffix, swap
static_assert(ConstexprMethodsHelper() == '2', "");
// substr
constexpr absl::string_view foobar("foobar", 6);
constexpr absl::string_view foo = foobar.substr(0, 3);
constexpr absl::string_view bar = foobar.substr(3);

@ -16,6 +16,6 @@
# Test scripts should source this file to get the identifiers.
readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20201026"
readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20201008"
readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20201008"
readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20210519"
readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20210519"
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20201015"

Loading…
Cancel
Save