diff --git a/include/etl/to_arithmetic.h b/include/etl/to_arithmetic.h index 232a233c..2e32175f 100644 --- a/include/etl/to_arithmetic.h +++ b/include/etl/to_arithmetic.h @@ -191,88 +191,85 @@ namespace etl struct character_set; //******************************************* - template <> - struct character_set + static char convert(char c) { - ETL_NODISCARD - ETL_CONSTEXPR14 - static char lookup(char c) - { - return to_lower(c); - } - }; + return to_lower(c); + } //******************************************* - template <> - struct character_set + ETL_NODISCARD + ETL_CONSTEXPR14 + static char convert(wchar_t c) { typedef wchar_t value_type; typedef const value_type* string_type; - static ETL_CONSTANT string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF"; - ETL_NODISCARD - ETL_CONSTEXPR14 - static char lookup(wchar_t c) +#if ETL_USING_CPP14 + constexpr string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF"; +#else + static const string_type valid_chars = L"+-.,eE0123456789abcdefABCDEF"; +#endif + + for (int i = 0; i < valid_length; ++i) { - for (int i = 0; i < valid_length; ++i) + if (c == valid_chars[i]) { - if (c == valid_chars[i]) - { - return to_lower(valid_character_set::valid_chars[i]); - } + return to_lower(valid_character_set::valid_chars[i]); } - - return valid_character_set::unknown_char; } - }; + + return valid_character_set::unknown_char; + } //******************************************* - template <> - struct character_set + ETL_NODISCARD + ETL_CONSTEXPR14 + static char convert(char16_t c) { typedef char16_t value_type; typedef const value_type* string_type; - static ETL_CONSTANT string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF"; - ETL_NODISCARD - ETL_CONSTEXPR14 - static char lookup(char16_t c) +#if ETL_USING_CPP14 + constexpr string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF"; +#else + static const string_type valid_chars = u"+-.,eE0123456789abcdefABCDEF"; +#endif + + for (int i = 0; i < valid_length; ++i) { - for (int i = 0; i < valid_length; ++i) + if (c == valid_chars[i]) { - if (c == valid_chars[i]) - { - return to_lower(valid_character_set::valid_chars[i]); - } + return to_lower(valid_character_set::valid_chars[i]); } - - return valid_character_set::unknown_char; } - }; + return valid_character_set::unknown_char; + } + //******************************************* - template <> - struct character_set + ETL_NODISCARD + ETL_CONSTEXPR14 + static char convert(char32_t c) { typedef char32_t value_type; typedef const value_type* string_type; - static ETL_CONSTANT string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF"; + +#if ETL_USING_CPP14 + constexpr string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF"; +#else + static const string_type valid_chars = U"+-.,eE0123456789abcdefABCDEF"; +#endif - ETL_NODISCARD - ETL_CONSTEXPR14 - static char lookup(wchar_t c) + for (int i = 0; i < valid_length; ++i) { - for (int i = 0; i < valid_length; ++i) + if (c == valid_chars[i]) { - if (c == valid_chars[i]) - { - return to_lower(valid_character_set::valid_chars[i]); - } + return to_lower(valid_character_set::valid_chars[i]); } - - return valid_character_set::unknown_char; } - }; + + return valid_character_set::unknown_char; + } //*************************************************************************** /// @@ -304,12 +301,29 @@ namespace etl return value; } + //*************************************************************************** + /// + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, TValue>::type + accumulate_value(TValue value, char digit, bool is_negative) + { + value *= etl::radix::decimal; + is_negative ? value -= digit : value += digit; + + return value; + } + //******************************************* template + ETL_NODISCARD + ETL_CONSTEXPR14 bool check_has_negative_prefix(etl::basic_string_view& view) { // Check for prefix. - const char c = character_set::lookup(view[0]); + const char c = character_set::convert(view[0]); const bool has_positive_prefix = (c == valid_character_set::positive_char); const bool has_negative_prefix = (c == valid_character_set::negative_char); @@ -356,12 +370,16 @@ namespace etl } //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 bool has_value() const { return (valid_value == true); } //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 TValue get_value() const { return value; @@ -374,6 +392,61 @@ namespace etl bool valid_value; etl::radix::value_type radix; }; + + //*************************************************************************** + /// + //*************************************************************************** + template + struct to_float_implementation + { + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + to_float_implementation(bool is_negative_) + : value(0) + , is_negative(is_negative_) + , valid_value(false) + { + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool add(char c) + { + bool is_valid = valid_character_set::is_valid(c, etl::radix::decimal); + + if (is_valid) + { + value = accumulate_value(value, valid_character_set::digit_value(c, etl::radix::decimal), is_negative); + valid_value = true; + } + + return is_valid; + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool has_value() const + { + return (valid_value == true); + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + TValue get_value() const + { + return value; + } + + private: + + TValue value; + bool is_negative; + bool valid_value; + }; //*************************************************************************** /// Text to integral from view and radix value type. @@ -401,7 +474,7 @@ namespace etl while (parsing) { - parsing = implementation.add(character_set::lookup(*itr)); + parsing = implementation.add(character_set::convert(*itr)); if (parsing) { @@ -458,7 +531,7 @@ namespace etl while (parsing) { - parsing = implementation.add(character_set::lookup(*itr)); + parsing = implementation.add(character_set::convert(*itr)); if (parsing) { @@ -513,7 +586,7 @@ namespace etl while (parsing) { - parsing = implementation.add(character_set::lookup(*itr)); + parsing = implementation.add(character_set::convert(*itr)); if (parsing) { @@ -570,7 +643,7 @@ namespace etl while (parsing) { - parsing = implementation.add(character_set::lookup(*itr)); + parsing = implementation.add(character_set::convert(*itr)); if (parsing) { @@ -800,81 +873,27 @@ namespace etl using namespace etl::private_to_arithmetic; etl::optional result; - etl::basic_string_view valid_characters; - view_information view_info; - numeric_information numeric_info; - bool parsing = validate_information_from_view(view, etl::radix::decimal, view_info, numeric_info); + bool is_negative = false; - if (parsing) + if (!view.empty()) { - // Integral part. - etl::basic_string_view::const_iterator itr_integral_begin = view.begin(); - etl::basic_string_view::const_iterator itr_integral_end = (numeric_info.radix_point_position == etl::npos) - ? view.end() - : itr_integral_begin + numeric_info.radix_point_position; + is_negative = check_has_negative_prefix(view); + } - TValue intergal_value = 0; - - while (itr_integral_begin != itr_integral_end) - { - if (is_valid_decimal_character(*itr_integral_begin)) - { - numeric_info.digit = get_digit_value(*itr_integral_begin); - intergal_value = accumulate_integral_part(intergal_value, numeric_info); - ++itr_integral_begin; - } - else - { - // Character was not a valid numeric, so fail. - ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format)); - parsing = false; - itr_integral_begin = itr_integral_end; - } - } - - // Fractional part. - etl::basic_string_view::const_reverse_iterator itr_fractional_end = ETL_OR_STD::reverse_iterator(itr_integral_begin + 1); - etl::basic_string_view::const_reverse_iterator itr_fractional_begin = (numeric_info.radix_point_position == etl::npos) - ? itr_fractional_end - : (numeric_info.exponential_position == etl::npos) - ? view.rbegin() - : ETL_OR_STD::reverse_iterator(view.begin() + numeric_info.exponential_position); - - TValue fractional_value = 0; - - while (itr_fractional_begin != itr_fractional_end) - { - if (is_valid_decimal_character(*itr_fractional_begin)) - { - numeric_info.digit = get_digit_value(*itr_fractional_begin); - fractional_value = accumulate_fractional_part(fractional_value, numeric_info); - ++itr_fractional_begin; - } - else - { - // Character was not a valid numeric, so fail. - ETL_ASSERT_FAIL(ETL_ERROR(etl::to_arithmetic_invalid_format)); - parsing = false; - itr_fractional_begin = itr_fractional_end; - } - } - - // Exponetial part. - etl::basic_string_view::const_iterator itr_exponential_end = view.end(); - etl::basic_string_view::const_iterator itr_exponential_begin = (numeric_info.exponential_position == etl::npos) - ? view.end() - : view.begin() + numeric_info.exponential_position + 1; - - //optional exponential_value = to_arithmetic(etl::basic_string_view(itr_exponential_begin, itr_exponential_end)); - - // Combine the integral and fractional parts. - TValue value = 0; + if (!view.empty()) + { + bool parsing = true; if (parsing) { - value = intergal_value + fractional_value; - result = value; + // Integral part. + + + // Fractional part. + + // Exponetial part. + } } diff --git a/test/test_string_to_arithmetic.cpp b/test/test_string_to_arithmetic.cpp index 8d5b0ac7..5dcd432e 100644 --- a/test/test_string_to_arithmetic.cpp +++ b/test/test_string_to_arithmetic.cpp @@ -262,20 +262,20 @@ namespace } //************************************************************************* - //TEST(test_valid_float) - //{ - // const std::string text1("-123.456789"); + TEST(test_valid_float) + { + const std::string text1("-123.456789"); - // float f1 = strtof(text1.c_str(), nullptr); - // float f2 = etl::to_arithmetic(text1.c_str(), text1.size()).value(); + float f1 = strtof(text1.c_str(), nullptr); + float f2 = etl::to_arithmetic(text1.c_str(), text1.size()).value(); - // CHECK_EQUAL(f1, f2); + CHECK_EQUAL(f1, f2); - // const std::string text2("-1.23456789e2"); - // float f3 = etl::to_arithmetic(text2.c_str(), text2.size()).value(); + const std::string text2("-1.23456789e2"); + float f3 = etl::to_arithmetic(text2.c_str(), text2.size()).value(); - // CHECK_EQUAL(f1, f3); - //} + CHECK_EQUAL(f1, f3); + } //************************************************************************* //TEST(test_valid_double) @@ -289,16 +289,16 @@ namespace //} //************************************************************************* - //TEST(test_constexpr_integral) - //{ - // constexpr const char* text{ "123" }; - // constexpr etl::string_view view(text, 3); + TEST(test_constexpr_integral) + { + constexpr const char* text{ "123" }; + constexpr etl::string_view view(text, 3); - // constexpr etl::optional opt = etl::to_arithmetic(view, etl::radix::decimal); - // constexpr int i = opt.value(); + constexpr etl::optional opt = etl::to_arithmetic(view, etl::radix::decimal); + constexpr int i = opt.value(); - // CHECK_EQUAL(123, i); - //} + CHECK_EQUAL(123, i); + } //************************************************************************* TEST(test_constexpr_floating_point)