Embedded Template Library 1.0
to_arithmetic.h
Go to the documentation of this file.
1
2/******************************************************************************
3The MIT License(MIT)
4
5Embedded Template Library.
6https://github.com/ETLCPP/etl
7https://www.etlcpp.com
8
9Copyright(c) 2022 John Wellbelove
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files(the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions :
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28******************************************************************************/
29
30#ifndef ETL_TO_ARITHMETIC_INCLUDED
31#define ETL_TO_ARITHMETIC_INCLUDED
32
33#include "platform.h"
34#include "type_traits.h"
35#include "integral_limits.h"
36#include "limits.h"
37#include "string_view.h"
38#include "basic_string.h"
39#include "format_spec.h"
40#include "radix.h"
41#include "string_utilities.h"
42#include "iterator.h"
43#include "bit.h"
44#include "smallest.h"
45#include "absolute.h"
46#include "expected.h"
47
48namespace etl
49{
50 //***************************************************************************
52 //***************************************************************************
54 {
55 enum enum_type
56 {
57 Valid,
58 Invalid_Radix,
59 Invalid_Format,
60 Invalid_Float,
61 Signed_To_Unsigned,
62 Overflow
63 };
64
65 ETL_DECLARE_ENUM_TYPE(to_arithmetic_status, int)
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")
72 ETL_END_ENUM_TYPE
73 };
74
75 //***************************************************************************
77 //***************************************************************************
78 template<typename TValue>
80 {
81 public:
82
83 typedef TValue value_type;
86
87 //*******************************************
89 //*******************************************
90 ETL_CONSTEXPR14
92 : conversion_value(static_cast<value_type>(0))
93 , conversion_status(error_type::Valid)
94 {
95 }
96
97 //*******************************************
99 //*******************************************
100 ETL_CONSTEXPR14
102 : conversion_value(other.conversion_value)
103 , conversion_status(other.conversion_status)
104 {
105 }
106
107 //*******************************************
109 //*******************************************
110 ETL_NODISCARD
111 ETL_CONSTEXPR14
112 bool has_value() const
113 {
114 return (conversion_status.error() == error_type::Valid);
115 }
116
117 //*******************************************
119 //*******************************************
120 ETL_NODISCARD
121 ETL_CONSTEXPR14
122 operator bool() const
123 {
124 return has_value();
125 }
126
127 //*******************************************
130 //*******************************************
131 ETL_NODISCARD
132 ETL_CONSTEXPR14
133 value_type value() const
134 {
135 return conversion_value;
136 }
137
138 //*******************************************
141 //*******************************************
142 ETL_NODISCARD
143 ETL_CONSTEXPR14
144 operator value_type() const
145 {
146 return value();
147 }
148
149 //*******************************************
158 //*******************************************
159 ETL_NODISCARD
160 ETL_CONSTEXPR14
162 {
163 return etl::to_arithmetic_status(conversion_status.error());
164 }
165
166 //*******************************************
168 //*******************************************
169 ETL_CONSTEXPR14
171 {
172 conversion_value = value_;
173
174 return *this;
175 }
176
177 //*******************************************
179 //*******************************************
180 ETL_CONSTEXPR14
182 {
183 conversion_status = status_;
184
185 return *this;
186 }
187
188 private:
189
190 value_type conversion_value;
191 unexpected_type conversion_status;
192 };
193
194 namespace private_to_arithmetic
195 {
196 template <typename T = void>
198 {
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';
204 };
205
206 template <typename T>
207 ETL_CONSTANT char char_statics<T>::Positive_Char;
208
209 template <typename T>
210 ETL_CONSTANT char char_statics<T>::Negative_Char;
211
212 template <typename T>
213 ETL_CONSTANT char char_statics<T>::Radix_Point1_Char;
214
215 template <typename T>
216 ETL_CONSTANT char char_statics<T>::Radix_Point2_Char;
217
218 template <typename T>
219 ETL_CONSTANT char char_statics<T>::Exponential_Char;
220
222 {
223 };
224
225 //*******************************************
226 ETL_NODISCARD
227 inline
228 ETL_CONSTEXPR14
229 bool is_valid(char c, etl::radix::value_type radix)
230 {
231 switch (radix)
232 {
233 case etl::radix::binary:
234 {
235 return (c >= '0') && (c <= '1');
236 break;
237 }
238
239 case etl::radix::octal:
240 {
241 return (c >= '0') && (c <= '7');
242 break;
243 }
244
245 case etl::radix::decimal:
246 {
247 return (c >= '0') && (c <= '9');
248 break;
249 }
250
251 case etl::radix::hex:
252 {
253 return ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f'));
254 break;
255 }
256
257 default:
258 {
259 return false;
260 break;
261 }
262 }
263 }
264
265 //*******************************************
266 ETL_NODISCARD
267 inline
268 ETL_CONSTEXPR14
269 char digit_value(char c, etl::radix::value_type radix)
270 {
271 switch (radix)
272 {
273 case etl::radix::binary:
274 case etl::radix::octal:
275 case etl::radix::decimal:
276 {
277 return c - '0';
278 break;
279 }
280
281 case etl::radix::hex:
282 {
283 if ((c >= '0') && (c <= '9'))
284 {
285 return c - '0';
286 }
287 else
288 {
289 return (c - 'a') + 10;
290 }
291 break;
292 }
293
294 default:
295 {
296 return 0;
297 break;
298 }
299 }
300 }
301
302 //*******************************************
303 ETL_NODISCARD
304 inline
305 ETL_CONSTEXPR14
306 char to_lower(char c)
307 {
308 if ((c >= 'A') && (c <= 'Z'))
309 {
310 c += 32;
311 }
312
313 return c;
314 }
315
316 //*******************************************
317 template <typename TChar>
318 ETL_NODISCARD
319 ETL_CONSTEXPR14
320 char convert(TChar c)
321 {
322 return to_lower(static_cast<char>(c));
323 }
324
325 //***************************************************************************
328 //***************************************************************************
329 template <typename TChar>
330 ETL_NODISCARD
331 ETL_CONSTEXPR14
333 {
334 if (!view.empty())
335 {
336 // Check for prefix.
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);
340
341 // Step over the prefix, if present.
342 if (has_positive_prefix || has_negative_prefix)
343 {
344 view.remove_prefix(1);
345 return has_negative_prefix;
346 }
347 }
348
349 return false;
350 }
351
352 //***************************************************************************
354 //***************************************************************************
355 ETL_NODISCARD
356 inline
357 ETL_CONSTEXPR14
358 bool is_valid_radix(const etl::radix::value_type radix)
359 {
360 return (radix == etl::radix::binary) ||
361 (radix == etl::radix::octal) ||
362 (radix == etl::radix::decimal) ||
363 (radix == etl::radix::hex);
364 }
365
366 //***************************************************************************
368 //***************************************************************************
369 template <typename TValue>
371 {
372 //*********************************
373 ETL_CONSTEXPR14
374 integral_accumulator(etl::radix::value_type radix_, TValue maximum_)
375 : radix(radix_)
376 , maximum(maximum_)
377 , integral_value(0)
378 , conversion_status(to_arithmetic_status::Valid)
379 {
380 }
381
382 //*********************************
383 ETL_NODISCARD
384 ETL_CONSTEXPR14
385 bool add(const char c)
386 {
387 bool is_success = false;
388 bool is_not_overflow = false;
389
390 const bool is_valid_char = is_valid(c, radix);
391
392 if (is_valid_char)
393 {
394 TValue old_value = integral_value;
395 integral_value *= radix;
396
397 // No multipication overflow?
398 is_not_overflow = ((integral_value / radix) == old_value);
399
400 if (is_not_overflow)
401 {
402 const char digit = digit_value(c, radix);
403
404 // No addition overflow?
405 is_not_overflow = ((maximum - digit) >= integral_value);
406
407 if ((maximum - digit) >= integral_value)
408 {
409 integral_value += digit;
410 is_success = true;
411 }
412 }
413 }
414
415 // Check the status of the conversion.
416 if (is_valid_char == false)
417 {
418 conversion_status = to_arithmetic_status::Invalid_Format;
419 }
420 else if (is_not_overflow == false)
421 {
422 conversion_status = to_arithmetic_status::Overflow;
423 }
424
425 return is_success;
426 }
427
428 //*********************************
429 ETL_NODISCARD
430 ETL_CONSTEXPR14
431 bool has_value() const
432 {
433 return conversion_status == to_arithmetic_status::Valid;
434 }
435
436 //*********************************
437 ETL_NODISCARD
438 ETL_CONSTEXPR14
439 TValue value() const
440 {
441 return integral_value;
442 }
443
444 //*********************************
445 ETL_NODISCARD
446 ETL_CONSTEXPR14
447 to_arithmetic_status status() const
448 {
449 return conversion_status;
450 }
451
452 private:
453
454 etl::radix::value_type radix;
455 TValue maximum;
456 TValue integral_value;
457 to_arithmetic_status conversion_status;
458 };
459
460 //***************************************************************************
462 //***************************************************************************
464 {
465 //*********************************
466 ETL_CONSTEXPR14
468 : divisor(1)
469 , floating_point_value(0)
470 , is_negative_mantissa(false)
471 , is_negative_exponent(false)
472 , expecting_sign(true)
473 , exponent_value(0)
474 , state(Parsing_Integral)
475 , conversion_status(to_arithmetic_status::Valid)
476 {
477 }
478
479 //*********************************
480 ETL_NODISCARD
481 ETL_CONSTEXPR14
482 bool add(char c)
483 {
484 bool is_success = true;
485
486 switch (state)
487 {
488 //***************************
489 case Parsing_Integral:
490 {
491 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
492 {
493 is_negative_mantissa = (c == char_constant::Negative_Char);
494 expecting_sign = false;
495 }
496 // Radix point?
497 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
498 {
499 expecting_sign = false;
500 state = Parsing_Fractional;
501 }
502 // Exponential?
503 else if (c == char_constant::Exponential_Char)
504 {
505 expecting_sign = true;
506 state = Parsing_Exponential;
507 }
508 else if (is_valid(c, etl::radix::decimal))
509 {
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;
515 }
516 else
517 {
518 conversion_status = to_arithmetic_status::Invalid_Format;
519 is_success = false;
520 }
521 break;
522 }
523
524 //***************************
525 case Parsing_Fractional:
526 {
527 // Radix point?
528 if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
529 {
530 conversion_status = to_arithmetic_status::Invalid_Format;
531 is_success = false;
532 }
533 // Exponential?
534 else if (c == char_constant::Exponential_Char)
535 {
536 expecting_sign = true;
537 state = Parsing_Exponential;
538 }
539 else if (is_valid(c, etl::radix::decimal))
540 {
541 const char digit = digit_value(c, etl::radix::decimal);
542 divisor *= 10;
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;
546 }
547 else
548 {
549 conversion_status = to_arithmetic_status::Invalid_Format;
550 is_success = false;
551 }
552 break;
553 }
554
555 //***************************
556 case Parsing_Exponential:
557 {
558 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
559 {
560 is_negative_exponent = (c == char_constant::Negative_Char);
561 expecting_sign = false;
562 }
563 // Radix point?
564 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char) || (c == char_constant::Exponential_Char))
565 {
566 conversion_status = to_arithmetic_status::Invalid_Format;
567 is_success = false;
568 }
569 else if (is_valid(c, etl::radix::decimal))
570 {
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;
574 }
575 else
576 {
577 conversion_status = to_arithmetic_status::Invalid_Format;
578 is_success = false;
579 }
580 break;
581 }
582
583 //***************************
584 default:
585 {
586 is_success = false;
587 break;
588 }
589 }
590
591 return is_success;
592 }
593
594 //*********************************
595 ETL_NODISCARD
596 ETL_CONSTEXPR14
597 bool has_value() const
598 {
599 return (conversion_status == to_arithmetic_status::Valid);
600 }
601
602 //*********************************
603 ETL_NODISCARD
604 ETL_CONSTEXPR14
605 long double value() const
606 {
607 return floating_point_value;
608 }
609
610 //*********************************
611 ETL_NODISCARD
612 ETL_CONSTEXPR14
613 to_arithmetic_status status() const
614 {
615 return conversion_status;
616 }
617
618 //*********************************
619 ETL_NODISCARD
620 ETL_CONSTEXPR14
621 int exponent() const
622 {
623 return exponent_value;
624 }
625
626 private:
627
628 enum
629 {
630 Parsing_Integral,
631 Parsing_Fractional,
632 Parsing_Exponential
633 };
634
635 long double divisor;
636 long double floating_point_value;
637 bool is_negative_mantissa;
638 bool is_negative_exponent;
639 bool expecting_sign;
640 int exponent_value;
641 int state;
642 to_arithmetic_status conversion_status;
643 };
644
645 //***************************************************************************
646 // Define an unsigned accumulator type that is at least as large as TValue.
647 //***************************************************************************
648 template <size_t Bits>
650
651 template <>
653 {
654 typedef uint32_t type;
655 };
656
657 template <>
659 {
660 typedef uint32_t type;
661 };
662
663 template <>
665 {
666 typedef uint32_t type;
667 };
668
669#if ETL_USING_64BIT_TYPES
670 template <>
672 {
673 typedef uint64_t type;
674 };
675#endif
676
677 //***************************************************************************
679 //***************************************************************************
680 template <typename TChar, typename TAccumulatorType>
681 ETL_NODISCARD
682 ETL_CONSTEXPR14
684 const etl::radix::value_type radix,
685 const TAccumulatorType maximum)
686 {
688 typedef typename etl::unexpected<etl::to_arithmetic_status> unexpected_type;
689
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();
692
693 integral_accumulator<TAccumulatorType> accumulator(radix, maximum);
694
695 while ((itr != itr_end) && accumulator.add(convert(*itr)))
696 {
697 // Keep looping until done or an error occurs.
698 ++itr;
699 }
700
701 if (accumulator.has_value())
702 {
703 accumulator_result = accumulator.value();
704 }
705 else
706 {
707 accumulator_result = unexpected_type(accumulator.status());
708 }
709
710 return accumulator_result;
711 }
712 }
713
714 //***************************************************************************
716 //***************************************************************************
717 template <typename TValue, typename TChar>
718 ETL_NODISCARD
719 ETL_CONSTEXPR14
722 const etl::radix::value_type radix)
723 {
724 using namespace etl::private_to_arithmetic;
725
726 typedef etl::to_arithmetic_result<TValue> result_type;
727 typedef typename result_type::unexpected_type unexpected_type;
728
729 result_type result;
730
731 if (is_valid_radix(radix))
732 {
733 // Is this a negative number?
734 const bool is_negative = check_and_remove_sign_prefix(view);
735
736 if (view.empty())
737 {
738 result = unexpected_type(to_arithmetic_status::Invalid_Format);
739 }
740 else
741 {
742 // Make sure we're not trying to put a negative value into an unsigned type.
743 if (is_negative && etl::is_unsigned<TValue>::value)
744 {
745 result = unexpected_type(to_arithmetic_status::Signed_To_Unsigned);
746 }
747 else
748 {
749 const bool is_decimal = (radix == etl::radix::decimal);
750
751 // Select the type we use for the accumulator.
752 typedef typename accumulator_type_select<etl::integral_limits<TValue>::bits>::type accumulator_type;
753
754 // Find the maximum absolute value for the type value we're trying to convert to.
755 const accumulator_type maximum = is_negative ? etl::absolute_unsigned(etl::integral_limits<TValue>::min)
758 // Do the conversion.
759 etl::to_arithmetic_result<accumulator_type> accumulator_result = to_arithmetic_integral<TChar>(view, radix, maximum);
760
761 result = unexpected_type(accumulator_result.error());
762
763 // Was it successful?
764 if (accumulator_result.has_value())
765 {
766 typedef typename etl::make_unsigned<TValue>::type uvalue_t;
767 const uvalue_t uvalue = static_cast<uvalue_t>(accumulator_result.value());
768
769 // Convert from the accumulator type to the desired type.
770 result = (is_negative ? static_cast<TValue>(0) - uvalue : etl::bit_cast<TValue>(uvalue));
771 }
772 }
773 }
774 }
775 else
776 {
777 result = unexpected_type(to_arithmetic_status::Invalid_Radix);
778 }
779
780 return result;
781 }
782
783 //***************************************************************************
785 //***************************************************************************
786 template <typename TValue, typename TChar>
787 ETL_NODISCARD
788 ETL_CONSTEXPR14
791 {
792 return etl::to_arithmetic<TValue, TChar>(view, etl::radix::decimal);
793 }
794
795 //***************************************************************************
797 //***************************************************************************
798 template <typename TValue, typename TChar>
799 ETL_NODISCARD
800 ETL_CONSTEXPR14
803 {
804 return etl::to_arithmetic<TValue, TChar>(view, spec.base);
805 }
806
807 //***************************************************************************
809 //***************************************************************************
810 template <typename TValue, typename TChar>
811 ETL_NODISCARD
812 ETL_CONSTEXPR14
814 to_arithmetic(const TChar* cp, size_t length, const etl::radix::value_type radix)
815 {
816 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length), radix);
817 }
818
819 //***************************************************************************
821 //***************************************************************************
822 template <typename TValue, typename TChar>
823 ETL_NODISCARD
824 ETL_CONSTEXPR14
826 to_arithmetic(const TChar* cp, size_t length)
827 {
828 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length), etl::radix::decimal);
829 }
830
831 //***************************************************************************
833 //***************************************************************************
834 template <typename TValue, typename TChar>
835 ETL_NODISCARD
836 ETL_CONSTEXPR14
838 to_arithmetic(const TChar* cp, size_t length, const typename etl::private_basic_format_spec::base_spec& spec)
839 {
840 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length), spec.base);
841 }
842
843 //***************************************************************************
845 //***************************************************************************
846 template <typename TValue, typename TChar>
847 ETL_NODISCARD
848 ETL_CONSTEXPR14
850 to_arithmetic(const etl::ibasic_string<TChar>& str, const etl::radix::value_type radix)
851 {
852 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(str), radix);;
853 }
854
855 //***************************************************************************
857 //***************************************************************************
858 template <typename TValue, typename TChar>
859 ETL_NODISCARD
860 ETL_CONSTEXPR14
863 {
864 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(str), etl::radix::decimal);;
865 }
866
867 //***************************************************************************
869 //***************************************************************************
870 template <typename TValue, typename TChar>
871 ETL_NODISCARD
872 ETL_CONSTEXPR14
875 {
876 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(str), spec);;
877 }
878
879 //***************************************************************************
881 //***************************************************************************
882 template <typename TValue, typename TChar>
883 ETL_NODISCARD
884 ETL_CONSTEXPR14
887 {
888 using namespace etl::private_to_arithmetic;
889
890 typedef etl::to_arithmetic_result<TValue> result_type;
891 typedef typename result_type::unexpected_type unexpected_type;
892
893 result_type result;
894
895 if (view.empty())
896 {
897 result = unexpected_type(to_arithmetic_status::Invalid_Format);
898 }
899 else
900 {
901 floating_point_accumulator accumulator;
902
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();
905
906 while ((itr != itr_end) && accumulator.add(convert(*itr)))
907 {
908 // Keep looping until done or an error occurs.
909 ++itr;
910 }
911
912 result = unexpected_type(accumulator.status());
913
914 if (result.has_value())
915 {
916 TValue value = static_cast<TValue>(accumulator.value());
917 int exponent = accumulator.exponent();
918
919 value *= pow(static_cast<TValue>(10.0), static_cast<TValue>(exponent));
920
921 // Check that the result is a valid floating point number.
922 if ((value == etl::numeric_limits<TValue>::infinity()) ||
924 {
925 result = unexpected_type(to_arithmetic_status::Overflow);
926 }
927 // Check for NaN.
928 else if (value != value)
929 {
930 result = unexpected_type(to_arithmetic_status::Invalid_Float);
931 }
932 else
933 {
934 result = value;
935 }
936 }
937 }
938
939 return result;
940 }
941
942 //***************************************************************************
944 //***************************************************************************
945 template <typename TValue, typename TChar>
946 ETL_NODISCARD
947 ETL_CONSTEXPR14
949 to_arithmetic(const TChar* cp, size_t length)
950 {
951 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length));
952 }
953
954 //***************************************************************************
956 //***************************************************************************
957 template <typename TValue, typename TChar>
958 ETL_NODISCARD
959 ETL_CONSTEXPR14
961 to_arithmetic(const TChar* cp)
962 {
963 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, etl::strlen<TChar>(cp)));
964 }
965
966 //***************************************************************************
968 //***************************************************************************
969 template <typename TValue, typename TChar>
970 ETL_NODISCARD
971 ETL_CONSTEXPR14
974 {
975 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(str));
976 }
977}
978
979//***************************************************************************
981//***************************************************************************
982template <typename T>
984{
985 if (lhs.has_value() && rhs.has_value())
986 {
987 return (lhs.value() == rhs.value());
988 }
989 else
990 {
991 return (lhs.status() == rhs.status());
992 }
993}
994
995//***************************************************************************
997//***************************************************************************
998template <typename T, typename U>
999ETL_CONSTEXPR14 bool operator ==(const etl::to_arithmetic_result<T>& lhs, const U& rhs)
1000{
1001 return bool(lhs) ? lhs.value() == rhs : false;
1002}
1003
1004//***************************************************************************
1006//***************************************************************************
1007template <typename T, typename U>
1008ETL_CONSTEXPR14 bool operator ==(const T& lhs, const etl::to_arithmetic_result<U>& rhs)
1009{
1010 return bool(rhs) ? rhs.value() == lhs : false;
1011}
1012
1013//***************************************************************************
1015//***************************************************************************
1016template <typename T>
1018{
1019 return !(lhs == rhs);
1020}
1021
1022//***************************************************************************
1024//***************************************************************************
1025template <typename T, typename U>
1026ETL_CONSTEXPR14 bool operator !=(const etl::to_arithmetic_result<T>& lhs, const U& rhs)
1027{
1028 return !(lhs == rhs);
1029}
1030
1031//***************************************************************************
1033//***************************************************************************
1034template <typename T, typename U>
1035ETL_CONSTEXPR14 bool operator !=(const T& lhs, const etl::to_arithmetic_result<T>& rhs)
1036{
1037 return !(lhs == rhs);
1038}
1039
1040#endif
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
Definition: radix.h:47
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: basic_format_spec.h:48
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