mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
AK: Add a somewhat naive implementation of String::reverse
This will reverse the String's code points (i.e. not just its bytes), but is not aware of grapheme clusters.
This commit is contained in:
parent
f5d253dcfa
commit
9db9b2f9be
Notes:
sideshowbarker
2024-07-17 03:00:02 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/9db9b2f9be Pull-request: https://github.com/SerenityOS/serenity/pull/17014 Reviewed-by: https://github.com/linusg ✅
3 changed files with 38 additions and 0 deletions
|
@ -10,6 +10,7 @@
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
@ -319,6 +320,25 @@ ErrorOr<String> String::replace(StringView needle, StringView replacement, Repla
|
||||||
return StringUtils::replace(*this, needle, replacement, replace_mode);
|
return StringUtils::replace(*this, needle, replacement, replace_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<String> String::reverse() const
|
||||||
|
{
|
||||||
|
// FIXME: This handles multi-byte code points, but not e.g. grapheme clusters.
|
||||||
|
// FIXME: We could avoid allocating a temporary vector if Utf8View supports reverse iteration.
|
||||||
|
auto code_point_length = code_points().length();
|
||||||
|
|
||||||
|
Vector<u32> code_points;
|
||||||
|
TRY(code_points.try_ensure_capacity(code_point_length));
|
||||||
|
|
||||||
|
for (auto code_point : this->code_points())
|
||||||
|
code_points.unchecked_append(code_point);
|
||||||
|
|
||||||
|
auto builder = TRY(StringBuilder::create(code_point_length * sizeof(u32)));
|
||||||
|
while (!code_points.is_empty())
|
||||||
|
TRY(builder.try_append_code_point(code_points.take_last()));
|
||||||
|
|
||||||
|
return builder.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
bool String::is_short_string() const
|
bool String::is_short_string() const
|
||||||
{
|
{
|
||||||
return has_short_string_bit(reinterpret_cast<uintptr_t>(m_data));
|
return has_short_string_bit(reinterpret_cast<uintptr_t>(m_data));
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
[[nodiscard]] StringView bytes_as_string_view() const;
|
[[nodiscard]] StringView bytes_as_string_view() const;
|
||||||
|
|
||||||
ErrorOr<String> replace(StringView needle, StringView replacement, ReplaceMode replace_mode) const;
|
ErrorOr<String> replace(StringView needle, StringView replacement, ReplaceMode replace_mode) const;
|
||||||
|
ErrorOr<String> reverse() const;
|
||||||
|
|
||||||
[[nodiscard]] bool operator==(String const&) const;
|
[[nodiscard]] bool operator==(String const&) const;
|
||||||
[[nodiscard]] bool operator!=(String const& other) const { return !(*this == other); }
|
[[nodiscard]] bool operator!=(String const& other) const { return !(*this == other); }
|
||||||
|
|
|
@ -108,6 +108,23 @@ TEST_CASE(replace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(reverse)
|
||||||
|
{
|
||||||
|
auto test_reverse = [](auto test, auto expected) {
|
||||||
|
auto string = MUST(String::from_utf8(test));
|
||||||
|
auto result = MUST(string.reverse());
|
||||||
|
|
||||||
|
EXPECT_EQ(result, expected);
|
||||||
|
};
|
||||||
|
|
||||||
|
test_reverse(""sv, ""sv);
|
||||||
|
test_reverse("a"sv, "a"sv);
|
||||||
|
test_reverse("ab"sv, "ba"sv);
|
||||||
|
test_reverse("ab cd ef"sv, "fe dc ba"sv);
|
||||||
|
test_reverse("😀"sv, "😀"sv);
|
||||||
|
test_reverse("ab😀cd"sv, "dc😀ba"sv);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(to_lowercase)
|
TEST_CASE(to_lowercase)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue