Commit 18045c4e by Abseil Team Committed by Dino Radaković

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
parent 7e8ec214
...@@ -132,9 +132,8 @@ static uintptr_t GetFP(const void *vuc) { ...@@ -132,9 +132,8 @@ static uintptr_t GetFP(const void *vuc) {
const uintptr_t bp = 0; const uintptr_t bp = 0;
const uintptr_t sp = 0; const uintptr_t sp = 0;
#endif #endif
// Sanity-check that the base pointer is valid. It should be as long as // Sanity-check that the base pointer is valid. It's possible that some
// SHRINK_WRAP_FRAME_POINTER is not set, but it's possible that some code in // code in the process is compiled with --copt=-fomit-frame-pointer or
// the process is compiled with --copt=-fomit-frame-pointer or
// --copt=-momit-leaf-frame-pointer. // --copt=-momit-leaf-frame-pointer.
// //
// TODO(bcmills): -momit-leaf-frame-pointer is currently the default // TODO(bcmills): -momit-leaf-frame-pointer is currently the default
...@@ -247,7 +246,7 @@ static void **NextStackFrame(void **old_fp, const void *uc) { ...@@ -247,7 +246,7 @@ static void **NextStackFrame(void **old_fp, const void *uc) {
// using an alternate signal stack. // using an alternate signal stack.
// //
// TODO(bcmills): The GetFP call should be completely unnecessary when // 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 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 // 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 // frames. Figure out why GetValidFrameAddr and/or libunwind isn't doing what
......
...@@ -230,7 +230,7 @@ using Hash = absl::hash_internal::Hash<T>; ...@@ -230,7 +230,7 @@ using Hash = absl::hash_internal::Hash<T>;
// The requirement that the arguments match in both type and value is critical. // 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 // 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)`. // `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) { size_t HashOf(const Types&... values) {
auto tuple = std::tie(values...); auto tuple = std::tie(values...);
return absl::Hash<decltype(tuple)>{}(tuple); return absl::Hash<decltype(tuple)>{}(tuple);
......
...@@ -995,4 +995,17 @@ TEST(HashOf, MatchesHashOfTupleForMultipleArguments) { ...@@ -995,4 +995,17 @@ TEST(HashOf, MatchesHashOfTupleForMultipleArguments) {
absl::HashOf(std::make_tuple(hello, world))); 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 } // namespace
...@@ -78,8 +78,8 @@ std::ostream& operator<<(std::ostream& o, string_view piece) { ...@@ -78,8 +78,8 @@ std::ostream& operator<<(std::ostream& o, string_view piece) {
return o; return o;
} }
string_view::size_type string_view::find(string_view s, size_type pos) const string_view::size_type string_view::find(string_view s,
noexcept { size_type pos) const noexcept {
if (empty() || pos > length_) { if (empty() || pos > length_) {
if (empty() && pos == 0 && s.empty()) return 0; if (empty() && pos == 0 && s.empty()) return 0;
return npos; return npos;
...@@ -98,8 +98,8 @@ string_view::size_type string_view::find(char c, size_type pos) const noexcept { ...@@ -98,8 +98,8 @@ string_view::size_type string_view::find(char c, size_type pos) const noexcept {
return result != nullptr ? result - ptr_ : npos; return result != nullptr ? result - ptr_ : npos;
} }
string_view::size_type string_view::rfind(string_view s, size_type pos) const string_view::size_type string_view::rfind(string_view s,
noexcept { size_type pos) const noexcept {
if (length_ < s.length_) return npos; if (length_ < s.length_) return npos;
if (s.empty()) return std::min(length_, pos); if (s.empty()) return std::min(length_, pos);
const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_; 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 ...@@ -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. // Search range is [0..pos] inclusive. If pos == npos, search everything.
string_view::size_type string_view::rfind(char c, size_type pos) const string_view::size_type string_view::rfind(char c,
noexcept { size_type pos) const noexcept {
// Note: memrchr() is not available on Windows. // Note: memrchr() is not available on Windows.
if (empty()) return npos; if (empty()) return npos;
for (size_type i = std::min(pos, length_ - 1);; --i) { 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 ...@@ -121,9 +121,8 @@ string_view::size_type string_view::rfind(char c, size_type pos) const
return npos; return npos;
} }
string_view::size_type string_view::find_first_of(string_view s, string_view::size_type string_view::find_first_of(
size_type pos) const string_view s, size_type pos) const noexcept {
noexcept {
if (empty() || s.empty()) { if (empty() || s.empty()) {
return npos; return npos;
} }
...@@ -138,9 +137,8 @@ string_view::size_type string_view::find_first_of(string_view s, ...@@ -138,9 +137,8 @@ string_view::size_type string_view::find_first_of(string_view s,
return npos; return npos;
} }
string_view::size_type string_view::find_first_not_of(string_view s, string_view::size_type string_view::find_first_not_of(
size_type pos) const string_view s, size_type pos) const noexcept {
noexcept {
if (empty()) return npos; if (empty()) return npos;
// Avoid the cost of LookupTable() for a single-character search. // Avoid the cost of LookupTable() for a single-character search.
if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos); 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, ...@@ -153,9 +151,8 @@ string_view::size_type string_view::find_first_not_of(string_view s,
return npos; return npos;
} }
string_view::size_type string_view::find_first_not_of(char c, string_view::size_type string_view::find_first_not_of(
size_type pos) const char c, size_type pos) const noexcept {
noexcept {
if (empty()) return npos; if (empty()) return npos;
for (; pos < length_; ++pos) { for (; pos < length_; ++pos) {
if (ptr_[pos] != c) { if (ptr_[pos] != c) {
...@@ -180,9 +177,8 @@ string_view::size_type string_view::find_last_of(string_view s, ...@@ -180,9 +177,8 @@ string_view::size_type string_view::find_last_of(string_view s,
return npos; return npos;
} }
string_view::size_type string_view::find_last_not_of(string_view s, string_view::size_type string_view::find_last_not_of(
size_type pos) const string_view s, size_type pos) const noexcept {
noexcept {
if (empty()) return npos; if (empty()) return npos;
size_type i = std::min(pos, length_ - 1); size_type i = std::min(pos, length_ - 1);
if (s.empty()) return i; if (s.empty()) return i;
...@@ -198,9 +194,8 @@ string_view::size_type string_view::find_last_not_of(string_view s, ...@@ -198,9 +194,8 @@ string_view::size_type string_view::find_last_not_of(string_view s,
return npos; return npos;
} }
string_view::size_type string_view::find_last_not_of(char c, string_view::size_type string_view::find_last_not_of(
size_type pos) const char c, size_type pos) const noexcept {
noexcept {
if (empty()) return npos; if (empty()) return npos;
size_type i = std::min(pos, length_ - 1); size_type i = std::min(pos, length_ - 1);
for (;; --i) { for (;; --i) {
......
...@@ -62,6 +62,12 @@ ABSL_NAMESPACE_END ...@@ -62,6 +62,12 @@ ABSL_NAMESPACE_END
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp #define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp
#endif // ABSL_HAVE_BUILTIN(__builtin_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 { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
...@@ -265,9 +271,7 @@ class string_view { ...@@ -265,9 +271,7 @@ class string_view {
// string_view::size() // string_view::size()
// //
// Returns the number of characters in the `string_view`. // Returns the number of characters in the `string_view`.
constexpr size_type size() const noexcept { constexpr size_type size() const noexcept { return length_; }
return length_;
}
// string_view::length() // string_view::length()
// //
...@@ -334,7 +338,7 @@ class string_view { ...@@ -334,7 +338,7 @@ class string_view {
// //
// Removes the first `n` characters from the `string_view`. Note that the // Removes the first `n` characters from the `string_view`. Note that the
// underlying string is not changed, only the view. // 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_); ABSL_HARDENING_ASSERT(n <= length_);
ptr_ += n; ptr_ += n;
length_ -= n; length_ -= n;
...@@ -344,7 +348,7 @@ class string_view { ...@@ -344,7 +348,7 @@ class string_view {
// //
// Removes the last `n` characters from the `string_view`. Note that the // Removes the last `n` characters from the `string_view`. Note that the
// underlying string is not changed, only the view. // 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_); ABSL_HARDENING_ASSERT(n <= length_);
length_ -= n; length_ -= n;
} }
...@@ -352,7 +356,7 @@ class string_view { ...@@ -352,7 +356,7 @@ class string_view {
// string_view::swap() // string_view::swap()
// //
// Swaps this `string_view` with another `string_view`. // 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; auto t = *this;
*this = s; *this = s;
s = t; s = t;
...@@ -389,7 +393,7 @@ class string_view { ...@@ -389,7 +393,7 @@ class string_view {
// `n`) as another string_view. This function throws `std::out_of_bounds` if // `n`) as another string_view. This function throws `std::out_of_bounds` if
// `pos > size`. // `pos > size`.
// Use absl::ClippedSubstr if you need a truncating substr operation. // 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_) return ABSL_PREDICT_FALSE(pos > length_)
? (base_internal::ThrowStdOutOfRange( ? (base_internal::ThrowStdOutOfRange(
"absl::string_view::substr"), "absl::string_view::substr"),
...@@ -413,31 +417,31 @@ class string_view { ...@@ -413,31 +417,31 @@ class string_view {
// Overload of `string_view::compare()` for comparing a substring of the // Overload of `string_view::compare()` for comparing a substring of the
// 'string_view` and another `absl::string_view`. // '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); return substr(pos1, count1).compare(v);
} }
// Overload of `string_view::compare()` for comparing a substring of the // Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a substring of another `absl::string_view`. // `string_view` and a substring of another `absl::string_view`.
int compare(size_type pos1, size_type count1, string_view v, size_type pos2, constexpr int compare(size_type pos1, size_type count1, string_view v,
size_type count2) const { size_type pos2, size_type count2) const {
return substr(pos1, count1).compare(v.substr(pos2, count2)); return substr(pos1, count1).compare(v.substr(pos2, count2));
} }
// Overload of `string_view::compare()` for comparing a `string_view` and a // Overload of `string_view::compare()` for comparing a `string_view` and a
// a different C-style string `s`. // a different C-style string `s`.
int compare(const char* s) const { return compare(string_view(s)); } constexpr int compare(const char* s) const { return compare(string_view(s)); }
// Overload of `string_view::compare()` for comparing a substring of the // Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a different string C-style string `s`. // `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)); return substr(pos1, count1).compare(string_view(s));
} }
// Overload of `string_view::compare()` for comparing a substring of the // Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a substring of a different C-style string `s`. // `string_view` and a substring of a different C-style string `s`.
int compare(size_type pos1, size_type count1, const char* s, constexpr int compare(size_type pos1, size_type count1, const char* s,
size_type count2) const { size_type count2) const {
return substr(pos1, count1).compare(string_view(s, count2)); return substr(pos1, count1).compare(string_view(s, count2));
} }
...@@ -454,48 +458,92 @@ class string_view { ...@@ -454,48 +458,92 @@ class string_view {
// within the `string_view`. // within the `string_view`.
size_type find(char c, size_type pos = 0) const noexcept; 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() // string_view::rfind()
// //
// Finds the last occurrence of a substring `s` within the `string_view`, // 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 // returning the position of the first character's match, or `npos` if no
// match was found. // match was found.
size_type rfind(string_view s, size_type pos = npos) const size_type rfind(string_view s, size_type pos = npos) const noexcept;
noexcept;
// Overload of `string_view::rfind()` for finding the last given character `c` // Overload of `string_view::rfind()` for finding the last given character `c`
// within the `string_view`. // within the `string_view`.
size_type rfind(char c, size_type pos = npos) const noexcept; 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() // string_view::find_first_of()
// //
// Finds the first occurrence of any of the characters in `s` within the // 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 // `string_view`, returning the start position of the match, or `npos` if no
// match was found. // match was found.
size_type find_first_of(string_view s, size_type pos = 0) const size_type find_first_of(string_view s, size_type pos = 0) const noexcept;
noexcept;
// Overload of `string_view::find_first_of()` for finding a character `c` // Overload of `string_view::find_first_of()` for finding a character `c`
// within the `string_view`. // within the `string_view`.
size_type find_first_of(char c, size_type pos = 0) const size_type find_first_of(char c, size_type pos = 0) const noexcept {
noexcept {
return find(c, pos); 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() // string_view::find_last_of()
// //
// Finds the last occurrence of any of the characters in `s` within the // 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 // `string_view`, returning the start position of the match, or `npos` if no
// match was found. // match was found.
size_type find_last_of(string_view s, size_type pos = npos) const size_type find_last_of(string_view s, size_type pos = npos) const noexcept;
noexcept;
// Overload of `string_view::find_last_of()` for finding a character `c` // Overload of `string_view::find_last_of()` for finding a character `c`
// within the `string_view`. // within the `string_view`.
size_type find_last_of(char c, size_type pos = npos) const size_type find_last_of(char c, size_type pos = npos) const noexcept {
noexcept {
return rfind(c, pos); 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() // string_view::find_first_not_of()
// //
// Finds the first occurrence of any of the characters not in `s` within the // Finds the first occurrence of any of the characters not in `s` within the
...@@ -507,18 +555,43 @@ class string_view { ...@@ -507,18 +555,43 @@ class string_view {
// that is not `c` within the `string_view`. // that is not `c` within the `string_view`.
size_type find_first_not_of(char c, size_type pos = 0) const noexcept; 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() // string_view::find_last_not_of()
// //
// Finds the last occurrence of any of the characters not in `s` within the // 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 // `string_view`, returning the start position of the last non-match, or
// `npos` if no non-match was found. // `npos` if no non-match was found.
size_type find_last_not_of(string_view s, 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 // Overload of `string_view::find_last_not_of()` for finding a character
// that is not `c` within the `string_view`. // that is not `c` within the `string_view`.
size_type find_last_not_of(char c, size_type pos = npos) const size_type find_last_not_of(char c, size_type pos = npos) const noexcept;
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: private:
static constexpr size_type kMaxSize = static constexpr size_type kMaxSize =
...@@ -596,6 +669,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece); ...@@ -596,6 +669,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece);
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
} // namespace absl } // namespace absl
#undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR
#undef ABSL_INTERNAL_STRING_VIEW_MEMCMP #undef ABSL_INTERNAL_STRING_VIEW_MEMCMP
#endif // ABSL_USES_STD_STRING_VIEW #endif // ABSL_USES_STD_STRING_VIEW
......
...@@ -449,6 +449,24 @@ TEST(StringViewTest, STL2) { ...@@ -449,6 +449,24 @@ TEST(StringViewTest, STL2) {
EXPECT_EQ(d.find('x', 4), absl::string_view::npos); EXPECT_EQ(d.find('x', 4), absl::string_view::npos);
EXPECT_EQ(e.find('x', 7), 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), 0);
EXPECT_EQ(a.rfind(b, 1), 0); EXPECT_EQ(a.rfind(b, 1), 0);
EXPECT_EQ(a.rfind(c), 23); EXPECT_EQ(a.rfind(c), 23);
...@@ -490,6 +508,14 @@ TEST(StringViewTest, STL2) { ...@@ -490,6 +508,14 @@ TEST(StringViewTest, STL2) {
EXPECT_EQ(e.rfind('o'), absl::string_view::npos); EXPECT_EQ(e.rfind('o'), absl::string_view::npos);
EXPECT_EQ(d.rfind('o', 4), 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(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 // Continued from STL2
...@@ -678,6 +704,7 @@ TEST(StringViewTest, STL2Substr) { ...@@ -678,6 +704,7 @@ TEST(StringViewTest, STL2Substr) {
EXPECT_EQ(a.substr(23, 3), c); EXPECT_EQ(a.substr(23, 3), c);
EXPECT_EQ(a.substr(23, 99), c); EXPECT_EQ(a.substr(23, 99), c);
EXPECT_EQ(a.substr(0), a); EXPECT_EQ(a.substr(0), a);
EXPECT_EQ(a.substr(), a);
EXPECT_EQ(a.substr(3, 2), "de"); EXPECT_EQ(a.substr(3, 2), "de");
// empty string nonsense // empty string nonsense
EXPECT_EQ(d.substr(0, 99), e); EXPECT_EQ(d.substr(0, 99), e);
...@@ -1087,7 +1114,24 @@ TEST(StringViewTest, ConstexprCompiles) { ...@@ -1087,7 +1114,24 @@ TEST(StringViewTest, ConstexprCompiles) {
EXPECT_EQ(sp_npos, -1); 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 foobar("foobar", 6);
constexpr absl::string_view foo = foobar.substr(0, 3); constexpr absl::string_view foo = foobar.substr(0, 3);
constexpr absl::string_view bar = foobar.substr(3); constexpr absl::string_view bar = foobar.substr(3);
......
...@@ -16,6 +16,6 @@ ...@@ -16,6 +16,6 @@
# Test scripts should source this file to get the identifiers. # Test scripts should source this file to get the identifiers.
readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20201026" 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_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:20201008" 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" readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20201015"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment