File tree 2 files changed +28
-3
lines changed 2 files changed +28
-3
lines changed Original file line number Diff line number Diff line change 12
12
#include < __config>
13
13
#include < __type_traits/enable_if.h>
14
14
#include < __type_traits/is_arithmetic.h>
15
- #include < __type_traits/is_floating_point.h>
16
15
#include < __type_traits/is_integral.h>
17
16
#include < __type_traits/is_signed.h>
18
17
#include < __type_traits/promote.h>
@@ -34,8 +33,21 @@ namespace __math {
34
33
# define _LIBCPP_SIGNBIT_CONSTEXPR
35
34
#endif
36
35
37
- template <class _A1 , __enable_if_t <is_floating_point<_A1>::value, int > = 0 >
38
- _LIBCPP_NODISCARD inline _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_HIDE_FROM_ABI bool signbit (_A1 __x) _NOEXCEPT {
36
+ // The universal C runtime (UCRT) in the WinSDK provides floating point overloads
37
+ // for std::signbit(). By defining our overloads as templates, we can work around
38
+ // this issue as templates are less preferred than non-template functions.
39
+ template <class = void >
40
+ _LIBCPP_NODISCARD inline _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_HIDE_FROM_ABI bool signbit (float __x) _NOEXCEPT {
41
+ return __builtin_signbit (__x);
42
+ }
43
+
44
+ template <class = void >
45
+ _LIBCPP_NODISCARD inline _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_HIDE_FROM_ABI bool signbit (double __x) _NOEXCEPT {
46
+ return __builtin_signbit (__x);
47
+ }
48
+
49
+ template <class = void >
50
+ _LIBCPP_NODISCARD inline _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_HIDE_FROM_ABI bool signbit (long double __x) _NOEXCEPT {
39
51
return __builtin_signbit (__x);
40
52
}
41
53
Original file line number Diff line number Diff line change @@ -70,9 +70,22 @@ struct TestInt {
70
70
}
71
71
};
72
72
73
+ template <typename T>
74
+ struct ConvertibleTo {
75
+ operator T () const { return T (); }
76
+ };
77
+
73
78
int main (int , char **) {
74
79
types::for_each (types::floating_point_types (), TestFloat ());
75
80
types::for_each (types::integral_types (), TestInt ());
76
81
82
+ // Make sure we can call `std::signbit` with convertible types. This checks
83
+ // whether overloads for all cv-unqualified floating-point types are working
84
+ // as expected.
85
+ {
86
+ assert (!std::signbit (ConvertibleTo<float >()));
87
+ assert (!std::signbit (ConvertibleTo<double >()));
88
+ assert (!std::signbit (ConvertibleTo<long double >()));
89
+ }
77
90
return 0 ;
78
91
}
You can’t perform that action at this time.
0 commit comments