diff options
author | Timothy Flynn <trflynn89@pm.me> | 2021-04-12 07:54:22 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-12 22:37:00 +0200 |
commit | 2370efbea6c1b46c1e7aacc303d9a5439c945fcd (patch) | |
tree | 57198bda1932029ecd2ecb6707b699691ad97384 /AK | |
parent | 04979865722ab558fdc4d909dbb9cecd40869897 (diff) | |
download | serenity-2370efbea6c1b46c1e7aacc303d9a5439c945fcd.zip |
AK: Add a predicate variant of StringView::split_view
Diffstat (limited to 'AK')
-rw-r--r-- | AK/StringView.cpp | 1 | ||||
-rw-r--r-- | AK/StringView.h | 24 | ||||
-rw-r--r-- | AK/Tests/TestStringView.cpp | 7 |
3 files changed, 31 insertions, 1 deletions
diff --git a/AK/StringView.cpp b/AK/StringView.cpp index a08d31ff94..50a4c3b677 100644 --- a/AK/StringView.cpp +++ b/AK/StringView.cpp @@ -31,7 +31,6 @@ #include <AK/Memory.h> #include <AK/String.h> #include <AK/StringView.h> -#include <AK/Vector.h> namespace AK { diff --git a/AK/StringView.h b/AK/StringView.h index 3fa71bf85f..ae8e5a7a47 100644 --- a/AK/StringView.h +++ b/AK/StringView.h @@ -32,6 +32,7 @@ #include <AK/Span.h> #include <AK/StdLibExtras.h> #include <AK/StringUtils.h> +#include <AK/Vector.h> namespace AK { @@ -108,6 +109,29 @@ public: [[nodiscard]] Vector<StringView> split_view(char, bool keep_empty = false) const; [[nodiscard]] Vector<StringView> split_view(const StringView&, bool keep_empty = false) const; + template<typename UnaryPredicate> + [[nodiscard]] Vector<StringView> split_view_if(UnaryPredicate&& predicate, bool keep_empty = false) const + { + if (is_empty()) + return {}; + + Vector<StringView> v; + size_t substart = 0; + for (size_t i = 0; i < length(); ++i) { + char ch = characters_without_null_termination()[i]; + if (predicate(ch)) { + size_t sublen = i - substart; + if (sublen != 0 || keep_empty) + v.append(substring_view(substart, sublen)); + substart = i + 1; + } + } + size_t taillen = length() - substart; + if (taillen != 0 || keep_empty) + v.append(substring_view(substart, taillen)); + return v; + } + // Create a Vector of StringViews split by line endings. As of CommonMark // 0.29, the spec defines a line ending as "a newline (U+000A), a carriage // return (U+000D) not followed by a newline, or a carriage return and a diff --git a/AK/Tests/TestStringView.cpp b/AK/Tests/TestStringView.cpp index a95be835bd..3a69070073 100644 --- a/AK/Tests/TestStringView.cpp +++ b/AK/Tests/TestStringView.cpp @@ -183,6 +183,13 @@ TEST_CASE(split_view) test_string_view = "axxbcxxdxx"; EXPECT_EQ(test_string_view.split_view("xx"), Vector<StringView>({ "a", "bc", "d" })); EXPECT_EQ(test_string_view.split_view("xx", true), Vector<StringView>({ "a", "bc", "d", "" })); + + test_string_view = "ax_b_cxd"; + auto predicate = [](char ch) { return ch == 'x' || ch == '_'; }; + EXPECT_EQ(test_string_view.split_view_if(predicate), Vector<StringView>({ "a", "b", "c", "d" })); + EXPECT_EQ(test_string_view.split_view_if(predicate, true), Vector<StringView>({ "a", "", "b", "c", "d" })); + EXPECT_EQ(test_string_view.split_view_if(predicate), Vector<StringView>({ "a", "b", "c", "d" })); + EXPECT_EQ(test_string_view.split_view_if(predicate, true), Vector<StringView>({ "a", "", "b", "c", "d" })); } TEST_MAIN(StringView) |