summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorBrian Gianforcaro <bgianf@serenityos.org>2022-01-09 02:26:45 -0800
committerAndreas Kling <kling@serenityos.org>2022-01-12 13:03:44 +0100
commit142e0990017a7f836ded172a253a2bfe5bb1311e (patch)
tree10605a4f43651cf78dc1514b0b47380c60ebc650 /AK
parentcd42f64bc79683533f08bb3ea6c8b7afa804bcf6 (diff)
downloadserenity-142e0990017a7f836ded172a253a2bfe5bb1311e.zip
AK: Implement StringView::for_each_split_view
StringView::for_each_split_view allows you to process the splits in a StringView without needing to allocate a Vector<StringView> to store each of the parts. Since we migrated the implementation from the normal split_view path, we can also re-implement split_view in terms of for_each_split_view.
Diffstat (limited to 'AK')
-rw-r--r--AK/StringView.cpp21
-rw-r--r--AK/StringView.h30
2 files changed, 32 insertions, 19 deletions
diff --git a/AK/StringView.cpp b/AK/StringView.cpp
index a83e65e229..4a569bbcb8 100644
--- a/AK/StringView.cpp
+++ b/AK/StringView.cpp
@@ -42,27 +42,10 @@ Vector<StringView> StringView::split_view(const char separator, bool keep_empty)
Vector<StringView> StringView::split_view(StringView separator, bool keep_empty) const
{
- VERIFY(!separator.is_empty());
-
- if (is_empty())
- return {};
-
- StringView view { *this };
-
Vector<StringView> parts;
-
- auto maybe_separator_index = find(separator);
- while (maybe_separator_index.has_value()) {
- auto separator_index = maybe_separator_index.value();
- auto part_with_separator = view.substring_view(0, separator_index + separator.length());
- if (keep_empty || separator_index > 0)
- parts.append(part_with_separator.substring_view(0, separator_index));
- view = view.substring_view_starting_after_substring(part_with_separator);
- maybe_separator_index = view.find(separator);
- }
- if (keep_empty || !view.is_empty())
+ for_each_split_view(separator, keep_empty, [&](StringView view) {
parts.append(view);
-
+ });
return parts;
}
diff --git a/AK/StringView.h b/AK/StringView.h
index 86f5747096..a63f0590b5 100644
--- a/AK/StringView.h
+++ b/AK/StringView.h
@@ -120,6 +120,36 @@ public:
[[nodiscard]] Vector<StringView> split_view_if(Function<bool(char)> const& predicate, bool keep_empty = false) const;
+ template<VoidFunction<StringView> Callback>
+ void for_each_split_view(char separator, bool keep_empty, Callback callback) const
+ {
+ StringView seperator_view { &separator, 1 };
+ for_each_split_view(seperator_view, keep_empty, callback);
+ }
+
+ template<VoidFunction<StringView> Callback>
+ void for_each_split_view(StringView separator, bool keep_empty, Callback callback) const
+ {
+ VERIFY(!separator.is_empty());
+
+ if (is_empty())
+ return;
+
+ StringView view { *this };
+
+ auto maybe_separator_index = find(separator);
+ while (maybe_separator_index.has_value()) {
+ auto separator_index = maybe_separator_index.value();
+ auto part_with_separator = view.substring_view(0, separator_index + separator.length());
+ if (keep_empty || separator_index > 0)
+ callback(part_with_separator.substring_view(0, separator_index));
+ view = view.substring_view_starting_after_substring(part_with_separator);
+ maybe_separator_index = view.find(separator);
+ }
+ if (keep_empty || !view.is_empty())
+ callback(view);
+ }
+
// 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