AK: Add a predicate variant of StringView::split_view

This commit is contained in:
Timothy Flynn 2021-04-12 07:54:22 -04:00 committed by Andreas Kling
parent 0497986572
commit 2370efbea6
Notes: sideshowbarker 2024-07-18 20:27:57 +09:00
3 changed files with 31 additions and 1 deletions

View file

@ -31,7 +31,6 @@
#include <AK/Memory.h> #include <AK/Memory.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/StringView.h> #include <AK/StringView.h>
#include <AK/Vector.h>
namespace AK { namespace AK {

View file

@ -32,6 +32,7 @@
#include <AK/Span.h> #include <AK/Span.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <AK/StringUtils.h> #include <AK/StringUtils.h>
#include <AK/Vector.h>
namespace AK { namespace AK {
@ -108,6 +109,29 @@ public:
[[nodiscard]] Vector<StringView> split_view(char, bool keep_empty = false) const; [[nodiscard]] Vector<StringView> split_view(char, bool keep_empty = false) const;
[[nodiscard]] Vector<StringView> split_view(const StringView&, 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 // 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 // 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 // return (U+000D) not followed by a newline, or a carriage return and a

View file

@ -183,6 +183,13 @@ TEST_CASE(split_view)
test_string_view = "axxbcxxdxx"; 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"), Vector<StringView>({ "a", "bc", "d" }));
EXPECT_EQ(test_string_view.split_view("xx", true), 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) TEST_MAIN(StringView)