From 72d7a159bf04ca26649928f4531d9af5e02e8f28 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 20 Dec 2023 14:06:23 -0800 Subject: [PATCH] Added ByAsciiWhitespace to str_split library. PiperOrigin-RevId: 592653487 Change-Id: Iddd2f484807cb02dd2ee8bba26c22d196be02c88 --- absl/strings/str_split.cc | 5 +++++ absl/strings/str_split.h | 18 +++++++++++++++ absl/strings/str_split_test.cc | 40 ++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/absl/strings/str_split.cc b/absl/strings/str_split.cc index 9669eb0b125..abe486b915e 100644 --- a/absl/strings/str_split.cc +++ b/absl/strings/str_split.cc @@ -96,6 +96,11 @@ absl::string_view ByString::Find(absl::string_view text, size_t pos) const { return GenericFind(text, delimiter_, pos, LiteralPolicy()); } +absl::string_view ByAsciiWhitespace::Find(absl::string_view text, + size_t pos) const { + return GenericFind(text, " \t\v\f\r\n", pos, AnyOfPolicy()); +} + // // ByChar // diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h index 7bbb68a3435..87540278ade 100644 --- a/absl/strings/str_split.h +++ b/absl/strings/str_split.h @@ -130,6 +130,24 @@ class ByString { const std::string delimiter_; }; +// ByAsciiWhitespace +// +// A sub-string delimiter that splits by ASCII whitespace +// (space, tab, vertical tab, formfeed, linefeed, or carriage return). +// Note: you probably want to use absl::SkipEmpty() as well! +// +// This class is equivalent to ByAnyChar with ASCII whitespace chars. +// +// Example: +// +// std::vector v = absl::StrSplit( +// "a b\tc\n d \n", absl::ByAsciiWhitespace(), absl::SkipEmpty()); +// // v[0] == "a", v[1] == "b", v[2] == "c", v[3] == "d" +class ByAsciiWhitespace { + public: + absl::string_view Find(absl::string_view text, size_t pos) const; +}; + // ByChar // // A single character delimiter. `ByChar` is functionally equivalent to a diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc index eb0c6c00cfe..df6c460f2a1 100644 --- a/absl/strings/str_split_test.cc +++ b/absl/strings/str_split_test.cc @@ -40,6 +40,7 @@ namespace { using ::testing::ElementsAre; +using ::testing::IsEmpty; using ::testing::Pair; using ::testing::UnorderedElementsAre; @@ -923,6 +924,45 @@ TEST(Delimiter, ByAnyChar) { EXPECT_TRUE(IsFoundAt("abc", empty, 1)); } +// +// Tests for ByAsciiWhitespace +// +TEST(Split, ByAsciiWhitespace) { + using absl::ByAsciiWhitespace; + using absl::SkipEmpty; + std::vector results; + + results = absl::StrSplit("aaaa\n", ByAsciiWhitespace()); + EXPECT_THAT(results, ElementsAre("aaaa", "")); + + results = absl::StrSplit("aaaa\n", ByAsciiWhitespace(), SkipEmpty()); + EXPECT_THAT(results, ElementsAre("aaaa")); + + results = absl::StrSplit(" ", ByAsciiWhitespace()); + EXPECT_THAT(results, ElementsAre("", "")); + + results = absl::StrSplit(" ", ByAsciiWhitespace(), SkipEmpty()); + EXPECT_THAT(results, IsEmpty()); + + results = absl::StrSplit("a", ByAsciiWhitespace()); + EXPECT_THAT(results, ElementsAre("a")); + + results = absl::StrSplit("", ByAsciiWhitespace()); + EXPECT_THAT(results, ElementsAre("")); + + results = absl::StrSplit("", ByAsciiWhitespace(), SkipEmpty()); + EXPECT_THAT(results, IsEmpty()); + + results = absl::StrSplit("a b\tc\n d\n", ByAsciiWhitespace()); + EXPECT_THAT(results, ElementsAre("a", "b", "c", "", "", "d", "")); + + results = absl::StrSplit("a b\tc\n d \n", ByAsciiWhitespace(), SkipEmpty()); + EXPECT_THAT(results, ElementsAre("a", "b", "c", "d")); + + results = absl::StrSplit("a\t\n\v\f\r b", ByAsciiWhitespace(), SkipEmpty()); + EXPECT_THAT(results, ElementsAre("a", "b")); +} + // // Tests for ByLength //