From 6fd8e96d537e8175f0ca06789a6a19913f561455 Mon Sep 17 00:00:00 2001 From: davidot Date: Tue, 11 Oct 2022 00:48:45 +0200 Subject: [PATCH] AK: Add to_{double, float} convenience functions to all string types These are guarded with #ifndef KERNEL, since doubles (and floats) are not allowed in KERNEL mode. In StringUtils there is convert_to_floating_point which does have a template parameter incase you have a templated type. --- AK/FlyString.cpp | 12 ++++++++++++ AK/FlyString.h | 4 ++++ AK/String.cpp | 12 ++++++++++++ AK/String.h | 4 ++++ AK/StringUtils.cpp | 18 ++++++++++++++++++ AK/StringUtils.h | 4 ++++ AK/StringView.cpp | 10 ++++++++++ AK/StringView.h | 4 ++++ 8 files changed, 68 insertions(+) diff --git a/AK/FlyString.cpp b/AK/FlyString.cpp index 7e4465876f4..1c30af74184 100644 --- a/AK/FlyString.cpp +++ b/AK/FlyString.cpp @@ -95,6 +95,18 @@ template Optional FlyString::to_uint(TrimWhitespace) const; template Optional FlyString::to_uint(TrimWhitespace) const; template Optional FlyString::to_uint(TrimWhitespace) const; +#ifndef KERNEL +Optional FlyString::to_double(TrimWhitespace trim_whitespace) const +{ + return StringUtils::convert_to_floating_point(view(), trim_whitespace); +} + +Optional FlyString::to_float(TrimWhitespace trim_whitespace) const +{ + return StringUtils::convert_to_floating_point(view(), trim_whitespace); +} +#endif + bool FlyString::equals_ignoring_case(StringView other) const { return StringUtils::equals_ignoring_case(view(), other); diff --git a/AK/FlyString.h b/AK/FlyString.h index c81eb65e48e..3cc12db8681 100644 --- a/AK/FlyString.h +++ b/AK/FlyString.h @@ -77,6 +77,10 @@ public: Optional to_int(TrimWhitespace = TrimWhitespace::Yes) const; template Optional to_uint(TrimWhitespace = TrimWhitespace::Yes) const; +#ifndef KERNEL + Optional to_double(TrimWhitespace = TrimWhitespace::Yes) const; + Optional to_float(TrimWhitespace = TrimWhitespace::Yes) const; +#endif bool equals_ignoring_case(StringView) const; bool starts_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const; diff --git a/AK/String.cpp b/AK/String.cpp index 86d0be5f20d..cd318efbd5f 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -182,6 +182,18 @@ template Optional String::to_uint(TrimWhitespace) const; template Optional String::to_uint(TrimWhitespace) const; template Optional String::to_uint(TrimWhitespace) const; +#ifndef KERNEL +Optional String::to_double(TrimWhitespace trim_whitespace) const +{ + return StringUtils::convert_to_floating_point(*this, trim_whitespace); +} + +Optional String::to_float(TrimWhitespace trim_whitespace) const +{ + return StringUtils::convert_to_floating_point(*this, trim_whitespace); +} +#endif + bool String::starts_with(StringView str, CaseSensitivity case_sensitivity) const { return StringUtils::starts_with(*this, str, case_sensitivity); diff --git a/AK/String.h b/AK/String.h index 29682bc5efa..89dcff15d6a 100644 --- a/AK/String.h +++ b/AK/String.h @@ -116,6 +116,10 @@ public: [[nodiscard]] Optional to_int(TrimWhitespace = TrimWhitespace::Yes) const; template [[nodiscard]] Optional to_uint(TrimWhitespace = TrimWhitespace::Yes) const; +#ifndef KERNEL + [[nodiscard]] Optional to_double(TrimWhitespace = TrimWhitespace::Yes) const; + [[nodiscard]] Optional to_float(TrimWhitespace = TrimWhitespace::Yes) const; +#endif [[nodiscard]] String to_lowercase() const; [[nodiscard]] String to_uppercase() const; diff --git a/AK/StringUtils.cpp b/AK/StringUtils.cpp index 42887cce059..28d4a6b0446 100644 --- a/AK/StringUtils.cpp +++ b/AK/StringUtils.cpp @@ -15,6 +15,7 @@ #include #ifndef KERNEL +# include # include #endif @@ -232,6 +233,23 @@ template Optional convert_to_uint_from_octal(StringView str, TrimWhitespace template Optional convert_to_uint_from_octal(StringView str, TrimWhitespace); template Optional convert_to_uint_from_octal(StringView str, TrimWhitespace); +#ifndef KERNEL +template +Optional convert_to_floating_point(StringView str, TrimWhitespace trim_whitespace) +{ + static_assert(IsSame || IsSame); + auto string = trim_whitespace == TrimWhitespace::Yes + ? str.trim_whitespace() + : str; + + char const* start = string.characters_without_null_termination(); + return parse_floating_point_completely(start, start + str.length()); +} + +template Optional convert_to_floating_point(StringView str, TrimWhitespace); +template Optional convert_to_floating_point(StringView str, TrimWhitespace); +#endif + bool equals_ignoring_case(StringView a, StringView b) { if (a.length() != b.length()) diff --git a/AK/StringUtils.h b/AK/StringUtils.h index aa9b2af73d3..10b9952516a 100644 --- a/AK/StringUtils.h +++ b/AK/StringUtils.h @@ -63,6 +63,10 @@ template Optional convert_to_uint_from_hex(StringView, TrimWhitespace = TrimWhitespace::Yes); template Optional convert_to_uint_from_octal(StringView, TrimWhitespace = TrimWhitespace::Yes); +#ifndef KERNEL +template +Optional convert_to_floating_point(StringView, TrimWhitespace = TrimWhitespace::Yes); +#endif bool equals_ignoring_case(StringView, StringView); bool ends_with(StringView a, StringView b, CaseSensitivity); bool starts_with(StringView, StringView, CaseSensitivity); diff --git a/AK/StringView.cpp b/AK/StringView.cpp index a987696a086..278b833bfd5 100644 --- a/AK/StringView.cpp +++ b/AK/StringView.cpp @@ -236,6 +236,16 @@ template Optional StringView::to_uint() const; template Optional StringView::to_uint() const; #ifndef KERNEL +Optional StringView::to_double(TrimWhitespace trim_whitespace) const +{ + return StringUtils::convert_to_floating_point(*this, trim_whitespace); +} + +Optional StringView::to_float(TrimWhitespace trim_whitespace) const +{ + return StringUtils::convert_to_floating_point(*this, trim_whitespace); +} + bool StringView::operator==(String const& string) const { return *this == string.view(); diff --git a/AK/StringView.h b/AK/StringView.h index 4b8b974aa45..bb1b6641849 100644 --- a/AK/StringView.h +++ b/AK/StringView.h @@ -190,6 +190,10 @@ public: Optional to_int() const; template Optional to_uint() const; +#ifndef KERNEL + Optional to_double(TrimWhitespace trim_whitespace = TrimWhitespace::Yes) const; + Optional to_float(TrimWhitespace trim_whitespace = TrimWhitespace::Yes) const; +#endif // Create a new substring view of this string view, starting either at the beginning of // the given substring view, or after its end, and continuing until the end of this string