summaryrefslogtreecommitdiff
path: root/absl/strings
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-05-25 13:13:33 -0700
committerGravatar Dino Radaković <dinor@google.com>2021-05-25 13:18:25 -0700
commit18045c4e32cbe6217224f46261b9e2607d6e723d (patch)
tree79e3a874888d298b317e4111e342815a30272577 /absl/strings
parent7e8ec214f2ceb949ad8ad33d83c194de3028ae55 (diff)
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
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/string_view.cc37
-rw-r--r--absl/strings/string_view.h130
-rw-r--r--absl/strings/string_view_test.cc46
3 files changed, 163 insertions, 50 deletions
diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc
index c5f5de93..d596e08c 100644
--- a/absl/strings/string_view.cc
+++ b/absl/strings/string_view.cc
@@ -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) {
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index 1f14a758..968549be 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -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
diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc
index 643af8f8..2c13dd1c 100644
--- a/absl/strings/string_view_test.cc
+++ b/absl/strings/string_view_test.cc
@@ -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);