30#ifndef ETL_TO_ARITHMETIC_INCLUDED
31#define ETL_TO_ARITHMETIC_INCLUDED
66 ETL_ENUM_TYPE(Valid,
"Valid")
67 ETL_ENUM_TYPE(Invalid_Radix,
"Invalid Radix")
68 ETL_ENUM_TYPE(Invalid_Format,
"Invalid Format")
69 ETL_ENUM_TYPE(Invalid_Float,
"Invalid Float")
70 ETL_ENUM_TYPE(Signed_To_Unsigned,
"Signed To Unsigned")
71 ETL_ENUM_TYPE(Overflow,
"Overflow")
78 template<
typename TValue>
83 typedef TValue value_type;
92 : conversion_value(static_cast<value_type>(0))
102 : conversion_value(other.conversion_value)
103 , conversion_status(other.conversion_status)
114 return (conversion_status.
error() == error_type::Valid);
122 operator bool()
const
135 return conversion_value;
144 operator value_type()
const
172 conversion_value = value_;
183 conversion_status = status_;
190 value_type conversion_value;
191 unexpected_type conversion_status;
194 namespace private_to_arithmetic
196 template <
typename T =
void>
199 static ETL_CONSTANT
char Positive_Char =
'+';
200 static ETL_CONSTANT
char Negative_Char =
'-';
201 static ETL_CONSTANT
char Radix_Point1_Char =
'.';
202 static ETL_CONSTANT
char Radix_Point2_Char =
',';
203 static ETL_CONSTANT
char Exponential_Char =
'e';
206 template <
typename T>
209 template <
typename T>
212 template <
typename T>
215 template <
typename T>
218 template <
typename T>
229 bool is_valid(
char c, etl::radix::value_type
radix)
233 case etl::radix::binary:
235 return (c >=
'0') && (c <=
'1');
239 case etl::radix::octal:
241 return (c >=
'0') && (c <=
'7');
245 case etl::radix::decimal:
247 return (c >=
'0') && (c <=
'9');
251 case etl::radix::hex:
253 return ((c >=
'0') && (c <=
'9')) || ((c >=
'a') && (c <=
'f'));
269 char digit_value(
char c, etl::radix::value_type radix)
273 case etl::radix::binary:
274 case etl::radix::octal:
275 case etl::radix::decimal:
281 case etl::radix::hex:
283 if ((c >=
'0') && (c <=
'9'))
289 return (c -
'a') + 10;
306 char to_lower(
char c)
308 if ((c >=
'A') && (c <=
'Z'))
317 template <
typename TChar>
320 char convert(TChar c)
322 return to_lower(
static_cast<char>(c));
329 template <
typename TChar>
337 const char c = convert(view[0]);
338 const bool has_positive_prefix = (c == char_constant::Positive_Char);
339 const bool has_negative_prefix = (c == char_constant::Negative_Char);
342 if (has_positive_prefix || has_negative_prefix)
345 return has_negative_prefix;
360 return (
radix == etl::radix::binary) ||
361 (
radix == etl::radix::octal) ||
362 (
radix == etl::radix::decimal) ||
363 (
radix == etl::radix::hex);
369 template <
typename TValue>
378 , conversion_status(to_arithmetic_status::Valid)
385 bool add(
const char c)
387 bool is_success =
false;
388 bool is_not_overflow =
false;
390 const bool is_valid_char = is_valid(c,
radix);
394 TValue old_value = integral_value;
395 integral_value *=
radix;
398 is_not_overflow = ((integral_value /
radix) == old_value);
402 const char digit = digit_value(c,
radix);
405 is_not_overflow = ((maximum - digit) >= integral_value);
407 if ((maximum - digit) >= integral_value)
409 integral_value += digit;
416 if (is_valid_char ==
false)
418 conversion_status = to_arithmetic_status::Invalid_Format;
420 else if (is_not_overflow ==
false)
422 conversion_status = to_arithmetic_status::Overflow;
431 bool has_value()
const
433 return conversion_status == to_arithmetic_status::Valid;
441 return integral_value;
449 return conversion_status;
454 etl::radix::value_type
radix;
456 TValue integral_value;
469 , floating_point_value(0)
470 , is_negative_mantissa(
false)
471 , is_negative_exponent(
false)
472 , expecting_sign(
true)
474 , state(Parsing_Integral)
475 , conversion_status(to_arithmetic_status::Valid)
484 bool is_success =
true;
489 case Parsing_Integral:
491 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
493 is_negative_mantissa = (c == char_constant::Negative_Char);
494 expecting_sign =
false;
497 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
499 expecting_sign =
false;
500 state = Parsing_Fractional;
503 else if (c == char_constant::Exponential_Char)
505 expecting_sign =
true;
506 state = Parsing_Exponential;
508 else if (is_valid(c, etl::radix::decimal))
510 const char digit = digit_value(c, etl::radix::decimal);
511 floating_point_value *= 10;
512 is_negative_mantissa ? floating_point_value -= digit : floating_point_value += digit;
513 conversion_status = to_arithmetic_status::Valid;
514 expecting_sign =
false;
518 conversion_status = to_arithmetic_status::Invalid_Format;
525 case Parsing_Fractional:
528 if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
530 conversion_status = to_arithmetic_status::Invalid_Format;
534 else if (c == char_constant::Exponential_Char)
536 expecting_sign =
true;
537 state = Parsing_Exponential;
539 else if (is_valid(c, etl::radix::decimal))
541 const char digit = digit_value(c, etl::radix::decimal);
543 long double fraction = digit / divisor;
544 is_negative_mantissa ? floating_point_value -= fraction : floating_point_value += fraction;
545 conversion_status = to_arithmetic_status::Valid;
549 conversion_status = to_arithmetic_status::Invalid_Format;
556 case Parsing_Exponential:
558 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
560 is_negative_exponent = (c == char_constant::Negative_Char);
561 expecting_sign =
false;
564 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char) || (c == char_constant::Exponential_Char))
566 conversion_status = to_arithmetic_status::Invalid_Format;
569 else if (is_valid(c, etl::radix::decimal))
571 const char digit = digit_value(c, etl::radix::decimal);
572 exponent_value *= etl::radix::decimal;
573 is_negative_exponent ? exponent_value -= digit : exponent_value += digit;
577 conversion_status = to_arithmetic_status::Invalid_Format;
597 bool has_value()
const
599 return (conversion_status == to_arithmetic_status::Valid);
605 long double value()
const
607 return floating_point_value;
615 return conversion_status;
623 return exponent_value;
636 long double floating_point_value;
637 bool is_negative_mantissa;
638 bool is_negative_exponent;
648 template <
size_t Bits>
654 typedef uint32_t type;
660 typedef uint32_t type;
666 typedef uint32_t type;
669#if ETL_USING_64BIT_TYPES
673 typedef uint64_t type;
680 template <
typename TChar,
typename TAccumulatorType>
684 const etl::radix::value_type
radix,
685 const TAccumulatorType maximum)
690 typename etl::basic_string_view<TChar>::const_iterator itr = view.
begin();
691 const typename etl::basic_string_view<TChar>::const_iterator itr_end = view.
end();
695 while ((itr != itr_end) && accumulator.add(convert(*itr)))
701 if (accumulator.has_value())
703 accumulator_result = accumulator.value();
707 accumulator_result = unexpected_type(accumulator.status());
710 return accumulator_result;
717 template <
typename TValue,
typename TChar>
722 const etl::radix::value_type
radix)
724 using namespace etl::private_to_arithmetic;
727 typedef typename result_type::unexpected_type unexpected_type;
731 if (is_valid_radix(
radix))
734 const bool is_negative = check_and_remove_sign_prefix(view);
738 result = unexpected_type(to_arithmetic_status::Invalid_Format);
745 result = unexpected_type(to_arithmetic_status::Signed_To_Unsigned);
749 const bool is_decimal = (
radix == etl::radix::decimal);
761 result = unexpected_type(accumulator_result.
error());
766 typedef typename etl::make_unsigned<TValue>::type uvalue_t;
767 const uvalue_t uvalue =
static_cast<uvalue_t
>(accumulator_result.
value());
770 result = (is_negative ?
static_cast<TValue
>(0) - uvalue : etl::bit_cast<TValue>(uvalue));
777 result = unexpected_type(to_arithmetic_status::Invalid_Radix);
786 template <
typename TValue,
typename TChar>
792 return etl::to_arithmetic<TValue, TChar>(view, etl::radix::decimal);
798 template <
typename TValue,
typename TChar>
804 return etl::to_arithmetic<TValue, TChar>(view, spec.base);
810 template <
typename TValue,
typename TChar>
822 template <
typename TValue,
typename TChar>
834 template <
typename TValue,
typename TChar>
846 template <
typename TValue,
typename TChar>
858 template <
typename TValue,
typename TChar>
870 template <
typename TValue,
typename TChar>
882 template <
typename TValue,
typename TChar>
888 using namespace etl::private_to_arithmetic;
891 typedef typename result_type::unexpected_type unexpected_type;
897 result = unexpected_type(to_arithmetic_status::Invalid_Format);
903 typename etl::basic_string_view<TChar>::const_iterator itr = view.
begin();
904 const typename etl::basic_string_view<TChar>::const_iterator itr_end = view.
end();
906 while ((itr != itr_end) && accumulator.add(convert(*itr)))
912 result = unexpected_type(accumulator.status());
914 if (result.has_value())
916 TValue value =
static_cast<TValue
>(accumulator.value());
917 int exponent = accumulator.exponent();
919 value *= pow(
static_cast<TValue
>(10.0),
static_cast<TValue
>(exponent));
925 result = unexpected_type(to_arithmetic_status::Overflow);
928 else if (value != value)
930 result = unexpected_type(to_arithmetic_status::Invalid_Float);
945 template <
typename TValue,
typename TChar>
957 template <
typename TValue,
typename TChar>
969 template <
typename TValue,
typename TChar>
991 return (lhs.status() == rhs.status());
998template <
typename T,
typename U>
1001 return bool(lhs) ? lhs.
value() == rhs :
false;
1007template <
typename T,
typename U>
1010 return bool(rhs) ? rhs.
value() == lhs :
false;
1016template <
typename T>
1019 return !(lhs == rhs);
1025template <
typename T,
typename U>
1028 return !(lhs == rhs);
1034template <
typename T,
typename U>
1037 return !(lhs == rhs);
String view.
Definition: string_view.h:96
ETL_CONSTEXPR const_iterator begin() const
Returns a const iterator to the beginning of the array.
Definition: string_view.h:193
ETL_CONSTEXPR14 void remove_prefix(size_type n)
Shrinks the view by moving its start forward.
Definition: string_view.h:384
ETL_CONSTEXPR bool empty() const
Returns true if the array size is zero.
Definition: string_view.h:261
ETL_CONSTEXPR const_iterator end() const
Returns a const iterator to the end of the array.
Definition: string_view.h:209
Definition: basic_string.h:326
Definition: limits.h:1164
Status values for to_arithmetic.
Definition: to_arithmetic.h:80
ETL_CONSTEXPR14 to_arithmetic_result(const to_arithmetic_result &other)
Copy constructor.
Definition: to_arithmetic.h:101
ETL_CONSTEXPR14 to_arithmetic_result & operator=(value_type value_)
Assignment from a value.
Definition: to_arithmetic.h:170
ETL_NODISCARD ETL_CONSTEXPR14 error_type error() const
Definition: to_arithmetic.h:161
ETL_NODISCARD ETL_CONSTEXPR14 value_type value() const
Definition: to_arithmetic.h:133
ETL_CONSTEXPR14 to_arithmetic_result()
Default constructor.
Definition: to_arithmetic.h:91
ETL_NODISCARD ETL_CONSTEXPR14 bool has_value() const
Returns true if the result has a valid value.
Definition: to_arithmetic.h:112
const TError & error() const
Get the error.
Definition: expected.h:216
Definition: integral_limits.h:468
enable_if
Definition: type_traits_generator.h:1191
is_unsigned
Definition: type_traits_generator.h:1021
bitset_ext
Definition: absolute.h:38
ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if< etl::is_integral< TValue >::value, etl::to_arithmetic_result< TValue > >::type to_arithmetic(etl::basic_string_view< TChar > view, const etl::radix::value_type radix)
Text to integral from view and radix value type.
Definition: to_arithmetic.h:721
Definition: to_arithmetic.h:649
Definition: to_arithmetic.h:222
Definition: to_arithmetic.h:198
Accumulate floating point.
Definition: to_arithmetic.h:464
Accumulate integrals.
Definition: to_arithmetic.h:371
Status values for to_arithmetic.
Definition: to_arithmetic.h:54
ETL_CONSTEXPR14 bool operator==(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Equality test for etl::to_arithmetic_result.
Definition: to_arithmetic.h:983
ETL_CONSTEXPR14 bool operator!=(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Inequality test for etl::to_arithmetic_result.
Definition: to_arithmetic.h:1017
ETL_NODISCARD ETL_CONSTEXPR14 bool check_and_remove_sign_prefix(etl::basic_string_view< TChar > &view)
Definition: to_arithmetic.h:332
ETL_NODISCARD ETL_CONSTEXPR14 etl::to_arithmetic_result< TAccumulatorType > to_arithmetic_integral(const etl::basic_string_view< TChar > &view, const etl::radix::value_type radix, const TAccumulatorType maximum)
Text to integral from view, radix value and maximum.
Definition: to_arithmetic.h:683
ETL_NODISCARD ETL_CONSTEXPR14 bool is_valid_radix(const etl::radix::value_type radix)
Checks to see if the radix is valid.
Definition: to_arithmetic.h:358