AK: Add String{,View}::is_whitespace()

+Tests!
This commit is contained in:
AnotherTest 2021-01-03 02:56:02 +03:30 committed by Andreas Kling
parent b795f582cf
commit f3ecea1fb3
Notes: sideshowbarker 2024-07-19 00:11:12 +09:00
5 changed files with 28 additions and 11 deletions

View file

@ -122,6 +122,8 @@ public:
String to_lowercase() const; String to_lowercase() const;
String to_uppercase() const; String to_uppercase() const;
bool is_whitespace() const { return StringUtils::is_whitespace(*this); }
#ifndef KERNEL #ifndef KERNEL
String trim_whitespace(TrimMode mode = TrimMode::Both) const String trim_whitespace(TrimMode mode = TrimMode::Both) const
{ {

View file

@ -31,6 +31,7 @@
#include <AK/StringUtils.h> #include <AK/StringUtils.h>
#include <AK/StringView.h> #include <AK/StringView.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <ctype.h>
namespace AK { namespace AK {
@ -302,17 +303,17 @@ bool contains(const StringView& str, const StringView& needle, CaseSensitivity c
return false; return false;
} }
bool is_whitespace(const StringView& str)
{
for (auto ch : str) {
if (!isspace(ch))
return false;
}
return true;
}
StringView trim_whitespace(const StringView& str, TrimMode mode) StringView trim_whitespace(const StringView& str, TrimMode mode)
{ {
auto is_whitespace_character = [](char ch) -> bool {
return ch == '\t'
|| ch == '\n'
|| ch == '\v'
|| ch == '\f'
|| ch == '\r'
|| ch == ' ';
};
size_t substring_start = 0; size_t substring_start = 0;
size_t substring_length = str.length(); size_t substring_length = str.length();
@ -320,7 +321,7 @@ StringView trim_whitespace(const StringView& str, TrimMode mode)
for (size_t i = 0; i < str.length(); ++i) { for (size_t i = 0; i < str.length(); ++i) {
if (substring_length == 0) if (substring_length == 0)
return ""; return "";
if (!is_whitespace_character(str[i])) if (!isspace(str[i]))
break; break;
++substring_start; ++substring_start;
--substring_length; --substring_length;
@ -331,7 +332,7 @@ StringView trim_whitespace(const StringView& str, TrimMode mode)
for (size_t i = str.length() - 1; i > 0; --i) { for (size_t i = str.length() - 1; i > 0; --i) {
if (substring_length == 0) if (substring_length == 0)
return ""; return "";
if (!is_whitespace_character(str[i])) if (!isspace(str[i]))
break; break;
--substring_length; --substring_length;
} }

View file

@ -69,6 +69,7 @@ bool equals_ignoring_case(const StringView&, const StringView&);
bool ends_with(const StringView& a, const StringView& b, CaseSensitivity); bool ends_with(const StringView& a, const StringView& b, CaseSensitivity);
bool starts_with(const StringView&, const StringView&, CaseSensitivity); bool starts_with(const StringView&, const StringView&, CaseSensitivity);
bool contains(const StringView&, const StringView&, CaseSensitivity); bool contains(const StringView&, const StringView&, CaseSensitivity);
bool is_whitespace(const StringView&);
StringView trim_whitespace(const StringView&, TrimMode mode); StringView trim_whitespace(const StringView&, TrimMode mode);
} }

View file

@ -180,6 +180,8 @@ public:
String to_string() const; String to_string() const;
bool is_whitespace() const { return StringUtils::is_whitespace(*this); }
template<typename T, typename... Rest> template<typename T, typename... Rest>
bool is_one_of(const T& string, Rest... rest) const bool is_one_of(const T& string, Rest... rest) const
{ {

View file

@ -287,4 +287,15 @@ TEST_CASE(contains)
EXPECT(!AK::StringUtils::contains(test_string, "L", CaseSensitivity::CaseInsensitive)); EXPECT(!AK::StringUtils::contains(test_string, "L", CaseSensitivity::CaseInsensitive));
} }
TEST_CASE(is_whitespace)
{
EXPECT(AK::StringUtils::is_whitespace(""));
EXPECT(AK::StringUtils::is_whitespace(" "));
EXPECT(AK::StringUtils::is_whitespace(" \t"));
EXPECT(AK::StringUtils::is_whitespace(" \t\n"));
EXPECT(AK::StringUtils::is_whitespace(" \t\n\r\v"));
EXPECT(!AK::StringUtils::is_whitespace(" a "));
EXPECT(!AK::StringUtils::is_whitespace("a\t"));
}
TEST_MAIN(StringUtils) TEST_MAIN(StringUtils)