mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
absl::string_view: Add support for starts_with() and ends_with()
when targeting at least C++20 These methods were added to C++20, so they are not available in earlier language standards. Users requiring compatibility prior to C++20 should use absl::StartsWith() and absl::EndsWith() from //absl/strings/match.h. Most users are not affected by this change. By default when targeting at least C++20 absl::string_view will be an alias for std::string_view. Only users that have modified //absl/base/options.h will see this change. PiperOrigin-RevId: 575238435 Change-Id: I7b03fde02c987b30b88c794640c2a616851997d1
This commit is contained in:
committed by
Copybara-Service
parent
0378614336
commit
0f110600fc
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user