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 "absolute.h"
35#include "basic_string.h"
36#include "bit.h"
37#include "expected.h"
38#include "format_spec.h"
39#include "integral_limits.h"
40#include "iterator.h"
41#include "limits.h"
42#include "math.h"
43#include "radix.h"
44#include "smallest.h"
45#include "string_utilities.h"
46#include "string_view.h"
47#include "type_traits.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
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;
87 typedef etl::to_arithmetic_status error_type;
88 typedef etl::unexpected<etl::to_arithmetic_status> unexpected_type;
89
90 //*******************************************
92 //*******************************************
93 ETL_CONSTEXPR14 to_arithmetic_result()
94 : conversion_value(static_cast<value_type>(0))
95 , conversion_status(error_type::Valid)
96 {
97 }
98
99 //*******************************************
101 //*******************************************
102 ETL_CONSTEXPR14 to_arithmetic_result(const to_arithmetic_result& other)
103 : conversion_value(other.conversion_value)
104 , conversion_status(other.conversion_status)
105 {
106 }
107
108 //*******************************************
110 //*******************************************
111 ETL_NODISCARD ETL_CONSTEXPR14 bool has_value() const
112 {
113 return (conversion_status.error() == error_type::Valid);
114 }
115
116 //*******************************************
118 //*******************************************
119 ETL_NODISCARD ETL_CONSTEXPR14 operator bool() const
120 {
121 return has_value();
122 }
123
124 //*******************************************
127 //*******************************************
128 ETL_NODISCARD ETL_CONSTEXPR14 value_type value() const
129 {
130 return conversion_value;
131 }
132
133 //*******************************************
136 //*******************************************
137 ETL_NODISCARD ETL_CONSTEXPR14 operator value_type() const
138 {
139 return value();
140 }
141
142 //*******************************************
151 //*******************************************
152 ETL_NODISCARD ETL_CONSTEXPR14 error_type error() const
153 {
154 return etl::to_arithmetic_status(conversion_status.error());
155 }
156
157 //*******************************************
159 //*******************************************
160 ETL_CONSTEXPR14 to_arithmetic_result& operator=(value_type value_)
161 {
162 conversion_value = value_;
163
164 return *this;
165 }
166
167 //*******************************************
169 //*******************************************
170 ETL_CONSTEXPR14 to_arithmetic_result& operator=(unexpected_type status_)
171 {
172 conversion_status = status_;
173
174 return *this;
175 }
176
177 private:
178
179 value_type conversion_value;
180 unexpected_type conversion_status;
181 };
182
183 namespace private_to_arithmetic
184 {
185 template <typename T = void>
187 {
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';
193 };
194
195 template <typename T>
196 ETL_CONSTANT char char_statics<T>::Positive_Char;
197
198 template <typename T>
199 ETL_CONSTANT char char_statics<T>::Negative_Char;
200
201 template <typename T>
202 ETL_CONSTANT char char_statics<T>::Radix_Point1_Char;
203
204 template <typename T>
205 ETL_CONSTANT char char_statics<T>::Radix_Point2_Char;
206
207 template <typename T>
208 ETL_CONSTANT char char_statics<T>::Exponential_Char;
209
211 {
212 };
213
214 //*******************************************
215 ETL_NODISCARD
216 inline
217 ETL_CONSTEXPR14 bool is_valid(char c, etl::radix::value_type radix)
218 {
219 switch (radix)
220 {
221 case etl::radix::binary:
222 {
223 return (c >= '0') && (c <= '1');
224 }
225
226 case etl::radix::octal:
227 {
228 return (c >= '0') && (c <= '7');
229 }
230
231 case etl::radix::decimal:
232 {
233 return (c >= '0') && (c <= '9');
234 }
235
236 case etl::radix::hexadecimal:
237 {
238 return ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f'));
239 }
240
241 default:
242 {
243 return false;
244 }
245 }
246 }
247
248 //*******************************************
249 ETL_NODISCARD
250 inline
251 ETL_CONSTEXPR14 char digit_value(char c, etl::radix::value_type radix)
252 {
253 switch (radix)
254 {
255 case etl::radix::binary:
256 case etl::radix::octal:
257 case etl::radix::decimal:
258 {
259 return c - '0';
260 }
261
262 case etl::radix::hexadecimal:
263 {
264 if ((c >= '0') && (c <= '9'))
265 {
266 return c - '0';
267 }
268 else
269 {
270 return (c - 'a') + 10;
271 }
272 }
273
274 default:
275 {
276 return 0;
277 }
278 }
279 }
280
281 //*******************************************
282 ETL_NODISCARD
283 inline
284 ETL_CONSTEXPR14 char to_lower(char c)
285 {
286 if ((c >= 'A') && (c <= 'Z'))
287 {
288 c += 32;
289 }
290
291 return c;
292 }
293
294 //*******************************************
295 template <typename TChar>
296 ETL_NODISCARD ETL_CONSTEXPR14 char convert(TChar c)
297 {
298 return to_lower(static_cast<char>(c));
299 }
300
301 //***************************************************************************
304 //***************************************************************************
305 template <typename TChar>
306 ETL_NODISCARD ETL_CONSTEXPR14 bool check_and_remove_sign_prefix(etl::basic_string_view<TChar>& view)
307 {
308 if (!view.empty())
309 {
310 // Check for prefix.
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);
314
315 // Step over the prefix, if present.
316 if (has_positive_prefix || has_negative_prefix)
317 {
318 view.remove_prefix(1);
319 return has_negative_prefix;
320 }
321 }
322
323 return false;
324 }
325
326 //***************************************************************************
328 //***************************************************************************
329 ETL_NODISCARD
330 inline
331 ETL_CONSTEXPR14 bool is_valid_radix(const etl::radix::value_type radix)
332 {
333 return (radix == etl::radix::binary) || (radix == etl::radix::octal) || (radix == etl::radix::decimal) || (radix == etl::radix::hexadecimal);
334 }
335
336 //***************************************************************************
338 //***************************************************************************
339 template <typename TValue>
340 struct integral_accumulator
341 {
342 //*********************************
343 ETL_CONSTEXPR14 integral_accumulator(etl::radix::value_type radix_, TValue maximum_)
344 : radix(radix_)
345 , maximum(maximum_)
346 , integral_value(0)
347 , conversion_status(to_arithmetic_status::Valid)
348 {
349 }
350
351 //*********************************
352 ETL_NODISCARD ETL_CONSTEXPR14 bool add(const char c)
353 {
354 bool is_success = false;
355 bool is_not_overflow = false;
356
357 const bool is_valid_char = is_valid(c, radix);
358
359 if (is_valid_char)
360 {
361 TValue old_value = integral_value;
362 integral_value *= radix;
363
364 // No multiplication overflow?
365 is_not_overflow = ((integral_value / radix) == old_value);
366
367 if (is_not_overflow)
368 {
369 const char digit = digit_value(c, radix);
370
371 // No addition overflow?
372 is_not_overflow = ((maximum - static_cast<TValue>(digit)) >= integral_value);
373
374 if ((maximum - static_cast<TValue>(digit)) >= integral_value)
375 {
376 integral_value += static_cast<TValue>(digit);
377 is_success = true;
378 }
379 }
380 }
381
382 // Check the status of the conversion.
383 if (is_valid_char == false)
384 {
385 conversion_status = to_arithmetic_status::Invalid_Format;
386 }
387 else if (is_not_overflow == false)
388 {
389 conversion_status = to_arithmetic_status::Overflow;
390 }
391
392 return is_success;
393 }
394
395 //*********************************
396 ETL_NODISCARD ETL_CONSTEXPR14 bool has_value() const
397 {
398 return conversion_status == to_arithmetic_status::Valid;
399 }
400
401 //*********************************
402 ETL_NODISCARD ETL_CONSTEXPR14 TValue value() const
403 {
404 return integral_value;
405 }
406
407 //*********************************
408 ETL_NODISCARD ETL_CONSTEXPR14 to_arithmetic_status status() const
409 {
410 return conversion_status;
411 }
412
413 private:
414
415 etl::radix::value_type radix;
416 TValue maximum;
417 TValue integral_value;
418 to_arithmetic_status conversion_status;
419 };
420
421 //***************************************************************************
423 //***************************************************************************
424 struct floating_point_accumulator
425 {
426 //*********************************
427 ETL_CONSTEXPR14 floating_point_accumulator()
428 : divisor(1)
429 , floating_point_value(0)
430 , is_negative_mantissa(false)
431 , is_negative_exponent(false)
432 , expecting_sign(true)
433 , exponent_value(0)
434 , state(Parsing_Integral)
435 , conversion_status(to_arithmetic_status::Valid)
436 {
437 }
438
439 //*********************************
440 ETL_NODISCARD ETL_CONSTEXPR14 bool add(char c)
441 {
442 bool is_success = true;
443
444 switch (state)
445 {
446 //***************************
447 case Parsing_Integral:
448 {
449 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
450 {
451 is_negative_mantissa = (c == char_constant::Negative_Char);
452 expecting_sign = false;
453 }
454 // Radix point?
455 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
456 {
457 expecting_sign = false;
458 state = Parsing_Fractional;
459 }
460 // Exponential?
461 else if (c == char_constant::Exponential_Char)
462 {
463 expecting_sign = true;
464 state = Parsing_Exponential;
465 }
466 else if (is_valid(c, etl::radix::decimal))
467 {
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;
473 }
474 else
475 {
476 conversion_status = to_arithmetic_status::Invalid_Format;
477 is_success = false;
478 }
479 break;
480 }
481
482 //***************************
483 case Parsing_Fractional:
484 {
485 // Radix point?
486 if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char))
487 {
488 conversion_status = to_arithmetic_status::Invalid_Format;
489 is_success = false;
490 }
491 // Exponential?
492 else if (c == char_constant::Exponential_Char)
493 {
494 expecting_sign = true;
495 state = Parsing_Exponential;
496 }
497 else if (is_valid(c, etl::radix::decimal))
498 {
499 const char digit = digit_value(c, etl::radix::decimal);
500 divisor *= 10;
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;
504 }
505 else
506 {
507 conversion_status = to_arithmetic_status::Invalid_Format;
508 is_success = false;
509 }
510 break;
511 }
512
513 //***************************
514 case Parsing_Exponential:
515 {
516 if (expecting_sign && ((c == char_constant::Positive_Char) || (c == char_constant::Negative_Char)))
517 {
518 is_negative_exponent = (c == char_constant::Negative_Char);
519 expecting_sign = false;
520 }
521 // Radix point?
522 else if ((c == char_constant::Radix_Point1_Char) || (c == char_constant::Radix_Point2_Char) || (c == char_constant::Exponential_Char))
523 {
524 conversion_status = to_arithmetic_status::Invalid_Format;
525 is_success = false;
526 }
527 else if (is_valid(c, etl::radix::decimal))
528 {
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;
532 }
533 else
534 {
535 conversion_status = to_arithmetic_status::Invalid_Format;
536 is_success = false;
537 }
538 break;
539 }
540
541 //***************************
542 default:
543 {
544 is_success = false;
545 break;
546 }
547 }
548
549 return is_success;
550 }
551
552 //*********************************
553 ETL_NODISCARD ETL_CONSTEXPR14 bool has_value() const
554 {
555 return (conversion_status == to_arithmetic_status::Valid);
556 }
557
558 //*********************************
559 ETL_NODISCARD ETL_CONSTEXPR14 long double value() const
560 {
561 return floating_point_value;
562 }
563
564 //*********************************
565 ETL_NODISCARD ETL_CONSTEXPR14 to_arithmetic_status status() const
566 {
567 return conversion_status;
568 }
569
570 //*********************************
571 ETL_NODISCARD ETL_CONSTEXPR14 int exponent() const
572 {
573 return exponent_value;
574 }
575
576 private:
577
578 enum
579 {
580 Parsing_Integral,
581 Parsing_Fractional,
582 Parsing_Exponential
583 };
584
585 long double divisor;
586 long double floating_point_value;
587 bool is_negative_mantissa;
588 bool is_negative_exponent;
589 bool expecting_sign;
590 int exponent_value;
591 int state;
592 to_arithmetic_status conversion_status;
593 };
594
595 //***************************************************************************
596 // Define an unsigned accumulator type that is at least as large as TValue.
597 //***************************************************************************
598 template <size_t Bits>
600
601 template <>
603 {
604 typedef uint32_t type;
605 };
606
607 template <>
609 {
610 typedef uint32_t type;
611 };
612
613 template <>
615 {
616 typedef uint32_t type;
617 };
618
619#if ETL_USING_64BIT_TYPES
620 template <>
622 {
623 typedef uint64_t type;
624 };
625#endif
626
627 //***************************************************************************
629 //***************************************************************************
630 template <typename TChar, typename TAccumulatorType>
632 const etl::radix::value_type radix, const TAccumulatorType maximum)
633 {
635 typedef typename etl::unexpected<etl::to_arithmetic_status> unexpected_type;
636
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();
639
640 integral_accumulator<TAccumulatorType> accumulator(radix, maximum);
641
642 while ((itr != itr_end) && accumulator.add(convert(*itr)))
643 {
644 // Keep looping until done or an error occurs.
645 ++itr;
646 }
647
648 if (accumulator.has_value())
649 {
650 accumulator_result = accumulator.value();
651 }
652 else
653 {
654 accumulator_result = unexpected_type(accumulator.status());
655 }
656
657 return accumulator_result;
658 }
659 } // namespace private_to_arithmetic
660
661 //***************************************************************************
663 //***************************************************************************
664 template <typename TValue, typename TChar>
665 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type
666 to_arithmetic(etl::basic_string_view<TChar> view, const etl::radix::value_type radix)
667 {
668 using namespace etl::private_to_arithmetic;
669
670 typedef etl::to_arithmetic_result<TValue> result_type;
671 typedef typename result_type::unexpected_type unexpected_type;
672
673 result_type result;
674
676 {
677 // Is this a negative number?
678 const bool is_negative = check_and_remove_sign_prefix(view);
679
680 if (view.empty())
681 {
682 result = unexpected_type(to_arithmetic_status::Invalid_Format);
683 }
684 else
685 {
686 // Make sure we're not trying to put a negative value into an unsigned
687 // type.
688 if (is_negative && etl::is_unsigned<TValue>::value)
689 {
690 result = unexpected_type(to_arithmetic_status::Signed_To_Unsigned);
691 }
692 else
693 {
694 const bool is_decimal = (radix == etl::radix::decimal);
695
696 // Select the type we use for the accumulator.
698
699 // Find the maximum absolute value for the type value we're trying to
700 // convert to.
701 const accumulator_type maximum = is_negative ? etl::absolute_unsigned(etl::integral_limits<TValue>::min)
704 // Do the conversion.
706
707 result = unexpected_type(accumulator_result.error());
708
709 // Was it successful?
710 if (accumulator_result.has_value())
711 {
712 typedef typename etl::make_unsigned<TValue>::type uvalue_t;
713 const uvalue_t uvalue = static_cast<uvalue_t>(accumulator_result.value());
714
715 // Convert from the accumulator type to the desired type.
716 result = (is_negative ? static_cast<TValue>(static_cast<TValue>(0) - static_cast<TValue>(uvalue)) : etl::bit_cast<TValue>(uvalue));
717 }
718 }
719 }
720 }
721 else
722 {
723 result = unexpected_type(to_arithmetic_status::Invalid_Radix);
724 }
725
726 return result;
727 }
728
729 //***************************************************************************
731 //***************************************************************************
732 template <typename TValue, typename TChar>
733 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type
735 {
736 return etl::to_arithmetic<TValue, TChar>(view, etl::radix::decimal);
737 }
738
739 //***************************************************************************
741 //***************************************************************************
742 template <typename TValue, typename TChar>
743 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type
745 {
746 return etl::to_arithmetic<TValue, TChar>(view, spec.base);
747 }
748
749 //***************************************************************************
751 //***************************************************************************
752 template <typename TValue, typename TChar>
753 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type
754 to_arithmetic(const TChar* cp, size_t length, const etl::radix::value_type radix)
755 {
757 }
758
759 //***************************************************************************
761 //***************************************************************************
762 template <typename TValue, typename TChar>
763 ETL_NODISCARD
764 ETL_CONSTEXPR14
765 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type to_arithmetic(const TChar* cp, size_t length)
766 {
767 return etl::to_arithmetic<TValue, TChar>(etl::basic_string_view<TChar>(cp, length), etl::radix::decimal);
768 }
769
770 //***************************************************************************
772 //***************************************************************************
773 template <typename TValue, typename TChar>
774 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type
775 to_arithmetic(const TChar* cp, size_t length, const typename etl::private_basic_format_spec::base_spec& spec)
776 {
778 }
779
780 //***************************************************************************
782 //***************************************************************************
783 template <typename TValue, typename TChar>
784 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type
785 to_arithmetic(const etl::ibasic_string<TChar>& str, const etl::radix::value_type radix)
786 {
788 }
789
790 //***************************************************************************
792 //***************************************************************************
793 template <typename TValue, typename TChar>
794 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type
799
800 //***************************************************************************
802 //***************************************************************************
803 template <typename TValue, typename TChar>
804 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_integral<TValue>::value, etl::to_arithmetic_result<TValue> >::type
809
810 //***************************************************************************
812 //***************************************************************************
813 template <typename TValue, typename TChar>
814 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<TValue>::value, etl::to_arithmetic_result<TValue> >::type
816 {
817 using namespace etl::private_to_arithmetic;
818
819 typedef etl::to_arithmetic_result<TValue> result_type;
820 typedef typename result_type::unexpected_type unexpected_type;
821
822 result_type result;
823
824 if (view.empty())
825 {
826 result = unexpected_type(to_arithmetic_status::Invalid_Format);
827 }
828 else
829 {
830 floating_point_accumulator accumulator;
831
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();
834
835 while ((itr != itr_end) && accumulator.add(convert(*itr)))
836 {
837 // Keep looping until done or an error occurs.
838 ++itr;
839 }
840
841 result = unexpected_type(accumulator.status());
842
843 if (result.has_value())
844 {
845 TValue value = static_cast<TValue>(accumulator.value());
846 int exponent = accumulator.exponent();
847
848 value *= pow(static_cast<TValue>(10.0), static_cast<TValue>(exponent));
849
850 // Check that the result is a valid floating point number.
851 if (etl::is_infinity(value))
852 {
853 result = unexpected_type(to_arithmetic_status::Overflow);
854 }
855 else if (etl::is_nan(value))
856 {
857 result = unexpected_type(to_arithmetic_status::Invalid_Float);
858 }
859 else
860 {
861 result = value;
862 }
863 }
864 }
865
866 return result;
867 }
868
869 //***************************************************************************
871 //***************************************************************************
872 template <typename TValue, typename TChar>
873 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<TValue>::value, etl::to_arithmetic_result<TValue> >::type to_arithmetic(const TChar* cp,
874 size_t length)
875 {
877 }
878
879 //***************************************************************************
881 //***************************************************************************
882 template <typename TValue, typename TChar>
883 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<TValue>::value, etl::to_arithmetic_result<TValue> >::type to_arithmetic(const TChar* cp)
884 {
886 }
887
888 //***************************************************************************
890 //***************************************************************************
891 template <typename TValue, typename TChar>
892 ETL_NODISCARD ETL_CONSTEXPR14 typename etl::enable_if<etl::is_floating_point<TValue>::value, etl::to_arithmetic_result<TValue> >::type
897} // namespace etl
898
899//***************************************************************************
901//***************************************************************************
902template <typename T>
903ETL_CONSTEXPR14 bool operator==(const etl::to_arithmetic_result<T>& lhs, const etl::to_arithmetic_result<T>& rhs)
904{
905 if (lhs.has_value() && rhs.has_value())
906 {
907 return (lhs.value() == rhs.value());
908 }
909 else
910 {
911 return (lhs.status() == rhs.status());
912 }
913}
914
915//***************************************************************************
917//***************************************************************************
918template <typename T, typename U>
919ETL_CONSTEXPR14 bool operator==(const etl::to_arithmetic_result<T>& lhs, const U& rhs)
920{
921 return bool(lhs) ? lhs.value() == rhs : false;
922}
923
924//***************************************************************************
926//***************************************************************************
927template <typename T, typename U>
928ETL_CONSTEXPR14 bool operator==(const T& lhs, const etl::to_arithmetic_result<U>& rhs)
929{
930 return bool(rhs) ? rhs.value() == lhs : false;
931}
932
933//***************************************************************************
935//***************************************************************************
936template <typename T>
937ETL_CONSTEXPR14 bool operator!=(const etl::to_arithmetic_result<T>& lhs, const etl::to_arithmetic_result<T>& rhs)
938{
939 return !(lhs == rhs);
940}
941
942//***************************************************************************
944//***************************************************************************
945template <typename T, typename U>
946ETL_CONSTEXPR14 bool operator!=(const etl::to_arithmetic_result<T>& lhs, const U& rhs)
947{
948 return !(lhs == rhs);
949}
950
951//***************************************************************************
953//***************************************************************************
954template <typename T, typename U>
955ETL_CONSTEXPR14 bool operator!=(const T& lhs, const etl::to_arithmetic_result<T>& rhs)
956{
957 return !(lhs == rhs);
958}
959
960#endif
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
Definition expected.h:94
#define ETL_DECLARE_ENUM_TYPE(TypeName, ValueType)
Definition enum_type.h:90
Definition integral_limits.h:518
Definition radix.h:47
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 basic_format_spec.h:49
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