summaryrefslogtreecommitdiff
path: root/absl/strings
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/string_view.h54
-rw-r--r--absl/strings/string_view_test.cc70
2 files changed, 123 insertions, 1 deletions
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index eae11b2a..f88b05b6 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -506,7 +506,7 @@ class string_view {
// 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 {
+ size_type count) const {
return find_first_of(string_view(s, count), pos);
}
@@ -590,6 +590,58 @@ class string_view {
return find_last_not_of(string_view(s), pos);
}
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+ // string_view::starts_with()
+ //
+ // Returns true if the `string_view` starts with the prefix `s`.
+ //
+ // This method only exists when targeting at least C++20.
+ // If support for C++ prior to C++20 is required, use `absl::StartsWith()`
+ // from `//absl/strings/match.h` for compatibility.
+ constexpr bool starts_with(string_view s) const noexcept {
+ return s.empty() ||
+ (size() >= s.size() &&
+ ABSL_INTERNAL_STRING_VIEW_MEMCMP(data(), s.data(), s.size()) == 0);
+ }
+
+ // Overload of `string_view::starts_with()` that returns true if `c` is the
+ // first character of the `string_view`.
+ constexpr bool starts_with(char c) const noexcept {
+ return !empty() && front() == c;
+ }
+
+ // Overload of `string_view::starts_with()` that returns true if the
+ // `string_view` starts with the C-style prefix `s`.
+ constexpr bool starts_with(const char* s) const {
+ return starts_with(string_view(s));
+ }
+
+ // string_view::ends_with()
+ //
+ // Returns true if the `string_view` ends with the suffix `s`.
+ //
+ // This method only exists when targeting at least C++20.
+ // If support for C++ prior to C++20 is required, use `absl::EndsWith()`
+ // from `//absl/strings/match.h` for compatibility.
+ constexpr bool ends_with(string_view s) const noexcept {
+ return s.empty() || (size() >= s.size() && ABSL_INTERNAL_STRING_VIEW_MEMCMP(
+ data() + (size() - s.size()),
+ s.data(), s.size()) == 0);
+ }
+
+ // Overload of `string_view::ends_with()` that returns true if `c` is the
+ // last character of the `string_view`.
+ constexpr bool ends_with(char c) const noexcept {
+ return !empty() && back() == c;
+ }
+
+ // Overload of `string_view::ends_with()` that returns true if the
+ // `string_view` ends with the C-style suffix `s`.
+ constexpr bool ends_with(const char* s) const {
+ return ends_with(string_view(s));
+ }
+#endif // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+
private:
// The constructor from std::string delegates to this constructor.
// See the comment on that constructor for the rationale.
diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc
index 642989b1..5b1eb01a 100644
--- a/absl/strings/string_view_test.cc
+++ b/absl/strings/string_view_test.cc
@@ -951,6 +951,76 @@ TEST(StringViewTest, At) {
#endif
}
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+TEST(StringViewTest, StartsWith) {
+ const absl::string_view a("foobar");
+ const absl::string_view b("123\0abc", 7);
+ const absl::string_view e;
+ EXPECT_TRUE(a.starts_with(a));
+ EXPECT_TRUE(a.starts_with("foo"));
+ EXPECT_TRUE(a.starts_with('f'));
+ EXPECT_TRUE(a.starts_with(e));
+ EXPECT_TRUE(b.starts_with(b));
+ EXPECT_TRUE(b.starts_with('1'));
+ EXPECT_TRUE(b.starts_with(e));
+ EXPECT_TRUE(e.starts_with(""));
+ EXPECT_FALSE(a.starts_with(b));
+ EXPECT_FALSE(b.starts_with(a));
+ EXPECT_FALSE(e.starts_with(a));
+ EXPECT_FALSE(a.starts_with('r'));
+ EXPECT_FALSE(a.starts_with('\0'));
+ EXPECT_FALSE(e.starts_with('r'));
+ EXPECT_FALSE(e.starts_with('\0'));
+
+ // Test that constexpr compiles.
+ constexpr absl::string_view kFooBar("foobar");
+ constexpr absl::string_view kFoo("foo");
+ constexpr absl::string_view kBar("bar");
+ constexpr bool k1 = kFooBar.starts_with(kFoo);
+ EXPECT_TRUE(k1);
+ constexpr bool k2 = kFooBar.starts_with(kBar);
+ EXPECT_FALSE(k2);
+ constexpr bool k3 = kFooBar.starts_with('f');
+ EXPECT_TRUE(k3);
+ constexpr bool k4 = kFooBar.starts_with("fo");
+ EXPECT_TRUE(k4);
+}
+
+TEST(StringViewTest, EndsWith) {
+ const absl::string_view a("foobar");
+ const absl::string_view b("123\0abc", 7);
+ const absl::string_view e;
+ EXPECT_TRUE(a.ends_with(a));
+ EXPECT_TRUE(a.ends_with('r'));
+ EXPECT_TRUE(a.ends_with("bar"));
+ EXPECT_TRUE(a.ends_with(e));
+ EXPECT_TRUE(b.ends_with(b));
+ EXPECT_TRUE(b.ends_with('c'));
+ EXPECT_TRUE(b.ends_with(e));
+ EXPECT_TRUE(e.ends_with(""));
+ EXPECT_FALSE(a.ends_with(b));
+ EXPECT_FALSE(b.ends_with(a));
+ EXPECT_FALSE(e.ends_with(a));
+ EXPECT_FALSE(a.ends_with('f'));
+ EXPECT_FALSE(a.ends_with('\0'));
+ EXPECT_FALSE(e.ends_with('r'));
+ EXPECT_FALSE(e.ends_with('\0'));
+
+ // Test that constexpr compiles.
+ constexpr absl::string_view kFooBar("foobar");
+ constexpr absl::string_view kFoo("foo");
+ constexpr absl::string_view kBar("bar");
+ constexpr bool k1 = kFooBar.ends_with(kFoo);
+ EXPECT_FALSE(k1);
+ constexpr bool k2 = kFooBar.ends_with(kBar);
+ EXPECT_TRUE(k2);
+ constexpr bool k3 = kFooBar.ends_with('r');
+ EXPECT_TRUE(k3);
+ constexpr bool k4 = kFooBar.ends_with("ar");
+ EXPECT_TRUE(k4);
+}
+#endif // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+
struct MyCharAlloc : std::allocator<char> {};
TEST(StringViewTest, ExplicitConversionOperator) {