Skip to content

Commit b56dd4f

Browse files
committed
float classification is now constexpr, and added __attribute__((const)) et al to non-standard prototypes like _fpclassifyf
1 parent 0d18903 commit b56dd4f

File tree

7 files changed

+145
-49
lines changed

7 files changed

+145
-49
lines changed

src/libc/include/__math_def.h

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef _MATH_DEF_H
22
#define _MATH_DEF_H
33

4+
#include <cdefs.h>
45
#include <stdbool.h>
56

67
#define NAN __builtin_nanf("")
@@ -40,30 +41,30 @@ typedef double double_t;
4041
extern "C" {
4142
#endif
4243

43-
int _fpclassifyf(float n);
44-
int _fpclassifyl(long double n);
44+
int _fpclassifyf(float) __NOEXCEPT_CONST;
45+
int _fpclassifyl(long double) __NOEXCEPT_CONST;
4546

46-
bool _isinff(float n);
47-
bool _isnanf(float n);
48-
bool _isnormalf(float n);
49-
bool _isfinitef(float n);
50-
bool _iszerof(float n);
51-
bool _issubnormalf(float n);
47+
bool _isinff(float) __NOEXCEPT_CONST;
48+
bool _isnanf(float) __NOEXCEPT_CONST;
49+
bool _isnormalf(float) __NOEXCEPT_CONST;
50+
bool _isfinitef(float) __NOEXCEPT_CONST;
51+
bool _iszerof(float) __NOEXCEPT_CONST;
52+
bool _issubnormalf(float) __NOEXCEPT_CONST;
5253

53-
int _isinfl(long double n);
54-
int _isnanl(long double n);
55-
bool _isnormall(long double n);
56-
bool _isfinitel(long double n);
57-
int _iszerol(long double n);
58-
int _issubnormall(long double n);
54+
int _isinfl(long double) __NOEXCEPT_CONST;
55+
int _isnanl(long double) __NOEXCEPT_CONST;
56+
bool _isnormall(long double) __NOEXCEPT_CONST;
57+
bool _isfinitel(long double) __NOEXCEPT_CONST;
58+
int _iszerol(long double) __NOEXCEPT_CONST;
59+
int _issubnormall(long double) __NOEXCEPT_CONST;
5960

6061
#if 0
6162
/* disabled until builtin is optimized */
6263
#define _signbitf(x) __builtin_signbit(x)
6364
#define _signbitl(x) __builtin_signbit(x)
6465
#else
65-
bool _signbitf(float x);
66-
bool _signbitl(long double x);
66+
bool _signbitf(float) __NOEXCEPT_CONST;
67+
bool _signbitl(long double) __NOEXCEPT_CONST;
6768
#endif
6869

6970
double acos(double);
@@ -327,9 +328,9 @@ long double truncl(long double);
327328

328329
/* aliases */
329330

330-
long double _debug_fabsl(long double);
331+
long double _debug_fabsl(long double) __NOEXCEPT_CONST;
331332
#define fabsl _debug_fabsl
332-
long double _debug_copysignl(long double, long double);
333+
long double _debug_copysignl(long double, long double) __NOEXCEPT_CONST;
333334
#define copysignl _debug_copysignl
334335
long double _debug_fmaxl(long double, long double);
335336
#define fmaxl _debug_fmaxl

src/libc/include/cdefs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
# define __NOEXCEPT __attribute__((__nothrow__, __leaf__))
2626
#endif /* __cplusplus */
2727

28+
#define __NOEXCEPT_CONST __NOEXCEPT __attribute__((__const__))
29+
#define __NOEXCEPT_PURE __NOEXCEPT __attribute__((__pure__))
30+
2831
#ifndef NULL
2932
# ifndef __cplusplus
3033
# define NULL ((void *)0)

src/libc/include/inttypes.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,9 @@ typedef struct {
177177

178178
__BEGIN_DECLS
179179

180-
extern intmax_t imaxabs(intmax_t __n)
181-
__NOEXCEPT __attribute__((__const__));
180+
extern intmax_t imaxabs(intmax_t __n) __NOEXCEPT_CONST;
182181

183-
extern imaxdiv_t imaxdiv(intmax_t __numer, intmax_t __denom)
184-
__NOEXCEPT __attribute__((__const__));
182+
extern imaxdiv_t imaxdiv(intmax_t __numer, intmax_t __denom) __NOEXCEPT_CONST;
185183

186184
intmax_t strtoimax(
187185
const char *__restrict nptr,

src/libc/include/stdlib.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ long labs(long n);
108108
long long llabs(long long n);
109109

110110
#ifdef __SIZEOF_INT48__
111-
signed __int48 i48abs(signed __int48 n);
111+
signed __int48 i48abs(signed __int48 n) __NOEXCEPT_CONST;
112112
#endif /* __SIZEOF_INT48__ */
113113

114114
#endif /* _ABS_INT_DEFINED */
@@ -120,7 +120,7 @@ ldiv_t ldiv(long numer, long denom);
120120
lldiv_t lldiv(long long numer, long long denom);
121121

122122
#ifdef __SIZEOF_INT48__
123-
i48div_t i48div(signed __int48 numer, signed __int48 denom);
123+
i48div_t i48div(signed __int48 numer, signed __int48 denom) __NOEXCEPT_CONST;
124124
#endif /* __SIZEOF_INT48__ */
125125

126126
__END_DECLS

src/libcxx/header_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <__config>
2+
#include <algorithm>
23
#include <bit>
34
#include <cassert>
45
#include <cctype>

src/libcxx/include/__abs_overloads

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ long labs(long n);
1818
long long llabs(long long n);
1919

2020
#ifdef __SIZEOF_INT48__
21-
signed __int48 i48abs(signed __int48 n);
21+
signed __int48 i48abs(signed __int48 n) __NOEXCEPT_CONST;
2222
#endif // __SIZEOF_INT48__
2323

2424
__END_DECLS

src/libcxx/include/cmath

Lines changed: 117 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,113 @@ namespace std {
1212
using ::float_t;
1313
using ::double_t;
1414

15-
inline bool signbit(float __x) { return static_cast<bool>(_signbitf(__x)); }
16-
inline bool signbit(double __x) { return static_cast<bool>(_signbitf(__x)); }
17-
inline bool signbit(long double __x) { return static_cast<bool>(_signbitl(__x)); }
18-
template<typename _Tp> inline
15+
inline constexpr bool signbit(float __x) {
16+
if (__builtin_constant_p(__x)) {
17+
return __builtin_signbitf(__x);
18+
}
19+
return static_cast<bool>(_signbitf(__x));
20+
}
21+
inline constexpr bool signbit(double __x) {
22+
if (__builtin_constant_p(__x)) {
23+
return __builtin_signbit(__x);
24+
}
25+
return static_cast<bool>(_signbitf(__x));
26+
}
27+
inline constexpr bool signbit(long double __x) {
28+
if (__builtin_constant_p(__x)) {
29+
return __builtin_signbitl(__x);
30+
}
31+
return static_cast<bool>(_signbitl(__x));
32+
}
33+
template<typename _Tp> inline constexpr
1934
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
2035
signbit(_Tp __x) { return signbit(__x); }
2136

22-
inline bool isinf(float __x) { return static_cast<bool>(_isinff(__x)); }
23-
inline bool isinf(double __x) { return static_cast<bool>(_isinff(__x)); }
24-
inline bool isinf(long double __x) { return static_cast<bool>(_isinfl(__x)); }
25-
template<typename _Tp> inline
37+
inline constexpr bool isinf(float __x) {
38+
if (__builtin_constant_p(__x)) {
39+
return __builtin_isinf(__x);
40+
}
41+
return static_cast<bool>(_isinff(__x));
42+
}
43+
inline constexpr bool isinf(double __x) {
44+
if (__builtin_constant_p(__x)) {
45+
return __builtin_isinf(__x);
46+
}
47+
return static_cast<bool>(_isinff(__x));
48+
}
49+
inline constexpr bool isinf(long double __x) {
50+
if (__builtin_constant_p(__x)) {
51+
return __builtin_isinf(__x);
52+
}
53+
return static_cast<bool>(_isinfl(__x));
54+
}
55+
template<typename _Tp> inline constexpr
2656
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
2757
isinf(_Tp __x) { return isinf(__x); }
2858

29-
inline bool isnan(float __x) { return static_cast<bool>(_isnanf(__x)); }
30-
inline bool isnan(double __x) { return static_cast<bool>(_isnanf(__x)); }
31-
inline bool isnan(long double __x) { return static_cast<bool>(_isnanl(__x)); }
32-
template<typename _Tp> inline
59+
inline constexpr bool isnan(float __x) {
60+
if (__builtin_constant_p(__x)) {
61+
return __builtin_isnan(__x);
62+
}
63+
return static_cast<bool>(_isnanf(__x));
64+
}
65+
inline constexpr bool isnan(double __x) {
66+
if (__builtin_constant_p(__x)) {
67+
return __builtin_isnan(__x);
68+
}
69+
return static_cast<bool>(_isnanf(__x));
70+
}
71+
inline constexpr bool isnan(long double __x) {
72+
if (__builtin_constant_p(__x)) {
73+
return __builtin_isnan(__x);
74+
}
75+
return static_cast<bool>(_isnanl(__x));
76+
}
77+
template<typename _Tp> inline constexpr
3378
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
3479
isnan(_Tp __x) { return isnan(__x); }
3580

36-
inline bool isnormal(float __x) { return static_cast<bool>(_isnormalf(__x)); }
37-
inline bool isnormal(double __x) { return static_cast<bool>(_isnormalf(__x)); }
38-
inline bool isnormal(long double __x) { return static_cast<bool>(_isnormall(__x)); }
39-
template<typename _Tp> inline
81+
inline constexpr bool isnormal(float __x) {
82+
if (__builtin_constant_p(__x)) {
83+
return __builtin_isnormal(__x);
84+
}
85+
return static_cast<bool>(_isnormalf(__x));
86+
}
87+
inline constexpr bool isnormal(double __x) {
88+
if (__builtin_constant_p(__x)) {
89+
return __builtin_isnormal(__x);
90+
}
91+
return static_cast<bool>(_isnormalf(__x));
92+
}
93+
inline constexpr bool isnormal(long double __x) {
94+
if (__builtin_constant_p(__x)) {
95+
return __builtin_isnormal(__x);
96+
}
97+
return static_cast<bool>(_isnormall(__x));
98+
}
99+
template<typename _Tp> inline constexpr
40100
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
41101
isnormal(_Tp __x) { return isnormal(__x); }
42102

43-
inline bool isfinite(float __x) { return static_cast<bool>(_isfinitef(__x)); }
44-
inline bool isfinite(double __x) { return static_cast<bool>(_isfinitef(__x)); }
45-
inline bool isfinite(long double __x) { return static_cast<bool>(_isfinitel(__x)); }
46-
template<typename _Tp> inline
103+
inline constexpr bool isfinite(float __x) {
104+
if (__builtin_constant_p(__x)) {
105+
return __builtin_isfinite(__x);
106+
}
107+
return static_cast<bool>(_isfinitef(__x));
108+
}
109+
inline constexpr bool isfinite(double __x) {
110+
if (__builtin_constant_p(__x)) {
111+
return __builtin_isfinite(__x);
112+
}
113+
return static_cast<bool>(_isfinitef(__x));
114+
}
115+
inline constexpr bool isfinite(long double __x) {
116+
if (__builtin_constant_p(__x)) {
117+
return __builtin_isfinite(__x);
118+
}
119+
return static_cast<bool>(_isfinitel(__x));
120+
}
121+
template<typename _Tp> inline constexpr
47122
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
48123
isfinite(_Tp __x) { return isfinite(__x); }
49124

@@ -61,10 +136,28 @@ template<typename _Tp> inline
61136
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
62137
issubnormal(_Tp __x) { return issubnormal(__x); }
63138

64-
inline int fpclassify(float __x) { return _fpclassifyf(__x); }
65-
inline int fpclassify(double __x) { return _fpclassifyf(__x); }
66-
inline int fpclassify(long double __x) { return _fpclassifyl(__x); }
67-
template<typename _Tp> inline
139+
inline constexpr int fpclassify(float __x) {
140+
if (__builtin_constant_p(__x)) {
141+
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
142+
} else {
143+
return _fpclassifyf(__x);
144+
}
145+
}
146+
inline constexpr int fpclassify(double __x) {
147+
if (__builtin_constant_p(__x)) {
148+
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
149+
} else {
150+
return _fpclassifyf(__x);
151+
}
152+
}
153+
inline constexpr int fpclassify(long double __x) {
154+
if (__builtin_constant_p(__x)) {
155+
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
156+
} else {
157+
return _fpclassifyl(__x);
158+
}
159+
}
160+
template<typename _Tp> inline constexpr
68161
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, int>
69162
fpclassify(_Tp __x) { return fpclassify(__x); }
70163

0 commit comments

Comments
 (0)