diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-10-17 14:06:48 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-10-17 14:06:48 +0800 |
commit | 5c5c496b605886b286d1b99e0f9e28ec02117ad5 (patch) | |
tree | c22b07e81ba179d7cc8790656abddbcc56b5d704 /src | |
parent | 32aa6f116acc6e3e20a1ec76cef45b29f7005ad7 (diff) | |
download | cru-5c5c496b605886b286d1b99e0f9e28ec02117ad5.tar.gz cru-5c5c496b605886b286d1b99e0f9e28ec02117ad5.tar.bz2 cru-5c5c496b605886b286d1b99e0f9e28ec02117ad5.zip |
Use std::from_chars.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/base/String.cpp | 121 | ||||
-rw-r--r-- | src/base/StringToNumberConverter.cpp | 170 | ||||
-rw-r--r-- | src/platform/graphics/Geometry.cpp | 14 | ||||
-rw-r--r-- | src/ui/components/Input.cpp | 23 | ||||
-rw-r--r-- | src/ui/mapper/ColorMapper.cpp | 6 | ||||
-rw-r--r-- | src/ui/mapper/FontMapper.cpp | 4 | ||||
-rw-r--r-- | src/ui/mapper/MeasureLengthMapper.cpp | 2 | ||||
-rw-r--r-- | src/ui/mapper/PointMapper.cpp | 5 | ||||
-rw-r--r-- | src/ui/mapper/SizeMapper.cpp | 5 | ||||
-rw-r--r-- | src/ui/mapper/ThicknessMapper.cpp | 4 |
11 files changed, 31 insertions, 326 deletions
diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt index 7e7b0127..685ceb8c 100644 --- a/src/base/CMakeLists.txt +++ b/src/base/CMakeLists.txt @@ -5,7 +5,6 @@ add_library(CruBase Format.cpp PropertyTree.cpp String.cpp - StringToNumberConverter.cpp StringUtil.cpp SubProcess.cpp io/AutoReadStream.cpp @@ -85,5 +84,3 @@ else() CRU_PLATFORM_UNIX ) endif() - -target_link_libraries(CruBase PUBLIC double-conversion) diff --git a/src/base/String.cpp b/src/base/String.cpp index c90b9a71..c96b898d 100644 --- a/src/base/String.cpp +++ b/src/base/String.cpp @@ -2,14 +2,9 @@ #include "cru/base/Buffer.h" #include "cru/base/Exception.h" -#include "cru/base/StringToNumberConverter.h" #include "cru/base/StringUtil.h" -#include <double-conversion/double-conversion.h> -#include <double-conversion/string-to-double.h> - #include <algorithm> -#include <cmath> #include <cstring> #include <functional> @@ -344,34 +339,6 @@ Range String::RangeFromCodePointToCodeUnit(Range code_point_range) const { return View().RangeFromCodePointToCodeUnit(code_point_range); } -int String::ParseToInt(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return View().ParseToInt(processed_characters_count, flags, base); -} - -long long String::ParseToLongLong(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return View().ParseToLongLong(processed_characters_count, flags, base); -} - -float String::ParseToFloat(Index* processed_characters_count, - StringToNumberFlag flags) const { - return View().ParseToFloat(processed_characters_count, flags); -} - -double String::ParseToDouble(Index* processed_characters_count, - StringToNumberFlag flags) const { - return View().ParseToDouble(processed_characters_count, flags); -} - -std::vector<float> String::ParseToFloatList(value_type separator) const { - return View().ParseToFloatList(separator); -} - -std::vector<double> String::ParseToDoubleList(value_type separator) const { - return View().ParseToDoubleList(separator); -} - std::ostream& operator<<(std::ostream& os, const String& value) { os << value.ToUtf8(); return os; @@ -583,94 +550,6 @@ Buffer StringView::ToUtf8Buffer(bool end_zero) const { return buffer; } -int StringView::ParseToInt(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return ParseToInteger<int>(processed_characters_count, flags, base); -} - -long long StringView::ParseToLongLong(Index* processed_characters_count, - StringToNumberFlag flags, - int base) const { - return ParseToInteger<long long>(processed_characters_count, flags, base); -} - -static int MapStringToDoubleFlags(StringToNumberFlag flags) { - int f = double_conversion::StringToDoubleConverter::ALLOW_CASE_INSENSIBILITY; - if (flags & StringToNumberFlags::kAllowLeadingSpaces) { - f |= double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES; - } - if (flags & StringToNumberFlags::kAllowTrailingSpaces) { - f |= double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES; - } - if (flags & StringToNumberFlags::kAllowTrailingJunk) { - f |= double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK; - } - return f; -} - -static double_conversion::StringToDoubleConverter CreateStringToDoubleConverter( - StringToNumberFlag flags) { - return {MapStringToDoubleFlags(flags), 0.0, NAN, "inf", "nan"}; -} - -float StringView::ParseToFloat(Index* processed_characters_count, - StringToNumberFlag flags) const { - int pcc; - auto result = CreateStringToDoubleConverter(flags).StringToFloat( - reinterpret_cast<const uc16*>(ptr_), static_cast<int>(size_), &pcc); - if (processed_characters_count != nullptr) { - *processed_characters_count = pcc; - } - - if (flags & StringToNumberFlags::kThrowOnError && std::isnan(result)) { - throw Exception("Result of string to float conversion is NaN"); - } - - return result; -} - -double StringView::ParseToDouble(Index* processed_characters_count, - StringToNumberFlag flags) const { - int pcc; - auto result = CreateStringToDoubleConverter(flags).StringToDouble( - reinterpret_cast<const uc16*>(ptr_), static_cast<int>(size_), &pcc); - if (processed_characters_count != nullptr) { - *processed_characters_count = pcc; - } - - if (flags & StringToNumberFlags::kThrowOnError && std::isnan(result)) { - throw Exception("Result of string to double conversion is NaN"); - } - - return result; -} - -std::vector<float> StringView::ParseToFloatList(value_type separator) const { - std::vector<float> result; - auto list = Split(separator, true); - for (auto& item : list) { - auto value = item.ParseToFloat(); - if (std::isnan(value)) { - throw Exception("Invalid double value."); - } - result.push_back(value); - } - return result; -} - -std::vector<double> StringView::ParseToDoubleList(value_type separator) const { - std::vector<double> result; - auto list = Split(separator, true); - for (auto& item : list) { - auto value = item.ParseToDouble(); - if (std::isnan(value)) { - throw Exception("Invalid double value."); - } - result.push_back(value); - } - return result; -} - String ToLower(StringView s) { String result; for (auto c : s) result.push_back(ToLower(c)); diff --git a/src/base/StringToNumberConverter.cpp b/src/base/StringToNumberConverter.cpp deleted file mode 100644 index f7516630..00000000 --- a/src/base/StringToNumberConverter.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "cru/base/StringToNumberConverter.h" -#include "cru/base/Exception.h" - -namespace cru { -bool StringToIntegerConverter::CheckParams() const { - return base == 0 || base >= 2 & base <= 36; -} - -static bool IsSpace(char c) { - return c == ' ' || c == '\t' || c == '\n' || c == '\r'; -} - -StringToIntegerResult StringToIntegerConverter::Parse( - const char* const str, const Index size, - Index* processed_characters_count) const { - if (str == nullptr) throw std::invalid_argument("Invalid str."); - if (size < 0) throw std::invalid_argument("Invalid size."); - if (!CheckParams()) throw std::invalid_argument("Invalid parsing flags."); - - const bool throw_on_error = flags.Has(StringToNumberFlags::kThrowOnError); - - auto const end = str + size; - - auto current = str; - - if (flags & StringToNumberFlags::kAllowLeadingSpaces) { - while (current != end && IsSpace(*current)) { - current++; - } - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception("Empty string (after reading leading spaces)."); - } else { - return {false, 0}; - } - } - - bool negate = false; - - if (*current == '-') { - ++current; - negate = true; - } else if (*current == '+') { - ++current; - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception("Empty string (after reading sign)."); - } else { - return {false, 0}; - } - } - - int real_base = base; - - if (real_base == 0) { - if (*current == '0') { - ++current; - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = current - str; - } - return {negate, 0}; - } else if (*current == 'x' || *current == 'X') { - ++current; - real_base = 16; - } else if (*current == 'b' || *current == 'B') { - ++current; - real_base = 2; - } else { - real_base = 8; - } - } else { - real_base = 10; - } - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception("Empty string (after reading head base indicator)."); - } else { - return {false, 0}; - } - } - - const bool allow_leading_zero = - flags.Has(StringToNumberFlags::kAllowLeadingZeroForInteger); - - while (current != end && *current == '0') { - current++; - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = current - str; - } - return {negate, 0}; - } - - const bool allow_trailing_junk = - flags.Has(StringToNumberFlags::kAllowTrailingJunk); - const bool allow_trailing_spaces = - flags.Has(StringToNumberFlags::kAllowTrailingSpaces); - - unsigned long long result = 0; - - while (current != end) { - const char c = *current; - if (c >= '0' && c <= (real_base > 10 ? '9' : real_base + '0' - 1)) { - result = result * real_base + c - '0'; - current++; - } else if (real_base > 10 && c >= 'a' && c <= (real_base + 'a' - 10 - 1)) { - result = result * real_base + c - 'a' + 10; - current++; - } else if (real_base > 10 && c >= 'A' && c <= (real_base + 'A' - 10 - 1)) { - result = result * real_base + c - 'A' + 10; - current++; - } else if (allow_trailing_junk) { - break; - } else if (allow_trailing_spaces && IsSpace(c)) { - break; - } else { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(std::string("Read invalid character '") + c + "'."); - } else { - return {false, 0}; - } - } - } - - if (allow_trailing_spaces) { - while (current != end && IsSpace(*current)) { - current++; - } - - if (current != end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception("There is trailing junk."); - } else { - return {false, 0}; - } - } - } - - if (processed_characters_count) { - *processed_characters_count = current - str; - } - - return {negate, result}; -} - -} // namespace cru diff --git a/src/platform/graphics/Geometry.cpp b/src/platform/graphics/Geometry.cpp index e88577ce..4189ef72 100644 --- a/src/platform/graphics/Geometry.cpp +++ b/src/platform/graphics/Geometry.cpp @@ -1,7 +1,7 @@ #include "cru/platform/graphics/Geometry.h" #include "cru/base/Exception.h" -#include "cru/base/String.h" +#include "cru/base/StringUtil.h" #include "cru/platform/Exception.h" #include "cru/platform/graphics/Factory.h" @@ -235,17 +235,15 @@ void IGeometryBuilder::ParseAndApplySvgPathData(std::string_view path_d) { ++position; } - Index processed_count = 0; - auto result = String::FromUtf8(path_d.substr(position)) - .ParseToFloat(&processed_count, - StringToNumberFlags::kAllowTrailingJunk); + auto result = cru::string::ParseToNumber<float>( + path_d.substr(position), cru::string::ParseToNumberFlags::AllowTrailingJunk); - if (std::isnan(result)) throw Exception("Invalid svg path data number."); + if (!result.valid) throw Exception("Invalid svg path data number."); - position += processed_count; + position += result.processed_char_count; - return result; + return result.value; }; auto read_point = [&] { diff --git a/src/ui/components/Input.cpp b/src/ui/components/Input.cpp index e75eccc5..0a14c7b8 100644 --- a/src/ui/components/Input.cpp +++ b/src/ui/components/Input.cpp @@ -1,8 +1,7 @@ #include "cru/ui/components/Input.h" -#include "cru/base/StringToNumberConverter.h" +#include "cru/base/StringUtil.h" #include "cru/ui/controls/Control.h" -#include <cmath> #include <optional> #include <string> @@ -44,18 +43,18 @@ InputValidateResult Input::GetLastValidateResult() const { } InputValidateResult FloatInputValidator::Validate(std::string_view text) const { - auto result = String::FromUtf8(text).ParseToFloat( - nullptr, StringToNumberFlags::kAllowLeadingSpaces & - StringToNumberFlags::kAllowTrailingSpaces); - if (std::isnan(result)) { + auto result = cru::string::ParseToNumber<float>( + text, cru::string::ParseToNumberFlags::AllowLeadingSpaces | + cru::string::ParseToNumberFlags::AllowTrailingSpaces); + if (!result.valid) { return InputValidateResult{false, "Invalid number."}; } - if (min && result < *min) { + if (min && result.value < *min) { return InputValidateResult{false, "Value is less than minimum."}; } - if (max && result > *max) { + if (max && result.value > *max) { return InputValidateResult{false, "Value is greater than maximum."}; } @@ -67,9 +66,11 @@ FloatInput::FloatInput() { ChangeEvent()->AddHandler([this](const InputChangeEventArgs& args) { if (args.valid) { - value_ = String::FromUtf8(args.text).ParseToFloat( - nullptr, StringToNumberFlags::kAllowLeadingSpaces & - StringToNumberFlags::kAllowTrailingSpaces); + value_ = cru::string::ParseToNumber<float>( + args.text, + cru::string::ParseToNumberFlags::AllowLeadingSpaces | + cru::string::ParseToNumberFlags::AllowTrailingSpaces) + .value; } }); } diff --git a/src/ui/mapper/ColorMapper.cpp b/src/ui/mapper/ColorMapper.cpp index 82e9dfbc..515eba97 100644 --- a/src/ui/mapper/ColorMapper.cpp +++ b/src/ui/mapper/ColorMapper.cpp @@ -1,6 +1,5 @@ #include "cru/ui/mapper/ColorMapper.h" - -#include <cru/base/String.h> +#include "cru/base/StringUtil.h" namespace cru::ui::mapper { bool ColorMapper::XmlElementIsOfThisType(xml::XmlElementNode* node) { @@ -25,7 +24,8 @@ Color ColorMapper::DoMapFromXml(xml::XmlElementNode* node) { auto alpha_value_attr = node->GetOptionalAttributeValueCaseInsensitive("alpha"); if (alpha_value_attr) { - result.alpha = String::FromUtf8(*alpha_value_attr).ParseToDouble() * 255; + result.alpha = + cru::string::ParseToNumber<double>(*alpha_value_attr).value * 255; } return result; diff --git a/src/ui/mapper/FontMapper.cpp b/src/ui/mapper/FontMapper.cpp index 1f749513..a0dcdd9f 100644 --- a/src/ui/mapper/FontMapper.cpp +++ b/src/ui/mapper/FontMapper.cpp @@ -1,6 +1,7 @@ #include "cru/ui/mapper/FontMapper.h" #include "../Helper.h" #include "cru/base/String.h" +#include "cru/base/StringUtil.h" #include "cru/platform/graphics/Factory.h" namespace cru::ui::mapper { @@ -15,7 +16,8 @@ std::shared_ptr<platform::graphics::IFont> FontMapper::DoMapFromXml( auto font_family = font_family_attr.value_or(""); auto font_size = - font_size_attr ? String::FromUtf8(*font_size_attr).ParseToFloat() : 24.0f; + font_size_attr ? cru::string::ParseToNumber<float>(*font_size_attr).value + : 24.0f; return GetGraphicsFactory()->CreateFont(font_family, font_size); } diff --git a/src/ui/mapper/MeasureLengthMapper.cpp b/src/ui/mapper/MeasureLengthMapper.cpp index 9f5c2a26..d36afb0e 100644 --- a/src/ui/mapper/MeasureLengthMapper.cpp +++ b/src/ui/mapper/MeasureLengthMapper.cpp @@ -15,7 +15,7 @@ render::MeasureLength MeasureLengthMapper::DoMapFromString(std::string str) { if (cru::string::CaseInsensitiveCompare(str, "unspecified") == 0) { return render::MeasureLength::NotSpecified(); } - auto value = String::FromUtf8(str).ParseToFloat(); + auto value = cru::string::ParseToNumber<float>(str).value; if (value < 0) { return render::MeasureLength::NotSpecified(); } diff --git a/src/ui/mapper/PointMapper.cpp b/src/ui/mapper/PointMapper.cpp index 12f000ef..a63e1b9e 100644 --- a/src/ui/mapper/PointMapper.cpp +++ b/src/ui/mapper/PointMapper.cpp @@ -1,6 +1,5 @@ #include "cru/ui/mapper/PointMapper.h" - -#include <cru/base/String.h> +#include "cru/base/StringUtil.h" namespace cru::ui::mapper { bool PointMapper::XmlElementIsOfThisType(xml::XmlElementNode* node) { @@ -8,7 +7,7 @@ bool PointMapper::XmlElementIsOfThisType(xml::XmlElementNode* node) { } Point PointMapper::DoMapFromString(std::string str) { - std::vector<float> values = String::FromUtf8(str).ParseToFloatList(); + std::vector<float> values = cru::string::ParseToNumberList<float>(str); if (values.size() == 2) { return {values[0], values[1]}; } else if (values.size() == 1) { diff --git a/src/ui/mapper/SizeMapper.cpp b/src/ui/mapper/SizeMapper.cpp index de8a0ded..d07d937d 100644 --- a/src/ui/mapper/SizeMapper.cpp +++ b/src/ui/mapper/SizeMapper.cpp @@ -1,6 +1,5 @@ #include "cru/ui/mapper/SizeMapper.h" - -#include <cru/base/String.h> +#include "cru/base/StringUtil.h" namespace cru::ui::mapper { bool SizeMapper::XmlElementIsOfThisType(xml::XmlElementNode* node) { @@ -8,7 +7,7 @@ bool SizeMapper::XmlElementIsOfThisType(xml::XmlElementNode* node) { } Size SizeMapper::DoMapFromString(std::string str) { - std::vector<float> values = String::FromUtf8(str).ParseToFloatList(); + std::vector<float> values = cru::string::ParseToNumberList<float>(str); if (values.size() == 2) { return {values[0], values[1]}; } else if (values.size() == 1) { diff --git a/src/ui/mapper/ThicknessMapper.cpp b/src/ui/mapper/ThicknessMapper.cpp index 96f016a7..e6557689 100644 --- a/src/ui/mapper/ThicknessMapper.cpp +++ b/src/ui/mapper/ThicknessMapper.cpp @@ -1,6 +1,6 @@ #include "cru/ui/mapper/ThicknessMapper.h" +#include "cru/base/StringUtil.h" #include "cru/xml/XmlNode.h" -#include "cru/base/String.h" namespace cru::ui::mapper { bool ThicknessMapper::XmlElementIsOfThisType(xml::XmlElementNode* node) { @@ -8,7 +8,7 @@ bool ThicknessMapper::XmlElementIsOfThisType(xml::XmlElementNode* node) { } Thickness ThicknessMapper::DoMapFromString(std::string str) { - std::vector<float> values = String::FromUtf8(str).ParseToFloatList(); + std::vector<float> values = cru::string::ParseToNumberList<float>(str); if (values.size() == 4) { return Thickness(values[0], values[1], values[2], values[3]); } else if (values.size() == 2) { |