From 56253bf3895e258729130a7ec22acff74e5b4212 Mon Sep 17 00:00:00 2001 From: Max Wipfli Date: Thu, 1 Jul 2021 14:58:37 +0200 Subject: [PATCH] AK: Reimplement StringView::find methods in StringUtils This patch reimplements the StringView::find methods in StringUtils, so they can also be used by String. The methods now also take an optional start parameter, which moves their API in line with String's respective methods. This also implements a StringView::find_ast(char) method, which is currently functionally equivalent to find_last_of(char). This is because find_last_of(char) will be removed in a further commit. --- AK/String.cpp | 5 +---- AK/StringUtils.cpp | 29 ++++++++++++++++++++++++++--- AK/StringUtils.h | 7 ++++++- AK/StringView.cpp | 10 ---------- AK/StringView.h | 6 ++++-- 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/AK/String.cpp b/AK/String.cpp index 44fd77fb70..bf423b0c8a 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -483,10 +483,7 @@ Optional String::find(char c, size_t start) const Optional String::find(StringView const& view, size_t start) const { - auto index = StringUtils::find(substring_view(start), view); - if (!index.has_value()) - return {}; - return index.value() + start; + return StringUtils::find(*this, view, start); } } diff --git a/AK/StringUtils.cpp b/AK/StringUtils.cpp index 5c5d5db10c..fdc4830120 100644 --- a/AK/StringUtils.cpp +++ b/AK/StringUtils.cpp @@ -332,11 +332,34 @@ StringView trim_whitespace(const StringView& str, TrimMode mode) return trim(str, " \n\t\v\f\r", mode); } -Optional find(const StringView& haystack, const StringView& needle) +Optional find(StringView const& haystack, char needle, size_t start) { - return AK::memmem_optional( - haystack.characters_without_null_termination(), haystack.length(), + if (start >= haystack.length()) + return {}; + for (size_t i = start; i < haystack.length(); ++i) { + if (haystack[i] == needle) + return i; + } + return {}; +} + +Optional find(StringView const& haystack, StringView const& needle, size_t start) +{ + if (start > haystack.length()) + return {}; + auto index = AK::memmem_optional( + haystack.characters_without_null_termination() + start, haystack.length() - start, needle.characters_without_null_termination(), needle.length()); + return index.has_value() ? (*index + start) : index; +} + +Optional find_last(StringView const& haystack, char needle) +{ + for (size_t i = haystack.length(); i > 0; --i) { + if (haystack[i - 1] == needle) + return i - 1; + } + return {}; } String to_snakecase(const StringView& str) diff --git a/AK/StringUtils.h b/AK/StringUtils.h index fa7ae1902d..f7211b0561 100644 --- a/AK/StringUtils.h +++ b/AK/StringUtils.h @@ -57,7 +57,12 @@ bool contains(const StringView&, const StringView&, CaseSensitivity); bool is_whitespace(const StringView&); StringView trim(const StringView& string, const StringView& characters, TrimMode mode); StringView trim_whitespace(const StringView& string, TrimMode mode); -Optional find(const StringView& haystack, const StringView& needle); + +Optional find(StringView const& haystack, char needle, size_t start = 0); +Optional find(StringView const& haystack, StringView const& needle, size_t start = 0); +Optional find_last(StringView const& haystack, char needle); +Vector find_all(StringView const& haystack, StringView const& needle); + String to_snakecase(const StringView&); } diff --git a/AK/StringView.cpp b/AK/StringView.cpp index 9053a6d131..9960d66707 100644 --- a/AK/StringView.cpp +++ b/AK/StringView.cpp @@ -282,16 +282,6 @@ Optional StringView::find_last_of(const StringView& view) const return {}; } -Optional StringView::find(char c) const -{ - return find(StringView { &c, 1 }); -} - -Optional StringView::find(const StringView& view) const -{ - return StringUtils::find(*this, view); -} - String StringView::to_string() const { return String { *this }; } } diff --git a/AK/StringView.h b/AK/StringView.h index 356f65f8f2..1c4da71248 100644 --- a/AK/StringView.h +++ b/AK/StringView.h @@ -92,8 +92,10 @@ public: Optional find_last_of(char) const; Optional find_last_of(const StringView&) const; - Optional find(const StringView&) const; - Optional find(char c) const; + [[nodiscard]] Optional find(char needle, size_t start = 0) const { return StringUtils::find(*this, needle, start); } + [[nodiscard]] Optional find(StringView const& needle, size_t start = 0) const { return StringUtils::find(*this, needle, start); } + [[nodiscard]] Optional find_last(char needle) const { return StringUtils::find_last(*this, needle); } + // FIXME: Implement find_last(StringView const&) for API symmetry. [[nodiscard]] constexpr StringView substring_view(size_t start, size_t length) const {