2222#endif // no system header
2323
2424#include <cuda/std/__bit/bit_cast.h>
25- #include <cuda/std/__type_traits/is_arithmetic.h>
25+ #include <cuda/std/__type_traits/integral_constant.h>
26+ #include <cuda/std/__type_traits/is_extended_floating_point.h>
27+ #include <cuda/std/__type_traits/is_floating_point.h>
28+ #include <cuda/std/__type_traits/is_integral.h>
2629#include <cuda/std/climits>
2730#include <cuda/std/version>
2831
@@ -46,7 +49,47 @@ enum float_denorm_style
4649 denorm_present = 1
4750};
4851
49- template <class _Tp, bool = is_arithmetic<_Tp>::value>
52+ enum class __numeric_limits_type
53+ {
54+ __integral,
55+ __bool,
56+ __floating_point,
57+ __other,
58+ };
59+
60+ template <class _Tp>
61+ _LIBCUDACXX_HIDE_FROM_ABI constexpr __numeric_limits_type __make_numeric_limits_type()
62+ {
63+ #if !defined(_CCCL_NO_IF_CONSTEXPR)
64+ _CCCL_IF_CONSTEXPR (_CCCL_TRAIT(is_same, _Tp, bool))
65+ {
66+ return __numeric_limits_type::__bool;
67+ }
68+ else _CCCL_IF_CONSTEXPR (_CCCL_TRAIT(is_integral, _Tp))
69+ {
70+ return __numeric_limits_type::__integral;
71+ }
72+ else _CCCL_IF_CONSTEXPR (_CCCL_TRAIT(is_floating_point, _Tp) || _CCCL_TRAIT(__is_extended_floating_point, _Tp))
73+ {
74+ return __numeric_limits_type::__floating_point;
75+ }
76+ else
77+ {
78+ return __numeric_limits_type::__other;
79+ }
80+ _CCCL_UNREACHABLE();
81+ #else // ^^^ !_CCCL_NO_IF_CONSTEXPR ^^^ // vvv _CCCL_NO_IF_CONSTEXPR vvv
82+ return _CCCL_TRAIT(is_same, _Tp, bool)
83+ ? __numeric_limits_type::__bool
84+ : (_CCCL_TRAIT(is_integral, _Tp)
85+ ? __numeric_limits_type::__integral
86+ : (_CCCL_TRAIT(is_floating_point, _Tp) || _CCCL_TRAIT(__is_extended_floating_point, _Tp)
87+ ? __numeric_limits_type::__floating_point
88+ : __numeric_limits_type::__other));
89+ #endif // _CCCL_NO_IF_CONSTEXPR
90+ }
91+
92+ template <class _Tp, __numeric_limits_type = __make_numeric_limits_type<_Tp>()>
5093class __numeric_limits_impl
5194{
5295public:
@@ -135,7 +178,7 @@ struct __int_min<_Tp, __digits, false>
135178};
136179
137180template <class _Tp>
138- class __numeric_limits_impl<_Tp, true >
181+ class __numeric_limits_impl<_Tp, __numeric_limits_type::__integral >
139182{
140183public:
141184 using type = _Tp;
@@ -212,7 +255,7 @@ public:
212255};
213256
214257template <>
215- class __numeric_limits_impl<bool, true >
258+ class __numeric_limits_impl<bool, __numeric_limits_type::__bool >
216259{
217260public:
218261 using type = bool;
@@ -286,7 +329,7 @@ public:
286329};
287330
288331template <>
289- class __numeric_limits_impl<float, true >
332+ class __numeric_limits_impl<float, __numeric_limits_type::__floating_point >
290333{
291334public:
292335 using type = float;
@@ -381,7 +424,7 @@ public:
381424};
382425
383426template <>
384- class __numeric_limits_impl<double, true >
427+ class __numeric_limits_impl<double, __numeric_limits_type::__floating_point >
385428{
386429public:
387430 using type = double;
@@ -476,7 +519,7 @@ public:
476519};
477520
478521template <>
479- class __numeric_limits_impl<long double, true >
522+ class __numeric_limits_impl<long double, __numeric_limits_type::__floating_point >
480523{
481524#ifndef _LIBCUDACXX_HAS_NO_LONG_DOUBLE
482525
@@ -551,6 +594,156 @@ public:
551594#endif // !_LIBCUDACXX_HAS_NO_LONG_DOUBLE
552595};
553596
597+ #if defined(_LIBCUDACXX_HAS_NVFP16)
598+ template <>
599+ class __numeric_limits_impl<__half, __numeric_limits_type::__floating_point>
600+ {
601+ public:
602+ using type = __half;
603+
604+ static constexpr bool is_specialized = true;
605+
606+ static constexpr bool is_signed = true;
607+ static constexpr int digits = 11;
608+ static constexpr int digits10 = 3;
609+ static constexpr int max_digits10 = 5;
610+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type min() noexcept
611+ {
612+ return type(__half_raw{0x0400u});
613+ }
614+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type max() noexcept
615+ {
616+ return type(__half_raw{0x7bffu});
617+ }
618+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type lowest() noexcept
619+ {
620+ return type(__half_raw{0xfbffu});
621+ }
622+
623+ static constexpr bool is_integer = false;
624+ static constexpr bool is_exact = false;
625+ static constexpr int radix = __FLT_RADIX__;
626+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type epsilon() noexcept
627+ {
628+ return type(__half_raw{0x1400u});
629+ }
630+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type round_error() noexcept
631+ {
632+ return type(__half_raw{0x3800u});
633+ }
634+
635+ static constexpr int min_exponent = -13;
636+ static constexpr int min_exponent10 = -4;
637+ static constexpr int max_exponent = 16;
638+ static constexpr int max_exponent10 = 4;
639+
640+ static constexpr bool has_infinity = true;
641+ static constexpr bool has_quiet_NaN = true;
642+ static constexpr bool has_signaling_NaN = true;
643+ static constexpr float_denorm_style has_denorm = denorm_present;
644+ static constexpr bool has_denorm_loss = false;
645+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type infinity() noexcept
646+ {
647+ return type(__half_raw{0x7c00u});
648+ }
649+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type quiet_NaN() noexcept
650+ {
651+ return type(__half_raw{0x7e00u});
652+ }
653+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type signaling_NaN() noexcept
654+ {
655+ return type(__half_raw{0x7d00u});
656+ }
657+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type denorm_min() noexcept
658+ {
659+ return type(__half_raw{0x0001u});
660+ }
661+
662+ static constexpr bool is_iec559 = true;
663+ static constexpr bool is_bounded = true;
664+ static constexpr bool is_modulo = false;
665+
666+ static constexpr bool traps = false;
667+ static constexpr bool tinyness_before = false;
668+ static constexpr float_round_style round_style = round_to_nearest;
669+ };
670+ #endif // _LIBCUDACXX_HAS_NVFP16
671+
672+ #if defined(_LIBCUDACXX_HAS_NVBF16)
673+ template <>
674+ class __numeric_limits_impl<__nv_bfloat16, __numeric_limits_type::__floating_point>
675+ {
676+ public:
677+ using type = __nv_bfloat16;
678+
679+ static constexpr bool is_specialized = true;
680+
681+ static constexpr bool is_signed = true;
682+ static constexpr int digits = 8;
683+ static constexpr int digits10 = 2;
684+ static constexpr int max_digits10 = 4;
685+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type min() noexcept
686+ {
687+ return type(__nv_bfloat16_raw{0x0080u});
688+ }
689+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type max() noexcept
690+ {
691+ return type(__nv_bfloat16_raw{0x7f7fu});
692+ }
693+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type lowest() noexcept
694+ {
695+ return type(__nv_bfloat16_raw{0xff7fu});
696+ }
697+
698+ static constexpr bool is_integer = false;
699+ static constexpr bool is_exact = false;
700+ static constexpr int radix = __FLT_RADIX__;
701+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type epsilon() noexcept
702+ {
703+ return type(__nv_bfloat16_raw{0x3c00u});
704+ }
705+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type round_error() noexcept
706+ {
707+ return type(__nv_bfloat16_raw{0x3f00u});
708+ }
709+
710+ static constexpr int min_exponent = -125;
711+ static constexpr int min_exponent10 = -37;
712+ static constexpr int max_exponent = 128;
713+ static constexpr int max_exponent10 = 38;
714+
715+ static constexpr bool has_infinity = true;
716+ static constexpr bool has_quiet_NaN = true;
717+ static constexpr bool has_signaling_NaN = true;
718+ static constexpr float_denorm_style has_denorm = denorm_present;
719+ static constexpr bool has_denorm_loss = false;
720+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type infinity() noexcept
721+ {
722+ return type(__nv_bfloat16_raw{0x7f80u});
723+ }
724+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type quiet_NaN() noexcept
725+ {
726+ return type(__nv_bfloat16_raw{0x7fc0u});
727+ }
728+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type signaling_NaN() noexcept
729+ {
730+ return type(__nv_bfloat16_raw{0x7fa0u});
731+ }
732+ _LIBCUDACXX_HIDE_FROM_ABI static constexpr type denorm_min() noexcept
733+ {
734+ return type(__nv_bfloat16_raw{0x0001u});
735+ }
736+
737+ static constexpr bool is_iec559 = true;
738+ static constexpr bool is_bounded = true;
739+ static constexpr bool is_modulo = false;
740+
741+ static constexpr bool traps = false;
742+ static constexpr bool tinyness_before = false;
743+ static constexpr float_round_style round_style = round_to_nearest;
744+ };
745+ #endif // _LIBCUDACXX_HAS_NVBF16
746+
554747template <class _Tp>
555748class numeric_limits : public __numeric_limits_impl<_Tp>
556749{};
0 commit comments