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;
94 : conversion_value(static_cast<value_type>(0))
95 , conversion_status(error_type::Valid)
103 : conversion_value(other.conversion_value)
104 , conversion_status(other.conversion_status)
113 return (conversion_status.error() == error_type::Valid);
119 ETL_NODISCARD ETL_CONSTEXPR14
operator bool()
const
128 ETL_NODISCARD ETL_CONSTEXPR14 value_type
value()
const
130 return conversion_value;
137 ETL_NODISCARD ETL_CONSTEXPR14
operator value_type()
const
152 ETL_NODISCARD ETL_CONSTEXPR14 error_type
error()
const
162 conversion_value = value_;
172 conversion_status = status_;
180 unexpected_type conversion_status;
183 namespace private_to_arithmetic
185 template <
typename T =
void>
188 static ETL_CONSTANT
char Positive_Char =
'+';
189 static ETL_CONSTANT
char Negative_Char =
'-';
190 static ETL_CONSTANT
char Radix_Point1_Char =
'.';
191 static ETL_CONSTANT
char Radix_Point2_Char =
',';
192 static ETL_CONSTANT
char Exponential_Char =
'e';
195 template <
typename T>
196 ETL_CONSTANT
char char_statics<T>::Positive_Char;
198 template <
typename T>
199 ETL_CONSTANT
char char_statics<T>::Negative_Char;
201 template <
typename T>
202 ETL_CONSTANT
char char_statics<T>::Radix_Point1_Char;
204 template <
typename T>
205 ETL_CONSTANT
char char_statics<T>::Radix_Point2_Char;
207 template <
typename T>
208 ETL_CONSTANT
char char_statics<T>::Exponential_Char;
217 ETL_CONSTEXPR14
bool is_valid(
char c, etl::radix::value_type
radix)
221 case etl::radix::binary:
223 return (c >=
'0') && (c <=
'1');
226 case etl::radix::octal:
228 return (c >=
'0') && (c <=
'7');
231 case etl::radix::decimal:
233 return (c >=
'0') && (c <=
'9');
236 case etl::radix::hexadecimal:
238 return ((c >=
'0') && (c <=
'9')) || ((c >=
'a') && (c <=
'f'));
251 ETL_CONSTEXPR14
char digit_value(
char c, etl::radix::value_type radix)
255 case etl::radix::binary:
256 case etl::radix::octal:
257 case etl::radix::decimal:
262 case etl::radix::hexadecimal:
264 if ((c >=
'0') && (c <=
'9'))
270 return (c -
'a') + 10;
284 ETL_CONSTEXPR14
char to_lower(
char c)
286 if ((c >=
'A') && (c <=
'Z'))
295 template <
typename TChar>
296 ETL_NODISCARD ETL_CONSTEXPR14
char convert(TChar c)
298 return to_lower(
static_cast<char>(c));
305 template <
typename TChar>
311 const char c = convert(view[0]);
312 const bool has_positive_prefix = (c == char_constant::Positive_Char);
313 const bool has_negative_prefix = (c == char_constant::Negative_Char);
316 if (has_positive_prefix || has_negative_prefix)
319 return has_negative_prefix;
333 return (
radix == etl::radix::binary) || (
radix == etl::radix::octal) || (
radix == etl::radix::decimal) || (
radix == etl::radix::hexadecimal);
339 template <
typename TValue>
340 struct integral_accumulator
343 ETL_CONSTEXPR14 integral_accumulator(etl::radix::value_type radix_, TValue maximum_)
347 , conversion_status(to_arithmetic_status::Valid)
352 ETL_NODISCARD ETL_CONSTEXPR14
bool add(
const char c)
354 bool is_success =
false;
355 bool is_not_overflow =
false;
357 const bool is_valid_char = is_valid(c, radix);
361 TValue old_value = integral_value;
362 integral_value *= radix;
365 is_not_overflow = ((integral_value / radix) == old_value);
369 const char digit = digit_value(c, radix);
372 is_not_overflow = ((maximum -
static_cast<TValue
>(digit)) >= integral_value);
374 if ((maximum -
static_cast<TValue
>(digit)) >= integral_value)
376 integral_value +=
static_cast<TValue
>(digit);
383 if (is_valid_char ==
false)
385 conversion_status = to_arithmetic_status::Invalid_Format;
387 else if (is_not_overflow ==
false)
389 conversion_status = to_arithmetic_status::Overflow;
396 ETL_NODISCARD ETL_CONSTEXPR14
bool has_value()
const
398 return conversion_status == to_arithmetic_status::Valid;
402 ETL_NODISCARD ETL_CONSTEXPR14 TValue value()
const
404 return integral_value;
410 return conversion_status;
415 etl::radix::value_type radix;
417 TValue integral_value;
424 struct floating_point_accumulator
427 ETL_CONSTEXPR14 floating_point_accumulator()
429 , floating_point_value(0)
430 , is_negative_mantissa(
false)
431 , is_negative_exponent(
false)
432 , expecting_sign(
true)
434 , state(Parsing_Integral)
435 , conversion_status(to_arithmetic_status::Valid)
440 ETL_NODISCARD ETL_CONSTEXPR14
bool add(
char c)
442 bool is_success =
true;
447 case Parsing_Integral:
449 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
451 is_negative_mantissa = (c == char_constant::Negative_Char);
452 expecting_sign =
false;
455 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
457 expecting_sign =
false;
458 state = Parsing_Fractional;
461 else if (c == char_constant::Exponential_Char)
463 expecting_sign =
true;
464 state = Parsing_Exponential;
466 else if (is_valid(c, etl::radix::decimal))
468 const char digit = digit_value(c, etl::radix::decimal);
469 floating_point_value *= 10;
470 is_negative_mantissa ? floating_point_value -= digit : floating_point_value += digit;
471 conversion_status = to_arithmetic_status::Valid;
472 expecting_sign =
false;
476 conversion_status = to_arithmetic_status::Invalid_Format;
483 case Parsing_Fractional:
486 if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
488 conversion_status = to_arithmetic_status::Invalid_Format;
492 else if (c == char_constant::Exponential_Char)
494 expecting_sign =
true;
495 state = Parsing_Exponential;
497 else if (is_valid(c, etl::radix::decimal))
499 const char digit = digit_value(c, etl::radix::decimal);
501 long double fraction = digit / divisor;
502 is_negative_mantissa ? floating_point_value -= fraction : floating_point_value += fraction;
503 conversion_status = to_arithmetic_status::Valid;
507 conversion_status = to_arithmetic_status::Invalid_Format;
514 case Parsing_Exponential:
516 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
518 is_negative_exponent = (c == char_constant::Negative_Char);
519 expecting_sign =
false;
522 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char) || (c == char_constant::Exponential_Char))
524 conversion_status = to_arithmetic_status::Invalid_Format;
527 else if (is_valid(c, etl::radix::decimal))
529 const char digit = digit_value(c, etl::radix::decimal);
530 exponent_value *= etl::radix::decimal;
531 is_negative_exponent ? exponent_value -= digit : exponent_value += digit;
535 conversion_status = to_arithmetic_status::Invalid_Format;
553 ETL_NODISCARD ETL_CONSTEXPR14
bool has_value()
const
555 return (conversion_status == to_arithmetic_status::Valid);
559 ETL_NODISCARD ETL_CONSTEXPR14
long double value()
const
561 return floating_point_value;
567 return conversion_status;
571 ETL_NODISCARD ETL_CONSTEXPR14
int exponent()
const
573 return exponent_value;
586 long double floating_point_value;
587 bool is_negative_mantissa;
588 bool is_negative_exponent;
598 template <
size_t Bits>
604 typedef uint32_t type;
610 typedef uint32_t type;
616 typedef uint32_t type;
619#if ETL_USING_64BIT_TYPES
623 typedef uint64_t type;
630 template <
typename TChar,
typename TAccumulatorType>
632 const etl::radix::value_type
radix,
const TAccumulatorType maximum)
637 typename etl::basic_string_view<TChar>::const_iterator itr = view.
begin();
638 const typename etl::basic_string_view<TChar>::const_iterator itr_end = view.
end();
642 while ((itr != itr_end) && accumulator.add(convert(*itr)))
648 if (accumulator.has_value())
650 accumulator_result = accumulator.value();
654 accumulator_result = unexpected_type(accumulator.status());
657 return accumulator_result;
664 template <
typename TValue,
typename TChar>
668 using namespace etl::private_to_arithmetic;
671 typedef typename result_type::unexpected_type unexpected_type;
682 result = unexpected_type(to_arithmetic_status::Invalid_Format);
688 if (is_negative && etl::is_unsigned<TValue>::value)
690 result = unexpected_type(to_arithmetic_status::Signed_To_Unsigned);
694 const bool is_decimal = (
radix == etl::radix::decimal);
707 result = unexpected_type(accumulator_result.
error());
712 typedef typename etl::make_unsigned<TValue>::type uvalue_t;
713 const uvalue_t uvalue =
static_cast<uvalue_t
>(accumulator_result.
value());
716 result = (is_negative ?
static_cast<TValue
>(
static_cast<TValue
>(0) -
static_cast<TValue
>(uvalue)) :
etl::bit_cast<TValue>(uvalue));
723 result = unexpected_type(to_arithmetic_status::Invalid_Radix);
732 template <
typename TValue,
typename TChar>
742 template <
typename TValue,
typename TChar>
752 template <
typename TValue,
typename TChar>
762 template <
typename TValue,
typename TChar>
773 template <
typename TValue,
typename TChar>
783 template <
typename TValue,
typename TChar>
793 template <
typename TValue,
typename TChar>
803 template <
typename TValue,
typename TChar>
813 template <
typename TValue,
typename TChar>
817 using namespace etl::private_to_arithmetic;
820 typedef typename result_type::unexpected_type unexpected_type;
826 result = unexpected_type(to_arithmetic_status::Invalid_Format);
832 typename etl::basic_string_view<TChar>::const_iterator itr = view.
begin();
833 const typename etl::basic_string_view<TChar>::const_iterator itr_end = view.
end();
835 while ((itr != itr_end) && accumulator.add(convert(*itr)))
841 result = unexpected_type(accumulator.status());
843 if (result.has_value())
845 TValue value =
static_cast<TValue
>(accumulator.value());
846 int exponent = accumulator.exponent();
848 value *= pow(
static_cast<TValue
>(10.0),
static_cast<TValue
>(exponent));
851 if (etl::is_infinity(value))
853 result = unexpected_type(to_arithmetic_status::Overflow);
855 else if (etl::is_nan(value))
857 result = unexpected_type(to_arithmetic_status::Invalid_Float);
872 template <
typename TValue,
typename TChar>
882 template <
typename TValue,
typename TChar>
891 template <
typename TValue,
typename TChar>
911 return (lhs.status() == rhs.status());
918template <
typename T,
typename U>
921 return bool(lhs) ? lhs.
value() == rhs :
false;
927template <
typename T,
typename U>
930 return bool(rhs) ? rhs.
value() == lhs :
false;
939 return !(lhs == rhs);
945template <
typename T,
typename U>
948 return !(lhs == rhs);
954template <
typename T,
typename U>
957 return !(lhs == rhs);
String view.
Definition string_view.h:117
ETL_CONSTEXPR14 void remove_prefix(size_type n) ETL_NOEXCEPT
Shrinks the view by moving its start forward.
Definition string_view.h:429
ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT
Returns a const iterator to the end of the array.
Definition string_view.h:247
ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition string_view.h:231
ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the array size is zero.
Definition string_view.h:299
Definition basic_string.h:350
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:102
ETL_CONSTEXPR14 to_arithmetic_result & operator=(value_type value_)
Assignment from a value.
Definition to_arithmetic.h:160
ETL_NODISCARD ETL_CONSTEXPR14 error_type error() const
Definition to_arithmetic.h:152
ETL_NODISCARD ETL_CONSTEXPR14 value_type value() const
Definition to_arithmetic.h:128
ETL_CONSTEXPR14 to_arithmetic_result & operator=(unexpected_type status_)
Assignment from an unexpected_type.
Definition to_arithmetic.h:170
ETL_CONSTEXPR14 to_arithmetic_result()
Default constructor.
Definition to_arithmetic.h:93
ETL_NODISCARD ETL_CONSTEXPR14 bool has_value() const
Returns true if the result has a valid value.
Definition to_arithmetic.h:111
#define ETL_DECLARE_ENUM_TYPE(TypeName, ValueType)
Definition enum_type.h:90
Definition integral_limits.h:518
bitset_ext
Definition absolute.h:40
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:666
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:55
ETL_CONSTEXPR14 size_t strlen(const T *t) ETL_NOEXCEPT
Alternative strlen for all character types.
Definition char_traits.h:293
Definition to_arithmetic.h:599
Definition to_arithmetic.h:211
Definition to_arithmetic.h:187
Accumulate floating point.
Definition to_arithmetic.h:425
Accumulate integrals.
Definition to_arithmetic.h:341
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:903
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:937
ETL_NODISCARD ETL_CONSTEXPR14 bool check_and_remove_sign_prefix(etl::basic_string_view< TChar > &view)
Definition to_arithmetic.h:306
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:631
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:331