30#ifndef ETL_TO_ARITHMETIC_INCLUDED
31#define ETL_TO_ARITHMETIC_INCLUDED
69 ETL_ENUM_TYPE(Valid,
"Valid")
70 ETL_ENUM_TYPE(Invalid_Radix,
"Invalid Radix")
71 ETL_ENUM_TYPE(Invalid_Format,
"Invalid Format")
72 ETL_ENUM_TYPE(Invalid_Float,
"Invalid Float")
73 ETL_ENUM_TYPE(Signed_To_Unsigned,
"Signed To Unsigned")
74 ETL_ENUM_TYPE(Overflow,
"Overflow")
81 template<
typename TValue>
86 typedef TValue value_type;
95 : conversion_value(static_cast<value_type>(0))
96 , conversion_status(error_type::Valid)
105 : conversion_value(other.conversion_value)
106 , conversion_status(other.conversion_status)
117 return (conversion_status.error() == error_type::Valid);
125 operator bool()
const
138 return conversion_value;
147 operator value_type()
const
175 conversion_value = value_;
186 conversion_status = status_;
194 unexpected_type conversion_status;
197 namespace private_to_arithmetic
199 template <
typename T =
void>
202 static ETL_CONSTANT
char Positive_Char =
'+';
203 static ETL_CONSTANT
char Negative_Char =
'-';
204 static ETL_CONSTANT
char Radix_Point1_Char =
'.';
205 static ETL_CONSTANT
char Radix_Point2_Char =
',';
206 static ETL_CONSTANT
char Exponential_Char =
'e';
209 template <
typename T>
210 ETL_CONSTANT
char char_statics<T>::Positive_Char;
212 template <
typename T>
213 ETL_CONSTANT
char char_statics<T>::Negative_Char;
215 template <
typename T>
216 ETL_CONSTANT
char char_statics<T>::Radix_Point1_Char;
218 template <
typename T>
219 ETL_CONSTANT
char char_statics<T>::Radix_Point2_Char;
221 template <
typename T>
222 ETL_CONSTANT
char char_statics<T>::Exponential_Char;
232 bool is_valid(
char c, etl::radix::value_type
radix)
236 case etl::radix::binary:
238 return (c >=
'0') && (c <=
'1');
241 case etl::radix::octal:
243 return (c >=
'0') && (c <=
'7');
246 case etl::radix::decimal:
248 return (c >=
'0') && (c <=
'9');
251 case etl::radix::hexadecimal:
253 return ((c >=
'0') && (c <=
'9')) || ((c >=
'a') && (c <=
'f'));
267 char digit_value(
char c, etl::radix::value_type radix)
271 case etl::radix::binary:
272 case etl::radix::octal:
273 case etl::radix::decimal:
278 case etl::radix::hexadecimal:
280 if ((c >=
'0') && (c <=
'9'))
286 return (c -
'a') + 10;
301 char to_lower(
char c)
303 if ((c >=
'A') && (c <=
'Z'))
312 template <
typename TChar>
315 char convert(TChar c)
317 return to_lower(
static_cast<char>(c));
324 template <
typename TChar>
332 const char c = convert(view[0]);
333 const bool has_positive_prefix = (c == char_constant::Positive_Char);
334 const bool has_negative_prefix = (c == char_constant::Negative_Char);
337 if (has_positive_prefix || has_negative_prefix)
340 return has_negative_prefix;
355 return (
radix == etl::radix::binary) ||
356 (
radix == etl::radix::octal) ||
357 (
radix == etl::radix::decimal) ||
358 (
radix == etl::radix::hexadecimal);
364 template <
typename TValue>
365 struct integral_accumulator
369 integral_accumulator(etl::radix::value_type radix_, TValue maximum_)
373 , conversion_status(to_arithmetic_status::Valid)
380 bool add(
const char c)
382 bool is_success =
false;
383 bool is_not_overflow =
false;
385 const bool is_valid_char = is_valid(c, radix);
389 TValue old_value = integral_value;
390 integral_value *= radix;
393 is_not_overflow = ((integral_value / radix) == old_value);
397 const char digit = digit_value(c, radix);
400 is_not_overflow = ((maximum - digit) >= integral_value);
402 if ((maximum - digit) >= integral_value)
404 integral_value += digit;
411 if (is_valid_char ==
false)
413 conversion_status = to_arithmetic_status::Invalid_Format;
415 else if (is_not_overflow ==
false)
417 conversion_status = to_arithmetic_status::Overflow;
426 bool has_value()
const
428 return conversion_status == to_arithmetic_status::Valid;
436 return integral_value;
444 return conversion_status;
449 etl::radix::value_type radix;
451 TValue integral_value;
458 struct floating_point_accumulator
462 floating_point_accumulator()
464 , floating_point_value(0)
465 , is_negative_mantissa(
false)
466 , is_negative_exponent(
false)
467 , expecting_sign(
true)
469 , state(Parsing_Integral)
470 , conversion_status(to_arithmetic_status::Valid)
479 bool is_success =
true;
484 case Parsing_Integral:
486 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
488 is_negative_mantissa = (c == char_constant::Negative_Char);
489 expecting_sign =
false;
492 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
494 expecting_sign =
false;
495 state = Parsing_Fractional;
498 else if (c == char_constant::Exponential_Char)
500 expecting_sign =
true;
501 state = Parsing_Exponential;
503 else if (is_valid(c, etl::radix::decimal))
505 const char digit = digit_value(c, etl::radix::decimal);
506 floating_point_value *= 10;
507 is_negative_mantissa ? floating_point_value -= digit : floating_point_value += digit;
508 conversion_status = to_arithmetic_status::Valid;
509 expecting_sign =
false;
513 conversion_status = to_arithmetic_status::Invalid_Format;
520 case Parsing_Fractional:
523 if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
525 conversion_status = to_arithmetic_status::Invalid_Format;
529 else if (c == char_constant::Exponential_Char)
531 expecting_sign =
true;
532 state = Parsing_Exponential;
534 else if (is_valid(c, etl::radix::decimal))
536 const char digit = digit_value(c, etl::radix::decimal);
538 long double fraction = digit / divisor;
539 is_negative_mantissa ? floating_point_value -= fraction : floating_point_value += fraction;
540 conversion_status = to_arithmetic_status::Valid;
544 conversion_status = to_arithmetic_status::Invalid_Format;
551 case Parsing_Exponential:
553 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
555 is_negative_exponent = (c == char_constant::Negative_Char);
556 expecting_sign =
false;
559 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char) || (c == char_constant::Exponential_Char))
561 conversion_status = to_arithmetic_status::Invalid_Format;
564 else if (is_valid(c, etl::radix::decimal))
566 const char digit = digit_value(c, etl::radix::decimal);
567 exponent_value *= etl::radix::decimal;
568 is_negative_exponent ? exponent_value -= digit : exponent_value += digit;
572 conversion_status = to_arithmetic_status::Invalid_Format;
592 bool has_value()
const
594 return (conversion_status == to_arithmetic_status::Valid);
600 long double value()
const
602 return floating_point_value;
610 return conversion_status;
618 return exponent_value;
631 long double floating_point_value;
632 bool is_negative_mantissa;
633 bool is_negative_exponent;
643 template <
size_t Bits>
649 typedef uint32_t type;
655 typedef uint32_t type;
661 typedef uint32_t type;
664#if ETL_USING_64BIT_TYPES
668 typedef uint64_t type;
675 template <
typename TChar,
typename TAccumulatorType>
679 const etl::radix::value_type
radix,
680 const TAccumulatorType maximum)
685 typename etl::basic_string_view<TChar>::const_iterator itr = view.
begin();
686 const typename etl::basic_string_view<TChar>::const_iterator itr_end = view.
end();
690 while ((itr != itr_end) && accumulator.add(convert(*itr)))
696 if (accumulator.has_value())
698 accumulator_result = accumulator.value();
702 accumulator_result = unexpected_type(accumulator.status());
705 return accumulator_result;
712 template <
typename TValue,
typename TChar>
717 const etl::radix::value_type
radix)
719 using namespace etl::private_to_arithmetic;
722 typedef typename result_type::unexpected_type unexpected_type;
733 result = unexpected_type(to_arithmetic_status::Invalid_Format);
740 result = unexpected_type(to_arithmetic_status::Signed_To_Unsigned);
744 const bool is_decimal = (
radix == etl::radix::decimal);
756 result = unexpected_type(accumulator_result.
error());
762 const uvalue_t uvalue =
static_cast<uvalue_t
>(accumulator_result.
value());
772 result = unexpected_type(to_arithmetic_status::Invalid_Radix);
781 template <
typename TValue,
typename TChar>
793 template <
typename TValue,
typename TChar>
805 template <
typename TValue,
typename TChar>
817 template <
typename TValue,
typename TChar>
829 template <
typename TValue,
typename TChar>
841 template <
typename TValue,
typename TChar>
853 template <
typename TValue,
typename TChar>
865 template <
typename TValue,
typename TChar>
877 template <
typename TValue,
typename TChar>
883 using namespace etl::private_to_arithmetic;
886 typedef typename result_type::unexpected_type unexpected_type;
892 result = unexpected_type(to_arithmetic_status::Invalid_Format);
898 typename etl::basic_string_view<TChar>::const_iterator itr = view.
begin();
899 const typename etl::basic_string_view<TChar>::const_iterator itr_end = view.
end();
901 while ((itr != itr_end) && accumulator.add(convert(*itr)))
907 result = unexpected_type(accumulator.status());
909 if (result.has_value())
911 TValue value =
static_cast<TValue
>(accumulator.value());
912 int exponent = accumulator.exponent();
914 value *= pow(
static_cast<TValue
>(10.0),
static_cast<TValue
>(exponent));
917 if (etl::is_infinity(value))
919 result = unexpected_type(to_arithmetic_status::Overflow);
921 else if (etl::is_nan(value))
923 result = unexpected_type(to_arithmetic_status::Invalid_Float);
938 template <
typename TValue,
typename TChar>
950 template <
typename TValue,
typename TChar>
962 template <
typename TValue,
typename TChar>
984 return (lhs.status() == rhs.status());
991template <
typename T,
typename U>
994 return bool(lhs) ? lhs.
value() == rhs :
false;
1000template <
typename T,
typename U>
1003 return bool(rhs) ? rhs.
value() == lhs :
false;
1009template <
typename T>
1012 return !(lhs == rhs);
1018template <
typename T,
typename U>
1021 return !(lhs == rhs);
1027template <
typename T,
typename U>
1030 return !(lhs == rhs);
String view.
Definition string_view.h:104
ETL_CONSTEXPR14 void remove_prefix(size_type n) ETL_NOEXCEPT
Shrinks the view by moving its start forward.
Definition string_view.h:395
ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT
Returns a const iterator to the end of the array.
Definition string_view.h:220
ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition string_view.h:204
ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the array size is zero.
Definition string_view.h:272
Definition basic_string.h:351
Status values for to_arithmetic.
Definition to_arithmetic.h:83
ETL_CONSTEXPR14 to_arithmetic_result(const to_arithmetic_result &other)
Copy constructor.
Definition to_arithmetic.h:104
ETL_CONSTEXPR14 to_arithmetic_result & operator=(value_type value_)
Assignment from a value.
Definition to_arithmetic.h:173
ETL_NODISCARD ETL_CONSTEXPR14 error_type error() const
Definition to_arithmetic.h:164
ETL_NODISCARD ETL_CONSTEXPR14 value_type value() const
Definition to_arithmetic.h:136
ETL_CONSTEXPR14 to_arithmetic_result()
Default constructor.
Definition to_arithmetic.h:94
ETL_NODISCARD ETL_CONSTEXPR14 bool has_value() const
Returns true if the result has a valid value.
Definition to_arithmetic.h:115
#define ETL_DECLARE_ENUM_TYPE(TypeName, ValueType)
Definition enum_type.h:85
Definition integral_limits.h:516
enable_if
Definition type_traits_generator.h:1254
is_unsigned
Definition type_traits_generator.h:1084
make_unsigned
Definition type_traits_generator.h:1244
bitset_ext
Definition absolute.h:39
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:716
ETL_NODISCARD etl::enable_if<!(etl::is_integral< TDestination >::value &&etl::is_integral< TSource >::value)&&(sizeof(TDestination)==sizeof(TSource))&&etl::is_trivially_copyable< TSource >::value &&etl::is_trivially_copyable< TDestination >::value, TDestination >::type bit_cast(const TSource &source) ETL_NOEXCEPT
bit_cast - Type to different type.
Definition bit.h:58
ETL_CONSTEXPR14 size_t strlen(const T *t) ETL_NOEXCEPT
Alternative strlen for all character types.
Definition char_traits.h:287
Definition to_arithmetic.h:644
Definition to_arithmetic.h:225
Definition to_arithmetic.h:201
Accumulate floating point.
Definition to_arithmetic.h:459
Accumulate integrals.
Definition to_arithmetic.h:366
Status values for to_arithmetic.
Definition to_arithmetic.h:57
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:976
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:1010
ETL_NODISCARD ETL_CONSTEXPR14 bool check_and_remove_sign_prefix(etl::basic_string_view< TChar > &view)
Definition to_arithmetic.h:327
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:678
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:353