Embedded Template Library 1.0
limits.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2018 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_LIMITS_INCLUDED
32#define ETL_LIMITS_INCLUDED
33
34#include "platform.h"
35#include "type_traits.h"
36#include "char_traits.h"
37#include "integral_limits.h"
38
39#if ETL_NOT_USING_STL && defined(ETL_COMPILER_ARM5) && !defined(__USE_C99_MATH)
40 // Required for nan, nanf, nanl
41 #define __USE_C99_MATH
42#endif
43
44#include <limits.h>
45#include <stdint.h>
46#include <float.h>
47#include <math.h>
48
49#include "private/minmax_push.h"
50
51#if defined(ETL_COMPILER_MICROSOFT)
52 #pragma warning(push)
53 #pragma warning(disable : 26812)
54#endif
55
56#if ETL_NOT_USING_STL
57#define ETL_LOG10_OF_2(x) (((x) * 301) / 1000)
58
59#if !defined(LDBL_MIN) && defined(DBL_MIN)
60 // Looks like we don't have these macros defined.
61 // That probably means that 'long double' is the same size as 'double'.
62 #define LDBL_MIN DBL_MIN
63 #define LDBL_MAX DBL_MAX
64 #define LDBL_EPSILON DBL_EPSILON
65 #define LDBL_MANT_DIG DBL_MANT_DIG
66 #define LDBL_DIG DBL_DIG
67 #define LDBL_MIN_EXP DBL_MIN_EXP
68 #define LDBL_MIN_10_EXP DBL_MIN_10_EXP
69 #define LDBL_MAX_EXP DBL_MAX_EXP
70 #define LDBL_MAX_10_EXP DBL_MAX_10_EXP
71#endif
72
73#if !defined(HUGE_VAL)
74 // Looks like we don't have these macros defined.
75 // They're compiler implementation dependent, so we'll make them the same as the max values.
76 #define HUGE_VALF FLT_MAX
77 #define HUGE_VAL DBL_MAX
78 #define HUGE_VALL LDBL_MAX
79#endif
80
81#if defined(ETL_NO_CPP_NAN_SUPPORT)
82 #if defined(NAN)
83 #define ETL_NAN (double)NAN
84 #define ETL_NANF (float)NAN
85 #define ETL_NANL (long double)NAN
86 #define ETL_HAS_NAN true
87 #else
88 #define ETL_NAN (double)0.0
89 #define ETL_NANF (float)0.0
90 #define ETL_NANL (long double)0.0
91 #define ETL_HAS_NAN false
92 #endif
93#else
94 #define ETL_NAN nan("")
95 #define ETL_NANF nanf("")
96 #define ETL_NANL nanl("")
97 #define ETL_HAS_NAN true
98#endif
99
100namespace etl
101{
102 enum float_round_style
103 {
104 round_indeterminate = -1,
105 round_toward_zero = 0,
106 round_to_nearest = 1,
107 round_toward_infinity = 2,
108 round_toward_neg_infinity = 3,
109 };
110
111 enum float_denorm_style
112 {
113 denorm_indeterminate = -1,
114 denorm_absent = 0,
115 denorm_present = 1
116 };
117
118 namespace private_limits
119 {
120 //*********************************
121 // Integral limits common
122 template <typename T = void>
123 class integral_limits_common
124 {
125 public:
126
127 static ETL_CONSTANT bool is_specialized = true;
128 static ETL_CONSTANT bool is_integer = true;
129 static ETL_CONSTANT bool is_exact = true;
130 static ETL_CONSTANT int max_digits10 = 0;
131 static ETL_CONSTANT int radix = 2;
132 static ETL_CONSTANT int min_exponent = 0;
133 static ETL_CONSTANT int min_exponent10 = 0;
134 static ETL_CONSTANT int max_exponent = 0;
135 static ETL_CONSTANT int max_exponent10 = 0;
136 static ETL_CONSTANT bool has_infinity = false;
137 static ETL_CONSTANT bool has_quiet_NaN = false;
138 static ETL_CONSTANT bool has_signaling_NaN = false;
139 static ETL_CONSTANT bool has_denorm_loss = false;
140 static ETL_CONSTANT bool is_iec559 = false;
141 static ETL_CONSTANT bool is_bounded = true;
142 static ETL_CONSTANT bool traps = false;
143 static ETL_CONSTANT bool tinyness_before = false;
144 static ETL_CONSTANT float_denorm_style has_denorm = denorm_absent;
145 static ETL_CONSTANT float_round_style round_style = round_toward_zero;
146 };
147
148 template <typename T>
149 ETL_CONSTANT bool integral_limits_common<T>::is_specialized;
150
151 template <typename T>
152 ETL_CONSTANT bool integral_limits_common<T>::is_integer;
153
154 template <typename T>
155 ETL_CONSTANT bool integral_limits_common<T>::is_exact;
156
157 template <typename T>
158 ETL_CONSTANT int integral_limits_common<T>::max_digits10;
159
160 template <typename T>
161 ETL_CONSTANT int integral_limits_common<T>::radix;
162
163 template <typename T>
164 ETL_CONSTANT int integral_limits_common<T>::min_exponent;
165
166 template <typename T>
167 ETL_CONSTANT int integral_limits_common<T>::min_exponent10;
168
169 template <typename T>
170 ETL_CONSTANT int integral_limits_common<T>::max_exponent;
171
172 template <typename T>
173 ETL_CONSTANT int integral_limits_common<T>::max_exponent10;
174
175 template <typename T>
176 ETL_CONSTANT bool integral_limits_common<T>::has_infinity;
177
178 template <typename T>
179 ETL_CONSTANT bool integral_limits_common<T>::has_quiet_NaN;
180
181 template <typename T>
182 ETL_CONSTANT bool integral_limits_common<T>::has_signaling_NaN;
183
184 template <typename T>
185 ETL_CONSTANT bool integral_limits_common<T>::has_denorm_loss;
186
187 template <typename T>
188 ETL_CONSTANT bool integral_limits_common<T>::is_iec559;
189
190 template <typename T>
191 ETL_CONSTANT bool integral_limits_common<T>::is_bounded;
192
193 template <typename T>
194 ETL_CONSTANT bool integral_limits_common<T>::traps;
195
196 template <typename T>
197 ETL_CONSTANT bool integral_limits_common<T>::tinyness_before;
198
199 template <typename T>
200 ETL_CONSTANT float_denorm_style integral_limits_common<T>::has_denorm;
201
202 template <typename T>
203 ETL_CONSTANT float_round_style integral_limits_common<T>::round_style;
204
205 //*********************************
206 // bool
207 template <typename T = void>
208 struct integral_limits_bool
209 {
210 static ETL_CONSTANT int digits = 1;
211 static ETL_CONSTANT int digits10 = 0;
212 static ETL_CONSTANT bool is_signed = false;
213 static ETL_CONSTANT bool is_modulo = false;
214 };
215
216 template <typename T>
217 ETL_CONSTANT int integral_limits_bool<T>::digits;
218
219 template <typename T>
220 ETL_CONSTANT int integral_limits_bool<T>::digits10;
221
222 template <typename T>
223 ETL_CONSTANT bool integral_limits_bool<T>::is_signed;
224
225 template <typename T>
226 ETL_CONSTANT bool integral_limits_bool<T>::is_modulo;
227
228 //*********************************
229 // char
230 template <typename T = void>
231 struct integral_limits_char
232 {
233 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(char)) - (etl::is_signed<char>::value ? 1 : 0);
234 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
235 static ETL_CONSTANT bool is_signed = etl::is_signed<char>::value;
236 static ETL_CONSTANT bool is_modulo = etl::is_unsigned<char>::value;
237 };
238
239 template <typename T>
240 ETL_CONSTANT int integral_limits_char<T>::digits;
241
242 template <typename T>
243 ETL_CONSTANT int integral_limits_char<T>::digits10;
244
245 template <typename T>
246 ETL_CONSTANT bool integral_limits_char<T>::is_signed;
247
248 template <typename T>
249 ETL_CONSTANT bool integral_limits_char<T>::is_modulo;
250
251 //*********************************
252 // unsigned char
253 template <typename T = void>
254 struct integral_limits_unsigned_char
255 {
256 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(unsigned char));
257 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
258 static ETL_CONSTANT bool is_signed = false;
259 static ETL_CONSTANT bool is_modulo = true;
260 };
261
262 template <typename T>
263 ETL_CONSTANT int integral_limits_unsigned_char<T>::digits;
264
265 template <typename T>
266 ETL_CONSTANT int integral_limits_unsigned_char<T>::digits10;
267
268 template <typename T>
269 ETL_CONSTANT bool integral_limits_unsigned_char<T>::is_signed;
270
271 template <typename T>
272 ETL_CONSTANT bool integral_limits_unsigned_char<T>::is_modulo;
273
274 //*********************************
275 // signed char
276 template <typename T = void>
277 struct integral_limits_signed_char
278 {
279 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(char)) - 1;
280 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
281 static ETL_CONSTANT bool is_signed = true;
282 static ETL_CONSTANT bool is_modulo = false;
283 };
284
285 template <typename T>
286 ETL_CONSTANT int integral_limits_signed_char<T>::digits;
287
288 template <typename T>
289 ETL_CONSTANT int integral_limits_signed_char<T>::digits10;
290
291 template <typename T>
292 ETL_CONSTANT bool integral_limits_signed_char<T>::is_signed;
293
294 template <typename T>
295 ETL_CONSTANT bool integral_limits_signed_char<T>::is_modulo;
296
297#if ETL_HAS_NATIVE_CHAR8_T
298 //*********************************
299 // char8_t
300 template <typename T = void>
301 struct integral_limits_char8_t
302 {
303 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(char8_t)) - (etl::is_signed<char8_t>::value ? 1 : 0);
304 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
305 static ETL_CONSTANT bool is_signed = etl::is_signed<char8_t>::value;
306 static ETL_CONSTANT bool is_modulo = false;
307 };
308
309 template <typename T>
310 ETL_CONSTANT int integral_limits_char8_t<T>::digits;
311
312 template <typename T>
313 ETL_CONSTANT int integral_limits_char8_t<T>::digits10;
314
315 template <typename T>
316 ETL_CONSTANT bool integral_limits_char8_t<T>::is_signed;
317
318 template <typename T>
319 ETL_CONSTANT bool integral_limits_char8_t<T>::is_modulo;
320#endif
321
322#if ETL_HAS_NATIVE_CHAR16_T
323 //*********************************
324 // char16_t
325 template <typename T = void>
326 struct integral_limits_char16_t
327 {
328 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(char16_t));
329 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
330 static ETL_CONSTANT bool is_signed = false;
331 static ETL_CONSTANT bool is_modulo = true;
332 };
333
334 template <typename T>
335 ETL_CONSTANT int integral_limits_char16_t<T>::digits;
336
337 template <typename T>
338 ETL_CONSTANT int integral_limits_char16_t<T>::digits10;
339
340 template <typename T>
341 ETL_CONSTANT bool integral_limits_char16_t<T>::is_signed;
342
343 template <typename T>
344 ETL_CONSTANT bool integral_limits_char16_t<T>::is_modulo;
345#endif
346
347#if ETL_HAS_NATIVE_CHAR32_T
348 //*********************************
349 // char32_t
350 template <typename T = void>
351 struct integral_limits_char32_t
352 {
353 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(char32_t));
354 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
355 static ETL_CONSTANT bool is_signed = false;
356 static ETL_CONSTANT bool is_modulo = true;
357 };
358
359 template <typename T>
360 ETL_CONSTANT int integral_limits_char32_t<T>::digits;
361
362 template <typename T>
363 ETL_CONSTANT int integral_limits_char32_t<T>::digits10;
364
365 template <typename T>
366 ETL_CONSTANT bool integral_limits_char32_t<T>::is_signed;
367
368 template <typename T>
369 ETL_CONSTANT bool integral_limits_char32_t<T>::is_modulo;
370#endif
371
372 //*********************************
373 // wchar_t
374 template <typename T = void>
375 struct integral_limits_wchar_t
376 {
377 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(wchar_t)) - (etl::is_signed<wchar_t>::value ? 1 : 0);
378 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
379 static ETL_CONSTANT bool is_signed = etl::is_signed<wchar_t>::value;
380 static ETL_CONSTANT bool is_modulo = etl::is_unsigned<wchar_t>::value;
381 };
382
383 template <typename T>
384 ETL_CONSTANT int integral_limits_wchar_t<T>::digits;
385
386 template <typename T>
387 ETL_CONSTANT int integral_limits_wchar_t<T>::digits10;
388
389 template <typename T>
390 ETL_CONSTANT bool integral_limits_wchar_t<T>::is_signed;
391
392 template <typename T>
393 ETL_CONSTANT bool integral_limits_wchar_t<T>::is_modulo;
394
395 //*********************************
396 // short
397 template <typename T = void>
398 struct integral_limits_short
399 {
400 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(short)) - 1;
401 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
402 static ETL_CONSTANT bool is_signed = true;
403 static ETL_CONSTANT bool is_modulo = false;
404 };
405
406 template <typename T>
407 ETL_CONSTANT int integral_limits_short<T>::digits;
408
409 template <typename T>
410 ETL_CONSTANT int integral_limits_short<T>::digits10;
411
412 template <typename T>
413 ETL_CONSTANT bool integral_limits_short<T>::is_signed;
414
415 template <typename T>
416 ETL_CONSTANT bool integral_limits_short<T>::is_modulo;
417
418 //*********************************
419 // unsigned short
420 template <typename T = void>
421 struct integral_limits_unsigned_short
422 {
423 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(unsigned short));
424 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
425 static ETL_CONSTANT bool is_signed = false;
426 static ETL_CONSTANT bool is_modulo = true;
427 };
428
429 template <typename T>
430 ETL_CONSTANT int integral_limits_unsigned_short<T>::digits;
431
432 template <typename T>
433 ETL_CONSTANT int integral_limits_unsigned_short<T>::digits10;
434
435 template <typename T>
436 ETL_CONSTANT bool integral_limits_unsigned_short<T>::is_signed;
437
438 template <typename T>
439 ETL_CONSTANT bool integral_limits_unsigned_short<T>::is_modulo;
440
441 //*********************************
442 // int
443 template <typename T = void>
444 struct integral_limits_int
445 {
446 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(int)) - 1;
447 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
448 static ETL_CONSTANT bool is_signed = true;
449 static ETL_CONSTANT bool is_modulo = false;
450 };
451
452 template <typename T>
453 ETL_CONSTANT int integral_limits_int<T>::digits;
454
455 template <typename T>
456 ETL_CONSTANT int integral_limits_int<T>::digits10;
457
458 template <typename T>
459 ETL_CONSTANT bool integral_limits_int<T>::is_signed;
460
461 template <typename T>
462 ETL_CONSTANT bool integral_limits_int<T>::is_modulo;
463
464 //*********************************
465 // unsigned int
466 template <typename T = void>
467 struct integral_limits_unsigned_int
468 {
469 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(unsigned int));
470 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
471 static ETL_CONSTANT bool is_signed = false;
472 static ETL_CONSTANT bool is_modulo = true;
473 };
474
475 template <typename T>
476 ETL_CONSTANT int integral_limits_unsigned_int<T>::digits;
477
478 template <typename T>
479 ETL_CONSTANT int integral_limits_unsigned_int<T>::digits10;
480
481 template <typename T>
482 ETL_CONSTANT bool integral_limits_unsigned_int<T>::is_signed;
483
484 template <typename T>
485 ETL_CONSTANT bool integral_limits_unsigned_int<T>::is_modulo;
486
487 //*********************************
488 // long
489 template <typename T = void>
490 struct integral_limits_long
491 {
492 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(long)) - 1;
493 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
494 static ETL_CONSTANT bool is_signed = true;
495 static ETL_CONSTANT bool is_modulo = false;
496 };
497
498 template <typename T>
499 ETL_CONSTANT int integral_limits_long<T>::digits;
500
501 template <typename T>
502 ETL_CONSTANT int integral_limits_long<T>::digits10;
503
504 template <typename T>
505 ETL_CONSTANT bool integral_limits_long<T>::is_signed;
506
507 template <typename T>
508 ETL_CONSTANT bool integral_limits_long<T>::is_modulo;
509
510 //*********************************
511 // unsigned long
512 template <typename T = void>
513 struct integral_limits_unsigned_long
514 {
515 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(unsigned long));
516 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
517 static ETL_CONSTANT bool is_signed = false;
518 static ETL_CONSTANT bool is_modulo = true;
519 };
520
521 template <typename T>
522 ETL_CONSTANT int integral_limits_unsigned_long<T>::digits;
523
524 template <typename T>
525 ETL_CONSTANT int integral_limits_unsigned_long<T>::digits10;
526
527 template <typename T>
528 ETL_CONSTANT bool integral_limits_unsigned_long<T>::is_signed;
529
530 template <typename T>
531 ETL_CONSTANT bool integral_limits_unsigned_long<T>::is_modulo;
532
533 //*********************************
534 // long long
535 template <typename T = void>
536 struct integral_limits_long_long
537 {
538 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(long long)) - 1;
539 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
540 static ETL_CONSTANT bool is_signed = true;
541 static ETL_CONSTANT bool is_modulo = false;
542 };
543
544 template <typename T>
545 ETL_CONSTANT int integral_limits_long_long<T>::digits;
546
547 template <typename T>
548 ETL_CONSTANT int integral_limits_long_long<T>::digits10;
549
550 template <typename T>
551 ETL_CONSTANT bool integral_limits_long_long<T>::is_signed;
552
553 template <typename T>
554 ETL_CONSTANT bool integral_limits_long_long<T>::is_modulo;
555
556 //*********************************
557 // unsigned long long
558 template <typename T = void>
559 struct integral_limits_unsigned_long_long
560 {
561 static ETL_CONSTANT int digits = (CHAR_BIT * sizeof(unsigned long long));
562 static ETL_CONSTANT int digits10 = ETL_LOG10_OF_2(digits);
563 static ETL_CONSTANT bool is_signed = false;
564 static ETL_CONSTANT bool is_modulo = true;
565 };
566
567 template <typename T>
568 ETL_CONSTANT int integral_limits_unsigned_long_long<T>::digits;
569
570 template <typename T>
571 ETL_CONSTANT int integral_limits_unsigned_long_long<T>::digits10;
572
573 template <typename T>
574 ETL_CONSTANT bool integral_limits_unsigned_long_long<T>::is_signed;
575
576 template <typename T>
577 ETL_CONSTANT bool integral_limits_unsigned_long_long<T>::is_modulo;
578
579 //*********************************
580 // Floating point limits common
581 template <typename T = void>
582 class floating_point_limits_common
583 {
584 public:
585
586 static ETL_CONSTANT bool is_specialized = true;
587 static ETL_CONSTANT bool is_signed = true;
588 static ETL_CONSTANT bool is_integer = false;
589 static ETL_CONSTANT bool is_exact = false;
590 static ETL_CONSTANT int radix = 2;
591 static ETL_CONSTANT bool has_infinity = true;
592 static ETL_CONSTANT bool has_quiet_NaN = ETL_HAS_NAN;
593 static ETL_CONSTANT bool has_signaling_NaN = ETL_HAS_NAN;
594 static ETL_CONSTANT bool has_denorm_loss = false;
595 static ETL_CONSTANT bool is_iec559 = false;
596 static ETL_CONSTANT bool is_bounded = true;
597 static ETL_CONSTANT bool is_modulo = false;
598 static ETL_CONSTANT bool traps = false;
599 static ETL_CONSTANT bool tinyness_before = false;
600 static ETL_CONSTANT float_denorm_style has_denorm = denorm_indeterminate;
601 static ETL_CONSTANT float_round_style round_style = round_indeterminate;
602
603 static float round_error() { return float(0.5); }
604 };
605
606 template <typename T>
607 ETL_CONSTANT bool floating_point_limits_common<T>::is_specialized;
608
609 template <typename T>
610 ETL_CONSTANT bool floating_point_limits_common<T>::is_integer;
611
612 template <typename T>
613 ETL_CONSTANT bool floating_point_limits_common<T>::is_exact;
614
615 template <typename T>
616 ETL_CONSTANT int floating_point_limits_common<T>::radix;
617
618 template <typename T>
619 ETL_CONSTANT bool floating_point_limits_common<T>::has_infinity;
620
621 template <typename T>
622 ETL_CONSTANT bool floating_point_limits_common<T>::has_quiet_NaN;
623
624 template <typename T>
625 ETL_CONSTANT bool floating_point_limits_common<T>::has_signaling_NaN;
626
627 template <typename T>
628 ETL_CONSTANT bool floating_point_limits_common<T>::has_denorm_loss;
629
630 template <typename T>
631 ETL_CONSTANT bool floating_point_limits_common<T>::is_iec559;
632
633 template <typename T>
634 ETL_CONSTANT bool floating_point_limits_common<T>::is_bounded;
635
636 template <typename T>
637 ETL_CONSTANT bool floating_point_limits_common<T>::traps;
638
639 template <typename T>
640 ETL_CONSTANT bool floating_point_limits_common<T>::tinyness_before;
641
642 template <typename T>
643 ETL_CONSTANT float_denorm_style floating_point_limits_common<T>::has_denorm;
644
645 template <typename T>
646 ETL_CONSTANT float_round_style floating_point_limits_common<T>::round_style;
647
648 //*********************************
649 // float
650 template <typename T = void>
651 struct floating_point_limits_float
652 {
653 static ETL_CONSTANT int digits = FLT_MANT_DIG;
654 static ETL_CONSTANT int digits10 = FLT_DIG;
655 static ETL_CONSTANT int max_digits10 = ETL_LOG10_OF_2(FLT_MANT_DIG) + 2;
656
657 static ETL_CONSTANT int min_exponent = FLT_MIN_EXP;
658 static ETL_CONSTANT int min_exponent10 = FLT_MIN_10_EXP;
659 static ETL_CONSTANT int max_exponent = FLT_MAX_EXP;
660 static ETL_CONSTANT int max_exponent10 = FLT_MAX_10_EXP;
661 };
662
663 template <typename T>
664 ETL_CONSTANT int floating_point_limits_float<T>::digits;
665
666 template <typename T>
667 ETL_CONSTANT int floating_point_limits_float<T>::digits10;
668
669 template <typename T>
670 ETL_CONSTANT int floating_point_limits_float<T>::max_digits10;
671
672 template <typename T>
673 ETL_CONSTANT int floating_point_limits_float<T>::min_exponent;
674
675 template <typename T>
676 ETL_CONSTANT int floating_point_limits_float<T>::min_exponent10;
677
678 template <typename T>
679 ETL_CONSTANT int floating_point_limits_float<T>::max_exponent;
680
681 template <typename T>
682 ETL_CONSTANT int floating_point_limits_float<T>::max_exponent10;
683
684 //*********************************
685 // double
686 template <typename T = void>
687 struct floating_point_limits_double
688 {
689 static ETL_CONSTANT int digits = DBL_MANT_DIG;
690 static ETL_CONSTANT int digits10 = DBL_DIG;
691 static ETL_CONSTANT int max_digits10 = ETL_LOG10_OF_2(DBL_MANT_DIG) + 2;
692
693 static ETL_CONSTANT int min_exponent = DBL_MIN_EXP;
694 static ETL_CONSTANT int min_exponent10 = DBL_MIN_10_EXP;
695 static ETL_CONSTANT int max_exponent = DBL_MAX_EXP;
696 static ETL_CONSTANT int max_exponent10 = DBL_MAX_10_EXP;
697 };
698
699 template <typename T>
700 ETL_CONSTANT int floating_point_limits_double<T>::digits;
701
702 template <typename T>
703 ETL_CONSTANT int floating_point_limits_double<T>::digits10;
704
705 template <typename T>
706 ETL_CONSTANT int floating_point_limits_double<T>::max_digits10;
707
708 template <typename T>
709 ETL_CONSTANT int floating_point_limits_double<T>::min_exponent;
710
711 template <typename T>
712 ETL_CONSTANT int floating_point_limits_double<T>::min_exponent10;
713
714 template <typename T>
715 ETL_CONSTANT int floating_point_limits_double<T>::max_exponent;
716
717 template <typename T>
718 ETL_CONSTANT int floating_point_limits_double<T>::max_exponent10;
719
720 //*********************************
721 // long double
722 template <typename T = void>
723 struct floating_point_limits_long_double
724 {
725 static ETL_CONSTANT int digits = LDBL_MANT_DIG;
726 static ETL_CONSTANT int digits10 = LDBL_DIG;
727 static ETL_CONSTANT int max_digits10 = ETL_LOG10_OF_2(LDBL_MANT_DIG) + 2;
728
729 static ETL_CONSTANT int min_exponent = LDBL_MIN_EXP;
730 static ETL_CONSTANT int min_exponent10 = LDBL_MIN_10_EXP;
731 static ETL_CONSTANT int max_exponent = LDBL_MAX_EXP;
732 static ETL_CONSTANT int max_exponent10 = LDBL_MAX_10_EXP;
733 };
734
735 template <typename T>
736 ETL_CONSTANT int floating_point_limits_long_double<T>::digits;
737
738 template <typename T>
739 ETL_CONSTANT int floating_point_limits_long_double<T>::digits10;
740
741 template <typename T>
742 ETL_CONSTANT int floating_point_limits_long_double<T>::max_digits10;
743
744 template <typename T>
745 ETL_CONSTANT int floating_point_limits_long_double<T>::min_exponent;
746
747 template <typename T>
748 ETL_CONSTANT int floating_point_limits_long_double<T>::min_exponent10;
749
750 template <typename T>
751 ETL_CONSTANT int floating_point_limits_long_double<T>::max_exponent;
752
753 template <typename T>
754 ETL_CONSTANT int floating_point_limits_long_double<T>::max_exponent10;
755 }
756
757 //***************************************************************************
758 // Default
759 template <typename T>
760 class numeric_limits;
761
762 template <typename T>
763 class numeric_limits<const T> : public numeric_limits<T> { };
764
765 template <typename T>
766 class numeric_limits<volatile T> : public numeric_limits<T> { };
767
768 template <typename T>
769 class numeric_limits<const volatile T> : public numeric_limits<T> { };
770
771 //***********************************
772 // bool
773 template<>
774 class numeric_limits<bool> : public private_limits::integral_limits_common<>,
775 public private_limits::integral_limits_bool<>
776 {
777 public:
778
779 static ETL_CONSTEXPR bool min() { return false; }
780 static ETL_CONSTEXPR bool max() { return true; }
781 static ETL_CONSTEXPR bool lowest() { return false; }
782 static ETL_CONSTEXPR bool epsilon() { return false; }
783 static ETL_CONSTEXPR bool round_error() { return false; }
784 static ETL_CONSTEXPR bool denorm_min() { return false; }
785 static ETL_CONSTEXPR bool infinity() { return false; }
786 static ETL_CONSTEXPR bool quiet_NaN() { return false; }
787 static ETL_CONSTEXPR bool signaling_NaN() { return false; }
788 };
789
790 //***************************************************************************
791 // char
792 template<>
793 class numeric_limits<char> : public private_limits::integral_limits_common<>,
794 public private_limits::integral_limits_char<>
795 {
796 public:
797
798 static ETL_CONSTEXPR char min() { return char(CHAR_MIN); }
799 static ETL_CONSTEXPR char max() { return char(CHAR_MAX); }
800 static ETL_CONSTEXPR char lowest() { return char(CHAR_MIN); }
801 static ETL_CONSTEXPR char epsilon() { return 0; }
802 static ETL_CONSTEXPR char round_error() { return 0; }
803 static ETL_CONSTEXPR char denorm_min() { return 0; }
804 static ETL_CONSTEXPR char infinity() { return 0; }
805 static ETL_CONSTEXPR char quiet_NaN() { return 0; }
806 static ETL_CONSTEXPR char signaling_NaN() { return 0; }
807 };
808
809 //***************************************************************************
810 // unsigned char
811 template<>
812 class numeric_limits<unsigned char> : public private_limits::integral_limits_common<>,
813 public private_limits::integral_limits_unsigned_char<>
814 {
815 public:
816
817 static ETL_CONSTEXPR unsigned char min() { return 0U; }
818 static ETL_CONSTEXPR unsigned char max() { return UCHAR_MAX; }
819 static ETL_CONSTEXPR unsigned char lowest() { return 0U; }
820 static ETL_CONSTEXPR unsigned char epsilon() { return 0U; }
821 static ETL_CONSTEXPR unsigned char round_error() { return 0U; }
822 static ETL_CONSTEXPR unsigned char denorm_min() { return 0U; }
823 static ETL_CONSTEXPR unsigned char infinity() { return 0U; }
824 static ETL_CONSTEXPR unsigned char quiet_NaN() { return 0U; }
825 static ETL_CONSTEXPR unsigned char signaling_NaN() { return 0U; }
826 };
827
828 //***************************************************************************
829 // signed char
830 template<>
831 class numeric_limits<signed char> : public private_limits::integral_limits_common<>,
832 public private_limits::integral_limits_signed_char<>
833 {
834 public:
835
836 static ETL_CONSTEXPR signed char min() { return SCHAR_MIN; }
837 static ETL_CONSTEXPR signed char max() { return SCHAR_MAX; }
838 static ETL_CONSTEXPR signed char lowest() { return SCHAR_MIN; }
839 static ETL_CONSTEXPR signed char epsilon() { return 0; }
840 static ETL_CONSTEXPR signed char round_error() { return 0; }
841 static ETL_CONSTEXPR signed char denorm_min() { return 0; }
842 static ETL_CONSTEXPR signed char infinity() { return 0; }
843 static ETL_CONSTEXPR signed char quiet_NaN() { return 0; }
844 static ETL_CONSTEXPR signed char signaling_NaN() { return 0; }
845 };
846
847#if ETL_HAS_NATIVE_CHAR8_T
848 //***************************************************************************
849 // char8_t
850 template<>
851 class numeric_limits<char8_t> : public private_limits::integral_limits_common<>,
852 public private_limits::integral_limits_char8_t<>
853 {
854 public:
855
856 static ETL_CONSTEXPR char8_t min() { return char8_t(CHAR_MIN); }
857 static ETL_CONSTEXPR char8_t max() { return char8_t(CHAR_MAX); }
858 static ETL_CONSTEXPR char8_t lowest() { return char8_t(CHAR_MIN); }
859 static ETL_CONSTEXPR char8_t epsilon() { return 0; }
860 static ETL_CONSTEXPR char8_t round_error() { return 0; }
861 static ETL_CONSTEXPR char8_t denorm_min() { return 0; }
862 static ETL_CONSTEXPR char8_t infinity() { return 0; }
863 static ETL_CONSTEXPR char8_t quiet_NaN() { return 0; }
864 static ETL_CONSTEXPR char8_t signaling_NaN() { return 0; }
865 };
866#endif
867
868#if ETL_HAS_NATIVE_CHAR16_T
869 //***************************************************************************
870 // char16_t
871 template<>
872 class numeric_limits<char16_t> : public private_limits::integral_limits_common<>,
873 public private_limits::integral_limits_char16_t<>
874 {
875 public:
876
877 static ETL_CONSTEXPR char16_t min() { return 0U; }
878 static ETL_CONSTEXPR char16_t max() { return UINT_LEAST16_MAX; }
879 static ETL_CONSTEXPR char16_t lowest() { return 0U; }
880 static ETL_CONSTEXPR char16_t epsilon() { return 0U; }
881 static ETL_CONSTEXPR char16_t round_error() { return 0U; }
882 static ETL_CONSTEXPR char16_t denorm_min() { return 0U; }
883 static ETL_CONSTEXPR char16_t infinity() { return 0U; }
884 static ETL_CONSTEXPR char16_t quiet_NaN() { return 0U; }
885 static ETL_CONSTEXPR char16_t signaling_NaN() { return 0U; }
886 };
887#endif
888
889#if ETL_HAS_NATIVE_CHAR32_T
890 //***************************************************************************
891 // char32_t
892 template<>
893 class numeric_limits<char32_t> : public private_limits::integral_limits_common<>,
894 public private_limits::integral_limits_char32_t<>
895 {
896 public:
897
898 static ETL_CONSTEXPR char32_t min() { return 0U; }
899 static ETL_CONSTEXPR char32_t max() { return UINT_LEAST32_MAX; }
900 static ETL_CONSTEXPR char32_t lowest() { return 0U; }
901 static ETL_CONSTEXPR char32_t epsilon() { return 0U; }
902 static ETL_CONSTEXPR char32_t round_error() { return 0U; }
903 static ETL_CONSTEXPR char32_t denorm_min() { return 0U; }
904 static ETL_CONSTEXPR char32_t infinity() { return 0U; }
905 static ETL_CONSTEXPR char32_t quiet_NaN() { return 0U; }
906 static ETL_CONSTEXPR char32_t signaling_NaN() { return 0U; }
907 };
908#endif
909
910 //***************************************************************************
911 // wchar_t
912 template<>
913 class numeric_limits<wchar_t> : public private_limits::integral_limits_common<>,
914 public private_limits::integral_limits_wchar_t<>
915 {
916 public:
917
918 static ETL_CONSTEXPR wchar_t min() { return WCHAR_MIN; }
919 static ETL_CONSTEXPR wchar_t max() { return WCHAR_MAX; }
920 static ETL_CONSTEXPR wchar_t lowest() { return WCHAR_MIN; }
921 static ETL_CONSTEXPR wchar_t epsilon() { return wchar_t(0); }
922 static ETL_CONSTEXPR wchar_t round_error() { return wchar_t(0); }
923 static ETL_CONSTEXPR wchar_t denorm_min() { return wchar_t(0); }
924 static ETL_CONSTEXPR wchar_t infinity() { return wchar_t(0); }
925 static ETL_CONSTEXPR wchar_t quiet_NaN() { return wchar_t(0); }
926 static ETL_CONSTEXPR wchar_t signaling_NaN() { return wchar_t(0); }
927 };
928
929 //***************************************************************************
930 // short
931 template<>
932 class numeric_limits<short> : public private_limits::integral_limits_common<>,
933 public private_limits::integral_limits_short<>
934 {
935 public:
936
937 static ETL_CONSTEXPR short min() { return SHRT_MIN; }
938 static ETL_CONSTEXPR short max() { return SHRT_MAX; }
939 static ETL_CONSTEXPR short lowest() { return SHRT_MIN; }
940 static ETL_CONSTEXPR short epsilon() { return 0; }
941 static ETL_CONSTEXPR short round_error() { return 0; }
942 static ETL_CONSTEXPR short denorm_min() { return 0; }
943 static ETL_CONSTEXPR short infinity() { return 0; }
944 static ETL_CONSTEXPR short quiet_NaN() { return 0; }
945 static ETL_CONSTEXPR short signaling_NaN() { return 0; }
946 };
947
948 //***************************************************************************
949 // unsigned short
950 template<>
951 class numeric_limits<unsigned short> : public private_limits::integral_limits_common<>,
952 public private_limits::integral_limits_unsigned_short<>
953 {
954 public:
955
956 static ETL_CONSTEXPR unsigned short min() { return 0U; }
957 static ETL_CONSTEXPR unsigned short max() { return USHRT_MAX; }
958 static ETL_CONSTEXPR unsigned short lowest() { return 0U; }
959 static ETL_CONSTEXPR unsigned short epsilon() { return 0U; }
960 static ETL_CONSTEXPR unsigned short round_error() { return 0U; }
961 static ETL_CONSTEXPR unsigned short denorm_min() { return 0U; }
962 static ETL_CONSTEXPR unsigned short infinity() { return 0U; }
963 static ETL_CONSTEXPR unsigned short quiet_NaN() { return 0U; }
964 static ETL_CONSTEXPR unsigned short signaling_NaN() { return 0U; }
965 };
966
967 //***************************************************************************
968 // int
969 template<>
970 class numeric_limits<int> : public private_limits::integral_limits_common<>,
971 public private_limits::integral_limits_int<>
972 {
973 public:
974
975 static ETL_CONSTEXPR int min() { return INT_MIN; }
976 static ETL_CONSTEXPR int max() { return INT_MAX; }
977 static ETL_CONSTEXPR int lowest() { return INT_MIN; }
978 static ETL_CONSTEXPR int epsilon() { return 0; }
979 static ETL_CONSTEXPR int round_error() { return 0; }
980 static ETL_CONSTEXPR int denorm_min() { return 0; }
981 static ETL_CONSTEXPR int infinity() { return 0; }
982 static ETL_CONSTEXPR int quiet_NaN() { return 0; }
983 static ETL_CONSTEXPR int signaling_NaN() { return 0; }
984 };
985
986 //***************************************************************************
987 // unsigned int
988 template<>
989 class numeric_limits<unsigned int> : public private_limits::integral_limits_common<>,
990 public private_limits::integral_limits_unsigned_int<>
991 {
992 public:
993
994 static ETL_CONSTEXPR unsigned int min() { return 0U; }
995 static ETL_CONSTEXPR unsigned int max() { return UINT_MAX; }
996 static ETL_CONSTEXPR unsigned int lowest() { return 0U; }
997 static ETL_CONSTEXPR unsigned int epsilon() { return 0U; }
998 static ETL_CONSTEXPR unsigned int round_error() { return 0U; }
999 static ETL_CONSTEXPR unsigned int denorm_min() { return 0U; }
1000 static ETL_CONSTEXPR unsigned int infinity() { return 0U; }
1001 static ETL_CONSTEXPR unsigned int quiet_NaN() { return 0U; }
1002 static ETL_CONSTEXPR unsigned int signaling_NaN() { return 0U; }
1003 };
1004
1005 //***************************************************************************
1006 // long
1007 template<>
1008 class numeric_limits<long> : public private_limits::integral_limits_common<>,
1009 public private_limits::integral_limits_long<>
1010 {
1011 public:
1012
1013 static ETL_CONSTEXPR long min() { return LONG_MIN; }
1014 static ETL_CONSTEXPR long max() { return LONG_MAX; }
1015 static ETL_CONSTEXPR long lowest() { return LONG_MIN; }
1016 static ETL_CONSTEXPR long epsilon() { return 0; }
1017 static ETL_CONSTEXPR long round_error() { return 0; }
1018 static ETL_CONSTEXPR long denorm_min() { return 0; }
1019 static ETL_CONSTEXPR long infinity() { return 0; }
1020 static ETL_CONSTEXPR long quiet_NaN() { return 0; }
1021 static ETL_CONSTEXPR long signaling_NaN() { return 0; }
1022 };
1023
1024 //***************************************************************************
1025 // unsigned long
1026 template<>
1027 class numeric_limits<unsigned long> : public private_limits::integral_limits_common<>,
1028 public private_limits::integral_limits_unsigned_long<>
1029 {
1030 public:
1031
1032 static ETL_CONSTEXPR unsigned long min() { return 0U; }
1033 static ETL_CONSTEXPR unsigned long max() { return ULONG_MAX; }
1034 static ETL_CONSTEXPR unsigned long lowest() { return 0U; }
1035 static ETL_CONSTEXPR unsigned long epsilon() { return 0U; }
1036 static ETL_CONSTEXPR unsigned long round_error() { return 0U; }
1037 static ETL_CONSTEXPR unsigned long denorm_min() { return 0U; }
1038 static ETL_CONSTEXPR unsigned long infinity() { return 0U; }
1039 static ETL_CONSTEXPR unsigned long quiet_NaN() { return 0U; }
1040 static ETL_CONSTEXPR unsigned long signaling_NaN() { return 0U; }
1041 };
1042
1043 //***************************************************************************
1044 // long long
1045 template<>
1046 class numeric_limits<long long> : public private_limits::integral_limits_common<>,
1047 public private_limits::integral_limits_long_long<>
1048 {
1049 public:
1050
1051 static ETL_CONSTEXPR long long min() { return LLONG_MIN; }
1052 static ETL_CONSTEXPR long long max() { return LLONG_MAX; }
1053 static ETL_CONSTEXPR long long lowest() { return LLONG_MIN; }
1054 static ETL_CONSTEXPR long long epsilon() { return 0; }
1055 static ETL_CONSTEXPR long long round_error() { return 0; }
1056 static ETL_CONSTEXPR long long denorm_min() { return 0; }
1057 static ETL_CONSTEXPR long long infinity() { return 0; }
1058 static ETL_CONSTEXPR long long quiet_NaN() { return 0; }
1059 static ETL_CONSTEXPR long long signaling_NaN() { return 0; }
1060 };
1061
1062 //***************************************************************************
1063 // unsigned long long
1064 template<>
1065 class numeric_limits<unsigned long long> : public private_limits::integral_limits_common<>,
1066 public private_limits::integral_limits_unsigned_long_long<>
1067 {
1068 public:
1069
1070 static ETL_CONSTEXPR unsigned long long min() { return 0U; }
1071 static ETL_CONSTEXPR unsigned long long max() { return ULLONG_MAX; }
1072 static ETL_CONSTEXPR unsigned long long lowest() { return 0U; }
1073 static ETL_CONSTEXPR unsigned long long epsilon() { return 0U; }
1074 static ETL_CONSTEXPR unsigned long long round_error() { return 0U; }
1075 static ETL_CONSTEXPR unsigned long long denorm_min() { return 0U; }
1076 static ETL_CONSTEXPR unsigned long long infinity() { return 0U; }
1077 static ETL_CONSTEXPR unsigned long long quiet_NaN() { return 0U; }
1078 static ETL_CONSTEXPR unsigned long long signaling_NaN() { return 0U; }
1079 };
1080
1081 //***************************************************************************
1082 // float
1083 template<>
1084 class numeric_limits<float> : public private_limits::floating_point_limits_common<>,
1085 public private_limits::floating_point_limits_float<>
1086 {
1087 public:
1088
1089 static ETL_CONSTEXPR float min() { return FLT_MIN; }
1090 static ETL_CONSTEXPR float max() { return FLT_MAX; }
1091 static ETL_CONSTEXPR float lowest() { return -FLT_MAX; }
1092 static ETL_CONSTEXPR float epsilon() { return FLT_EPSILON; }
1093 static ETL_CONSTEXPR float denorm_min() { return FLT_MIN; }
1094 static ETL_CONSTEXPR float infinity() { return HUGE_VALF; }
1095 static float quiet_NaN() { return ETL_NANF; }
1096 static float signaling_NaN() { return ETL_NANF; }
1097 };
1098
1099 //***************************************************************************
1100 // double
1101 template<>
1102 class numeric_limits<double> : public private_limits::floating_point_limits_common<>,
1103 public private_limits::floating_point_limits_double<>
1104 {
1105 public:
1106
1107 static ETL_CONSTEXPR double min() { return DBL_MIN; }
1108 static ETL_CONSTEXPR double max() { return DBL_MAX; }
1109 static ETL_CONSTEXPR double lowest() { return -DBL_MAX; }
1110 static ETL_CONSTEXPR double epsilon() { return DBL_EPSILON; }
1111 static ETL_CONSTEXPR double denorm_min() { return DBL_MIN; }
1112 static ETL_CONSTEXPR double infinity() { return HUGE_VAL; }
1113 static double quiet_NaN() { return ETL_NAN; }
1114 static double signaling_NaN() { return ETL_NAN; }
1115 };
1116
1117 //***************************************************************************
1118 // long double
1119 template<>
1120 class numeric_limits<long double> : public private_limits::floating_point_limits_common<>,
1121 public private_limits::floating_point_limits_long_double<>
1122 {
1123 public:
1124
1125 static ETL_CONSTEXPR long double min() { return LDBL_MIN; }
1126 static ETL_CONSTEXPR long double max() { return LDBL_MAX; }
1127 static ETL_CONSTEXPR long double lowest() { return -LDBL_MAX; }
1128 static ETL_CONSTEXPR long double epsilon() { return LDBL_EPSILON; }
1129 static ETL_CONSTEXPR long double denorm_min() { return LDBL_MIN; }
1130 static ETL_CONSTEXPR long double infinity() { return HUGE_VALL; }
1131 static long double quiet_NaN() { return ETL_NANL; }
1132 static long double signaling_NaN() { return ETL_NANL; }
1133 };
1134}
1135
1136#else
1137
1138#include <limits>
1139
1140namespace etl
1141{
1142 enum float_round_style
1143 {
1144 round_indeterminate = std::round_indeterminate,
1145 round_toward_zero = std::round_toward_zero,
1146 round_to_nearest = std::round_to_nearest,
1147 round_toward_infinity = std::round_toward_infinity,
1148 round_toward_neg_infinity = std::round_toward_neg_infinity,
1149 };
1150
1151 enum float_denorm_style
1152 {
1153 denorm_indeterminate = std::denorm_indeterminate,
1154 denorm_absent = std::denorm_absent,
1155 denorm_present = std::denorm_present
1156 };
1157
1158#if ETL_USING_CPP11
1159 template <typename T>
1160 using numeric_limits = std::numeric_limits<T>;
1161#else
1162 template <typename T>
1163 class numeric_limits : public std::numeric_limits<T>
1164 {
1165 };
1166#endif
1167}
1168#endif
1169
1170#if defined(ETL_COMPILER_MICROSOFT)
1171 #pragma warning(pop)
1172#endif
1173
1174#include "private/minmax_pop.h"
1175
1176#endif
Definition: limits.h:1164
is_signed
Definition: type_traits_generator.h:1011
is_unsigned
Definition: type_traits_generator.h:1021
bitset_ext
Definition: absolute.h:38