Embedded Template Library 1.0
Loading...
Searching...
No Matches
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#include "math.h"
48
49#include <math.h>
50
51namespace etl
52{
53 //***************************************************************************
55 //***************************************************************************
57 {
58 enum enum_type
59 {
60 Valid,
61 Invalid_Radix,
62 Invalid_Format,
63 Invalid_Float,
64 Signed_To_Unsigned,
65 Overflow
66 };
67
68 ETL_DECLARE_ENUM_TYPE(to_arithmetic_status, int)
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")
75 ETL_END_ENUM_TYPE
76 };
77
78 //***************************************************************************
80 //***************************************************************************
81 template<typename TValue>
83 {
84 public:
85
86 typedef TValue value_type;
89
90 //*******************************************
92 //*******************************************
93 ETL_CONSTEXPR14
95 : conversion_value(static_cast<value_type>(0))
96 , conversion_status(error_type::Valid)
97 {
98 }
99
100 //*******************************************
102 //*******************************************
103 ETL_CONSTEXPR14
105 : conversion_value(other.conversion_value)
106 , conversion_status(other.conversion_status)
107 {
108 }
109
110 //*******************************************
112 //*******************************************
113 ETL_NODISCARD
114 ETL_CONSTEXPR14
115 bool has_value() const
116 {
117 return (conversion_status.error() == error_type::Valid);
118 }
119
120 //*******************************************
122 //*******************************************
123 ETL_NODISCARD
124 ETL_CONSTEXPR14
125 operator bool() const
126 {
127 return has_value();
128 }
129
130 //*******************************************
133 //*******************************************
134 ETL_NODISCARD
135 ETL_CONSTEXPR14
137 {
138 return conversion_value;
139 }
140
141 //*******************************************
144 //*******************************************
145 ETL_NODISCARD
146 ETL_CONSTEXPR14
147 operator value_type() const
148 {
149 return value();
150 }
151
152 //*******************************************
161 //*******************************************
162 ETL_NODISCARD
163 ETL_CONSTEXPR14
165 {
166 return etl::to_arithmetic_status(conversion_status.error());
167 }
168
169 //*******************************************
171 //*******************************************
172 ETL_CONSTEXPR14
174 {
175 conversion_value = value_;
176
177 return *this;
178 }
179
180 //*******************************************
182 //*******************************************
183 ETL_CONSTEXPR14
185 {
186 conversion_status = status_;
187
188 return *this;
189 }
190
191 private:
192
193 value_type conversion_value;
194 unexpected_type conversion_status;
195 };
196
197 namespace private_to_arithmetic
198 {
199 template <typename T = void>
200 struct char_statics
201 {
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';
207 };
208
209 template <typename T>
210 ETL_CONSTANT char char_statics<T>::Positive_Char;
211
212 template <typename T>
213 ETL_CONSTANT char char_statics<T>::Negative_Char;
214
215 template <typename T>
216 ETL_CONSTANT char char_statics<T>::Radix_Point1_Char;
217
218 template <typename T>
219 ETL_CONSTANT char char_statics<T>::Radix_Point2_Char;
220
221 template <typename T>
222 ETL_CONSTANT char char_statics<T>::Exponential_Char;
223
224 struct char_constant : char_statics<>
225 {
226 };
227
228 //*******************************************
229 ETL_NODISCARD
230 inline
231 ETL_CONSTEXPR14
232 bool is_valid(char c, etl::radix::value_type radix)
233 {
234 switch (radix)
235 {
236 case etl::radix::binary:
237 {
238 return (c >= '0') && (c <= '1');
239 break;
240 }
241
242 case etl::radix::octal:
243 {
244 return (c >= '0') && (c <= '7');
245 break;
246 }
247
248 case etl::radix::decimal:
249 {
250 return (c >= '0') && (c <= '9');
251 break;
252 }
253
254 case etl::radix::hexadecimal:
255 {
256 return ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f'));
257 break;
258 }
259
260 default:
261 {
262 return false;
263 break;
264 }
265 }
266 }
267
268 //*******************************************
269 ETL_NODISCARD
270 inline
271 ETL_CONSTEXPR14
272 char digit_value(char c, etl::radix::value_type radix)
273 {
274 switch (radix)
275 {
276 case etl::radix::binary:
277 case etl::radix::octal:
278 case etl::radix::decimal:
279 {
280 return c - '0';
281 break;
282 }
283
284 case etl::radix::hexadecimal:
285 {
286 if ((c >= '0') && (c <= '9'))
287 {
288 return c - '0';
289 }
290 else
291 {
292 return (c - 'a') + 10;
293 }
294 break;
295 }
296
297 default:
298 {
299 return 0;
300 break;
301 }
302 }
303 }
304
305 //*******************************************
306 ETL_NODISCARD
307 inline
308 ETL_CONSTEXPR14
309 char to_lower(char c)
310 {
311 if ((c >= 'A') && (c <= 'Z'))
312 {
313 c += 32;
314 }
315
316 return c;
317 }
318
319 //*******************************************
320 template <typename TChar>
321 ETL_NODISCARD
322 ETL_CONSTEXPR14
323 char convert(TChar c)
324 {
325 return to_lower(static_cast<char>(c));
326 }
327
328 //***************************************************************************
331 //***************************************************************************
332 template <typename TChar>
333 ETL_NODISCARD
334 ETL_CONSTEXPR14
335 bool check_and_remove_sign_prefix(etl::basic_string_view<TChar>& view)
336 {
337 if (!view.empty())
338 {
339 // Check for prefix.
340 const char c = convert(view[0]);
341 const bool has_positive_prefix = (c == char_constant::Positive_Char);
342 const bool has_negative_prefix = (c == char_constant::Negative_Char);
343
344 // Step over the prefix, if present.
345 if (has_positive_prefix || has_negative_prefix)
346 {
347 view.remove_prefix(1);
348 return has_negative_prefix;
349 }
350 }
351
352 return false;
353 }
354
355 //***************************************************************************
357 //***************************************************************************
358 ETL_NODISCARD
359 inline
360 ETL_CONSTEXPR14
361 bool is_valid_radix(const etl::radix::value_type radix)
362 {
363 return (radix == etl::radix::binary) ||
364 (radix == etl::radix::octal) ||
365 (radix == etl::radix::decimal) ||
366 (radix == etl::radix::hexadecimal);
367 }
368
369 //***************************************************************************
371 //***************************************************************************
372 template <typename TValue>
373 struct integral_accumulator
374 {
375 //*********************************
376 ETL_CONSTEXPR14
377 integral_accumulator(etl::radix::value_type radix_, TValue maximum_)
378 : radix(radix_)
379 , maximum(maximum_)
380 , integral_value(0)
381 , conversion_status(to_arithmetic_status::Valid)
382 {
383 }
384
385 //*********************************
386 ETL_NODISCARD
387 ETL_CONSTEXPR14
388 bool add(const char c)
389 {
390 bool is_success = false;
391 bool is_not_overflow = false;
392
393 const bool is_valid_char = is_valid(c, radix);
394
395 if (is_valid_char)
396 {
397 TValue old_value = integral_value;
398 integral_value *= radix;
399
400 // No multiplication overflow?
401 is_not_overflow = ((integral_value / radix) == old_value);
402
403 if (is_not_overflow)
404 {
405 const char digit = digit_value(c, radix);
406
407 // No addition overflow?
408 is_not_overflow = ((maximum - digit) >= integral_value);
409
410 if ((maximum - digit) >= integral_value)
411 {
412 integral_value += digit;
413 is_success = true;
414 }
415 }
416 }
417
418 // Check the status of the conversion.
419 if (is_valid_char == false)
420 {
421 conversion_status = to_arithmetic_status::Invalid_Format;
422 }
423 else if (is_not_overflow == false)
424 {
425 conversion_status = to_arithmetic_status::Overflow;
426 }
427
428 return is_success;
429 }
430
431 //*********************************
432 ETL_NODISCARD
433 ETL_CONSTEXPR14
434 bool has_value() const
435 {
436 return conversion_status == to_arithmetic_status::Valid;
437 }
438
439 //*********************************
440 ETL_NODISCARD
441 ETL_CONSTEXPR14
442 TValue value() const
443 {
444 return integral_value;
445 }
446
447 //*********************************
448 ETL_NODISCARD
449 ETL_CONSTEXPR14
450 to_arithmetic_status status() const
451 {
452 return conversion_status;
453 }
454
455 private:
456
457 etl::radix::value_type radix;
458 TValue maximum;
459 TValue integral_value;
460 to_arithmetic_status conversion_status;
461 };
462
463 //***************************************************************************
465 //***************************************************************************
466 struct floating_point_accumulator
467 {
468 //*********************************
469 ETL_CONSTEXPR14
470 floating_point_accumulator()
471 : divisor(1)
472 , floating_point_value(0)
473 , is_negative_mantissa(false)
474 , is_negative_exponent(false)
475 , expecting_sign(true)
476 , exponent_value(0)
477 , state(Parsing_Integral)
478 , conversion_status(to_arithmetic_status::Valid)
479 {
480 }
481
482 //*********************************
483 ETL_NODISCARD
484 ETL_CONSTEXPR14
485 bool add(char c)
486 {
487 bool is_success = true;
488
489 switch (state)
490 {
491 //***************************
492 case Parsing_Integral:
493 {
494 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
495 {
496 is_negative_mantissa = (c == char_constant::Negative_Char);
497 expecting_sign = false;
498 }
499 // Radix point?
500 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
501 {
502 expecting_sign = false;
503 state = Parsing_Fractional;
504 }
505 // Exponential?
506 else if (c == char_constant::Exponential_Char)
507 {
508 expecting_sign = true;
509 state = Parsing_Exponential;
510 }
511 else if (is_valid(c, etl::radix::decimal))
512 {
513 const char digit = digit_value(c, etl::radix::decimal);
514 floating_point_value *= 10;
515 is_negative_mantissa ? floating_point_value -= digit : floating_point_value += digit;
516 conversion_status = to_arithmetic_status::Valid;
517 expecting_sign = false;
518 }
519 else
520 {
521 conversion_status = to_arithmetic_status::Invalid_Format;
522 is_success = false;
523 }
524 break;
525 }
526
527 //***************************
528 case Parsing_Fractional:
529 {
530 // Radix point?
531 if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
532 {
533 conversion_status = to_arithmetic_status::Invalid_Format;
534 is_success = false;
535 }
536 // Exponential?
537 else if (c == char_constant::Exponential_Char)
538 {
539 expecting_sign = true;
540 state = Parsing_Exponential;
541 }
542 else if (is_valid(c, etl::radix::decimal))
543 {
544 const char digit = digit_value(c, etl::radix::decimal);
545 divisor *= 10;
546 long double fraction = digit / divisor;
547 is_negative_mantissa ? floating_point_value -= fraction : floating_point_value += fraction;
548 conversion_status = to_arithmetic_status::Valid;
549 }
550 else
551 {
552 conversion_status = to_arithmetic_status::Invalid_Format;
553 is_success = false;
554 }
555 break;
556 }
557
558 //***************************
559 case Parsing_Exponential:
560 {
561 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
562 {
563 is_negative_exponent = (c == char_constant::Negative_Char);
564 expecting_sign = false;
565 }
566 // Radix point?
567 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char) || (c == char_constant::Exponential_Char))
568 {
569 conversion_status = to_arithmetic_status::Invalid_Format;
570 is_success = false;
571 }
572 else if (is_valid(c, etl::radix::decimal))
573 {
574 const char digit = digit_value(c, etl::radix::decimal);
575 exponent_value *= etl::radix::decimal;
576 is_negative_exponent ? exponent_value -= digit : exponent_value += digit;
577 }
578 else
579 {
580 conversion_status = to_arithmetic_status::Invalid_Format;
581 is_success = false;
582 }
583 break;
584 }
585
586 //***************************
587 default:
588 {
589 is_success = false;
590 break;
591 }
592 }
593
594 return is_success;
595 }
596
597 //*********************************
598 ETL_NODISCARD
599 ETL_CONSTEXPR14
600 bool has_value() const
601 {
602 return (conversion_status == to_arithmetic_status::Valid);
603 }
604
605 //*********************************
606 ETL_NODISCARD
607 ETL_CONSTEXPR14
608 long double value() const
609 {
610 return floating_point_value;
611 }
612
613 //*********************************
614 ETL_NODISCARD
615 ETL_CONSTEXPR14
616 to_arithmetic_status status() const
617 {
618 return conversion_status;
619 }
620
621 //*********************************
622 ETL_NODISCARD
623 ETL_CONSTEXPR14
624 int exponent() const
625 {
626 return exponent_value;
627 }
628
629 private:
630
631 enum
632 {
633 Parsing_Integral,
634 Parsing_Fractional,
635 Parsing_Exponential
636 };
637
638 long double divisor;
639 long double floating_point_value;
640 bool is_negative_mantissa;
641 bool is_negative_exponent;
642 bool expecting_sign;
643 int exponent_value;
644 int state;
645 to_arithmetic_status conversion_status;
646 };
647
648 //***************************************************************************
649 // Define an unsigned accumulator type that is at least as large as TValue.
650 //***************************************************************************
651 template <size_t Bits>
652 struct accumulator_type_select;
653
654 template <>
655 struct accumulator_type_select<8U>
656 {
657 typedef uint32_t type;
658 };
659
660 template <>
661 struct accumulator_type_select<16U>
662 {
663 typedef uint32_t type;
664 };
665
666 template <>
667 struct accumulator_type_select<32U>
668 {
669 typedef uint32_t type;
670 };
671
672#if ETL_USING_64BIT_TYPES
673 template <>
674 struct accumulator_type_select<64U>
675 {
676 typedef uint64_t type;
677 };
678#endif
679
680 //***************************************************************************
682 //***************************************************************************
683 template <typename TChar, typename TAccumulatorType>
684 ETL_NODISCARD
685 ETL_CONSTEXPR14
687 const etl::radix::value_type radix,
688 const TAccumulatorType maximum)
689 {
691 typedef typename etl::unexpected<etl::to_arithmetic_status> unexpected_type;
692
693 typename etl::basic_string_view<TChar>::const_iterator itr = view.begin();
694 const typename etl::basic_string_view<TChar>::const_iterator itr_end = view.end();
695
696 integral_accumulator<TAccumulatorType> accumulator(radix, maximum);
697
698 while ((itr != itr_end) && accumulator.add(convert(*itr)))
699 {
700 // Keep looping until done or an error occurs.
701 ++itr;
702 }
703
704 if (accumulator.has_value())
705 {
706 accumulator_result = accumulator.value();
707 }
708 else
709 {
710 accumulator_result = unexpected_type(accumulator.status());
711 }
712
713 return accumulator_result;
714 }
715 }
716
717 //***************************************************************************
719 //***************************************************************************
720 template <typename TValue, typename TChar>
721 ETL_NODISCARD
722 ETL_CONSTEXPR14
725 const etl::radix::value_type radix)
726 {
727 using namespace etl::private_to_arithmetic;
728
729 typedef etl::to_arithmetic_result<TValue> result_type;
730 typedef typename result_type::unexpected_type unexpected_type;
731
732 result_type result;
733
734 if (is_valid_radix(radix))
735 {
736 // Is this a negative number?
737 const bool is_negative = check_and_remove_sign_prefix(view);
738
739 if (view.empty())
740 {
741 result = unexpected_type(to_arithmetic_status::Invalid_Format);
742 }
743 else
744 {
745 // Make sure we're not trying to put a negative value into an unsigned type.
746 if (is_negative && etl::is_unsigned<TValue>::value)
747 {
748 result = unexpected_type(to_arithmetic_status::Signed_To_Unsigned);
749 }
750 else
751 {
752 const bool is_decimal = (radix == etl::radix::decimal);
753
754 // Select the type we use for the accumulator.
755 typedef typename accumulator_type_select<etl::integral_limits<TValue>::bits>::type accumulator_type;
756
757 // Find the maximum absolute value for the type value we're trying to convert to.
758 const accumulator_type maximum = is_negative ? etl::absolute_unsigned(etl::integral_limits<TValue>::min)
761 // Do the conversion.
763
764 result = unexpected_type(accumulator_result.error());
765
766 // Was it successful?
767 if (accumulator_result.has_value())
768 {
770 const uvalue_t uvalue = static_cast<uvalue_t>(accumulator_result.value());
771
772 // Convert from the accumulator type to the desired type.
773 result = (is_negative ? static_cast<TValue>(0) - uvalue : etl::bit_cast<TValue>(uvalue));
774 }
775 }
776 }
777 }
778 else
779 {
780 result = unexpected_type(to_arithmetic_status::Invalid_Radix);
781 }
782
783 return result;
784 }
785
786 //***************************************************************************
788 //***************************************************************************
789 template <typename TValue, typename TChar>
790 ETL_NODISCARD
791 ETL_CONSTEXPR14
794 {
795 return etl::to_arithmetic<TValue, TChar>(view, etl::radix::decimal);
796 }
797
798 //***************************************************************************
800 //***************************************************************************
801 template <typename TValue, typename TChar>
802 ETL_NODISCARD
803 ETL_CONSTEXPR14
809
810 //***************************************************************************
812 //***************************************************************************
813 template <typename TValue, typename TChar>
814 ETL_NODISCARD
815 ETL_CONSTEXPR14
817 to_arithmetic(const TChar* cp, size_t length, const etl::radix::value_type radix)
818 {
820 }
821
822 //***************************************************************************
824 //***************************************************************************
825 template <typename TValue, typename TChar>
826 ETL_NODISCARD
827 ETL_CONSTEXPR14
829 to_arithmetic(const TChar* cp, size_t length)
830 {
831 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length), etl::radix::decimal);
832 }
833
834 //***************************************************************************
836 //***************************************************************************
837 template <typename TValue, typename TChar>
838 ETL_NODISCARD
839 ETL_CONSTEXPR14
845
846 //***************************************************************************
848 //***************************************************************************
849 template <typename TValue, typename TChar>
850 ETL_NODISCARD
851 ETL_CONSTEXPR14
853 to_arithmetic(const etl::ibasic_string<TChar>& str, const etl::radix::value_type radix)
854 {
856 }
857
858 //***************************************************************************
860 //***************************************************************************
861 template <typename TValue, typename TChar>
862 ETL_NODISCARD
863 ETL_CONSTEXPR14
869
870 //***************************************************************************
872 //***************************************************************************
873 template <typename TValue, typename TChar>
874 ETL_NODISCARD
875 ETL_CONSTEXPR14
881
882 //***************************************************************************
884 //***************************************************************************
885 template <typename TValue, typename TChar>
886 ETL_NODISCARD
887 ETL_CONSTEXPR14
890 {
891 using namespace etl::private_to_arithmetic;
892
893 typedef etl::to_arithmetic_result<TValue> result_type;
894 typedef typename result_type::unexpected_type unexpected_type;
895
896 result_type result;
897
898 if (view.empty())
899 {
900 result = unexpected_type(to_arithmetic_status::Invalid_Format);
901 }
902 else
903 {
904 floating_point_accumulator accumulator;
905
907 const typename etl::basic_string_view<TChar>::const_iterator itr_end = view.end();
908
909 while ((itr != itr_end) && accumulator.add(convert(*itr)))
910 {
911 // Keep looping until done or an error occurs.
912 ++itr;
913 }
914
915 result = unexpected_type(accumulator.status());
916
917 if (result.has_value())
918 {
919 TValue value = static_cast<TValue>(accumulator.value());
920 int exponent = accumulator.exponent();
921
922 value *= pow(static_cast<TValue>(10.0), static_cast<TValue>(exponent));
923
924 // Check that the result is a valid floating point number.
925 if (etl::is_infinity(value))
926 {
927 result = unexpected_type(to_arithmetic_status::Overflow);
928 }
929 else if (etl::is_nan(value))
930 {
931 result = unexpected_type(to_arithmetic_status::Invalid_Float);
932 }
933 else
934 {
935 result = value;
936 }
937 }
938 }
939
940 return result;
941 }
942
943 //***************************************************************************
945 //***************************************************************************
946 template <typename TValue, typename TChar>
947 ETL_NODISCARD
948 ETL_CONSTEXPR14
950 to_arithmetic(const TChar* cp, size_t length)
951 {
953 }
954
955 //***************************************************************************
957 //***************************************************************************
958 template <typename TValue, typename TChar>
959 ETL_NODISCARD
960 ETL_CONSTEXPR14
966
967 //***************************************************************************
969 //***************************************************************************
970 template <typename TValue, typename TChar>
971 ETL_NODISCARD
972 ETL_CONSTEXPR14
978}
979
980//***************************************************************************
982//***************************************************************************
983template <typename T>
985{
986 if (lhs.has_value() && rhs.has_value())
987 {
988 return (lhs.value() == rhs.value());
989 }
990 else
991 {
992 return (lhs.status() == rhs.status());
993 }
994}
995
996//***************************************************************************
998//***************************************************************************
999template <typename T, typename U>
1000ETL_CONSTEXPR14 bool operator ==(const etl::to_arithmetic_result<T>& lhs, const U& rhs)
1001{
1002 return bool(lhs) ? lhs.value() == rhs : false;
1003}
1004
1005//***************************************************************************
1007//***************************************************************************
1008template <typename T, typename U>
1009ETL_CONSTEXPR14 bool operator ==(const T& lhs, const etl::to_arithmetic_result<U>& rhs)
1010{
1011 return bool(rhs) ? rhs.value() == lhs : false;
1012}
1013
1014//***************************************************************************
1016//***************************************************************************
1017template <typename T>
1019{
1020 return !(lhs == rhs);
1021}
1022
1023//***************************************************************************
1025//***************************************************************************
1026template <typename T, typename U>
1027ETL_CONSTEXPR14 bool operator !=(const etl::to_arithmetic_result<T>& lhs, const U& rhs)
1028{
1029 return !(lhs == rhs);
1030}
1031
1032//***************************************************************************
1034//***************************************************************************
1035template <typename T, typename U>
1036ETL_CONSTEXPR14 bool operator !=(const T& lhs, const etl::to_arithmetic_result<T>& rhs)
1037{
1038 return !(lhs == rhs);
1039}
1040
1041#endif
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
const TError & error() const
Get the error.
Definition expected.h:200
Definition integral_limits.h:516
Definition radix.h:47
is_unsigned
Definition type_traits_generator.h:1021
make_unsigned
Definition type_traits_generator.h:1181
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:724
pair holds two objects of arbitrary type
Definition utility.h:164
Definition basic_format_spec.h:48
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:984
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:1018