bigdecimal 3.0.2 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,62 +10,74 @@
10
10
  #define RUBY_BIG_DECIMAL_H 1
11
11
 
12
12
  #define RUBY_NO_OLD_COMPATIBILITY
13
-
14
13
  #include "ruby/ruby.h"
15
- #include <float.h>
14
+ #include "missing.h"
16
15
 
17
- #ifndef RB_UNUSED_VAR
18
- # ifdef __GNUC__
19
- # define RB_UNUSED_VAR(x) x __attribute__ ((unused))
20
- # else
21
- # define RB_UNUSED_VAR(x) x
22
- # endif
16
+ #ifdef HAVE_FLOAT_H
17
+ # include <float.h>
23
18
  #endif
24
19
 
25
- #ifndef UNREACHABLE
26
- # define UNREACHABLE /* unreachable */
27
- #endif
28
-
29
- #undef BDIGIT
30
- #undef SIZEOF_BDIGITS
31
- #undef BDIGIT_DBL
32
- #undef BDIGIT_DBL_SIGNED
33
- #undef PRI_BDIGIT_PREFIX
34
- #undef PRI_BDIGIT_DBL_PREFIX
35
-
36
20
  #ifdef HAVE_INT64_T
37
- # define BDIGIT uint32_t
38
- # define BDIGIT_DBL uint64_t
39
- # define BDIGIT_DBL_SIGNED int64_t
40
- # define SIZEOF_BDIGITS 4
41
- # define PRI_BDIGIT_PREFIX ""
21
+ # define DECDIG uint32_t
22
+ # define DECDIG_DBL uint64_t
23
+ # define DECDIG_DBL_SIGNED int64_t
24
+ # define SIZEOF_DECDIG 4
25
+ # define PRI_DECDIG_PREFIX ""
42
26
  # ifdef PRI_LL_PREFIX
43
- # define PRI_BDIGIT_DBL_PREFIX PRI_LL_PREFIX
27
+ # define PRI_DECDIG_DBL_PREFIX PRI_LL_PREFIX
44
28
  # else
45
- # define PRI_BDIGIT_DBL_PREFIX "l"
29
+ # define PRI_DECDIG_DBL_PREFIX "l"
46
30
  # endif
47
31
  #else
48
- # define BDIGIT uint16_t
49
- # define BDIGIT_DBL uint32_t
50
- # define BDIGIT_DBL_SIGNED int32_t
51
- # define SIZEOF_BDIGITS 2
52
- # define PRI_BDIGIT_PREFIX "h"
53
- # define PRI_BDIGIT_DBL_PREFIX ""
32
+ # define DECDIG uint16_t
33
+ # define DECDIG_DBL uint32_t
34
+ # define DECDIG_DBL_SIGNED int32_t
35
+ # define SIZEOF_DECDIG 2
36
+ # define PRI_DECDIG_PREFIX "h"
37
+ # define PRI_DECDIG_DBL_PREFIX ""
54
38
  #endif
55
39
 
56
- #define PRIdBDIGIT PRI_BDIGIT_PREFIX"d"
57
- #define PRIiBDIGIT PRI_BDIGIT_PREFIX"i"
58
- #define PRIoBDIGIT PRI_BDIGIT_PREFIX"o"
59
- #define PRIuBDIGIT PRI_BDIGIT_PREFIX"u"
60
- #define PRIxBDIGIT PRI_BDIGIT_PREFIX"x"
61
- #define PRIXBDIGIT PRI_BDIGIT_PREFIX"X"
40
+ #define PRIdDECDIG PRI_DECDIG_PREFIX"d"
41
+ #define PRIiDECDIG PRI_DECDIG_PREFIX"i"
42
+ #define PRIoDECDIG PRI_DECDIG_PREFIX"o"
43
+ #define PRIuDECDIG PRI_DECDIG_PREFIX"u"
44
+ #define PRIxDECDIG PRI_DECDIG_PREFIX"x"
45
+ #define PRIXDECDIG PRI_DECDIG_PREFIX"X"
46
+
47
+ #define PRIdDECDIG_DBL PRI_DECDIG_DBL_PREFIX"d"
48
+ #define PRIiDECDIG_DBL PRI_DECDIG_DBL_PREFIX"i"
49
+ #define PRIoDECDIG_DBL PRI_DECDIG_DBL_PREFIX"o"
50
+ #define PRIuDECDIG_DBL PRI_DECDIG_DBL_PREFIX"u"
51
+ #define PRIxDECDIG_DBL PRI_DECDIG_DBL_PREFIX"x"
52
+ #define PRIXDECDIG_DBL PRI_DECDIG_DBL_PREFIX"X"
53
+
54
+ #if SIZEOF_DECDIG == 4
55
+ # define BIGDECIMAL_BASE ((DECDIG)1000000000U)
56
+ # define BIGDECIMAL_COMPONENT_FIGURES 9
57
+ /*
58
+ * The number of components required for a 64-bit integer.
59
+ *
60
+ * INT64_MAX: 9_223372036_854775807
61
+ * UINT64_MAX: 18_446744073_709551615
62
+ */
63
+ # define BIGDECIMAL_INT64_MAX_LENGTH 3
62
64
 
63
- #define PRIdBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"d"
64
- #define PRIiBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"i"
65
- #define PRIoBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"o"
66
- #define PRIuBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"u"
67
- #define PRIxBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"x"
68
- #define PRIXBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"X"
65
+ #elif SIZEOF_DECDIG == 2
66
+ # define BIGDECIMAL_BASE ((DECDIG)10000U)
67
+ # define BIGDECIMAL_COMPONENT_FIGURES 4
68
+ /*
69
+ * The number of components required for a 64-bit integer.
70
+ *
71
+ * INT64_MAX: 922_3372_0368_5477_5807
72
+ * UINT64_MAX: 1844_6744_0737_0955_1615
73
+ */
74
+ # define BIGDECIMAL_INT64_MAX_LENGTH 5
75
+
76
+ #else
77
+ # error Unknown size of DECDIG
78
+ #endif
79
+
80
+ #define BIGDECIMAL_DOUBLE_FIGURES (1+DBL_DIG)
69
81
 
70
82
  #if defined(__cplusplus)
71
83
  extern "C" {
@@ -74,115 +86,8 @@ extern "C" {
74
86
  #endif
75
87
  #endif
76
88
 
77
- #ifndef HAVE_LABS
78
- static inline long
79
- labs(long const x)
80
- {
81
- if (x < 0) return -x;
82
- return x;
83
- }
84
- #endif
85
-
86
- #ifndef HAVE_LLABS
87
- static inline LONG_LONG
88
- llabs(LONG_LONG const x)
89
- {
90
- if (x < 0) return -x;
91
- return x;
92
- }
93
- #endif
94
-
95
- #ifndef HAVE_FINITE
96
- static int
97
- finite(double)
98
- {
99
- return !isnan(n) && !isinf(n);
100
- }
101
- #endif
102
-
103
- #ifndef isfinite
104
- # ifndef HAVE_ISFINITE
105
- # define HAVE_ISFINITE 1
106
- # define isfinite(x) finite(x)
107
- # endif
108
- #endif
109
-
110
- #ifndef FIX_CONST_VALUE_PTR
111
- # if defined(__fcc__) || defined(__fcc_version) || \
112
- defined(__FCC__) || defined(__FCC_VERSION)
113
- /* workaround for old version of Fujitsu C Compiler (fcc) */
114
- # define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
115
- # else
116
- # define FIX_CONST_VALUE_PTR(x) (x)
117
- # endif
118
- #endif
119
-
120
- #ifndef HAVE_RB_ARRAY_CONST_PTR
121
- static inline const VALUE *
122
- rb_array_const_ptr(VALUE a)
123
- {
124
- return FIX_CONST_VALUE_PTR((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ?
125
- RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr);
126
- }
127
- #endif
128
-
129
- #ifndef RARRAY_CONST_PTR
130
- # define RARRAY_CONST_PTR(a) rb_array_const_ptr(a)
131
- #endif
132
-
133
- #ifndef RARRAY_AREF
134
- # define RARRAY_AREF(a, i) (RARRAY_CONST_PTR(a)[i])
135
- #endif
136
-
137
- #ifndef HAVE_RB_SYM2STR
138
- static inline VALUE
139
- rb_sym2str(VALUE sym)
140
- {
141
- return rb_id2str(SYM2ID(sym));
142
- }
143
- #endif
144
-
145
- #ifndef ST2FIX
146
- # undef RB_ST2FIX
147
- # define RB_ST2FIX(h) LONG2FIX((long)(h))
148
- # define ST2FIX(h) RB_ST2FIX(h)
149
- #endif
150
-
151
- #ifdef vabs
152
- # undef vabs
153
- #endif
154
- #if SIZEOF_VALUE <= SIZEOF_INT
155
- # define vabs abs
156
- #elif SIZEOF_VALUE <= SIZEOF_LONG
157
- # define vabs labs
158
- #elif SIZEOF_VALUE <= SIZEOF_LONG_LONG
159
- # define vabs llabs
160
- #endif
161
-
162
- #if !defined(HAVE_RB_CATEGORY_WARN) || !defined(HAVE_CONST_RB_WARN_CATEGORY_DEPRECATED)
163
- # define rb_category_warn(category, ...) rb_warn(__VA_ARGS__)
164
- #endif
165
-
166
89
  extern VALUE rb_cBigDecimal;
167
90
 
168
- #if 0 || SIZEOF_BDIGITS >= 16
169
- # define RMPD_COMPONENT_FIGURES 38
170
- # define RMPD_BASE ((BDIGIT)100000000000000000000000000000000000000U)
171
- #elif SIZEOF_BDIGITS >= 8
172
- # define RMPD_COMPONENT_FIGURES 19
173
- # define RMPD_BASE ((BDIGIT)10000000000000000000U)
174
- #elif SIZEOF_BDIGITS >= 4
175
- # define RMPD_COMPONENT_FIGURES 9
176
- # define RMPD_BASE ((BDIGIT)1000000000U)
177
- #elif SIZEOF_BDIGITS >= 2
178
- # define RMPD_COMPONENT_FIGURES 4
179
- # define RMPD_BASE ((BDIGIT)10000U)
180
- #else
181
- # define RMPD_COMPONENT_FIGURES 2
182
- # define RMPD_BASE ((BDIGIT)100U)
183
- #endif
184
-
185
-
186
91
  /*
187
92
  * NaN & Infinity
188
93
  */
@@ -207,9 +112,8 @@ extern VALUE rb_cBigDecimal;
207
112
 
208
113
  /* Following 2 exceptions can't controlled by user */
209
114
  #define VP_EXCEPTION_OP ((unsigned short)0x0020)
210
- #define VP_EXCEPTION_MEMORY ((unsigned short)0x0040)
211
115
 
212
- #define RMPD_EXCEPTION_MODE_DEFAULT 0U
116
+ #define BIGDECIMAL_EXCEPTION_MODE_DEFAULT 0U
213
117
 
214
118
  /* Computation mode */
215
119
  #define VP_ROUND_MODE ((unsigned short)0x0100)
@@ -221,7 +125,7 @@ extern VALUE rb_cBigDecimal;
221
125
  #define VP_ROUND_FLOOR 6
222
126
  #define VP_ROUND_HALF_EVEN 7
223
127
 
224
- #define RMPD_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP
128
+ #define BIGDECIMAL_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP
225
129
 
226
130
  #define VP_SIGN_NaN 0 /* NaN */
227
131
  #define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */
@@ -263,7 +167,7 @@ typedef struct {
263
167
  * -3 : Negative infinite number
264
168
  */
265
169
  short flag; /* Not used in vp_routines,space for user. */
266
- BDIGIT frac[FLEXIBLE_ARRAY_SIZE]; /* Array of fraction part. */
170
+ DECDIG frac[FLEXIBLE_ARRAY_SIZE]; /* Array of fraction part. */
267
171
  } Real;
268
172
 
269
173
  /*
@@ -272,21 +176,13 @@ typedef struct {
272
176
  * ------------------
273
177
  */
274
178
 
275
- VP_EXPORT Real *
276
- VpNewRbClass(size_t mx, char const *str, VALUE klass);
277
-
278
- VP_EXPORT Real *VpCreateRbObject(size_t mx,const char *str);
179
+ VP_EXPORT Real *VpNewRbClass(size_t mx, char const *str, VALUE klass, bool strict_p, bool raise_exception);
279
180
 
280
- static inline BDIGIT
281
- rmpd_base_value(void) { return RMPD_BASE; }
282
- static inline size_t
283
- rmpd_component_figures(void) { return RMPD_COMPONENT_FIGURES; }
284
- static inline size_t
285
- rmpd_double_figures(void) { return 1+DBL_DIG; }
181
+ VP_EXPORT Real *VpCreateRbObject(size_t mx, const char *str, bool raise_exception);
286
182
 
287
- #define VpBaseFig() rmpd_component_figures()
288
- #define VpDblFig() rmpd_double_figures()
289
- #define VpBaseVal() rmpd_base_value()
183
+ #define VpBaseFig() BIGDECIMAL_COMPONENT_FIGURES
184
+ #define VpDblFig() BIGDECIMAL_DOUBLE_FIGURES
185
+ #define VpBaseVal() BIGDECIMAL_BASE
290
186
 
291
187
  /* Zero,Inf,NaN (isinf(),isnan() used to check) */
292
188
  VP_EXPORT double VpGetDoubleNaN(void);
@@ -308,7 +204,7 @@ VP_EXPORT int VpException(unsigned short f,const char *str,int always);
308
204
  VP_EXPORT int VpIsNegDoubleZero(double v);
309
205
  #endif
310
206
  VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt);
311
- VP_EXPORT size_t VpInit(BDIGIT BaseVal);
207
+ VP_EXPORT size_t VpInit(DECDIG BaseVal);
312
208
  VP_EXPORT void *VpMemAlloc(size_t mb);
313
209
  VP_EXPORT void *VpMemRealloc(void *ptr, size_t mb);
314
210
  VP_EXPORT void VpFree(Real *pv);
@@ -334,7 +230,8 @@ VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il);
334
230
  VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf);
335
231
  VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf);
336
232
  VP_EXPORT void VpFrac(Real *y, Real *x);
337
- VP_EXPORT int VpPower(Real *y, Real *x, SIGNED_VALUE n);
233
+ VP_EXPORT int VpPowerByInt(Real *y, Real *x, SIGNED_VALUE n);
234
+ #define VpPower VpPowerByInt
338
235
 
339
236
  /* VP constants */
340
237
  VP_EXPORT Real *VpOne(void);
@@ -0,0 +1,141 @@
1
+ #ifndef BIGDECIMAL_BITS_H
2
+ #define BIGDECIMAL_BITS_H
3
+
4
+ #include "feature.h"
5
+ #include "static_assert.h"
6
+
7
+ #if defined(__x86_64__) && defined(HAVE_X86INTRIN_H)
8
+ # include <x86intrin.h> /* for _lzcnt_u64, etc. */
9
+ #elif defined(_MSC_VER) && defined(HAVE_INTRIN_H)
10
+ # include <intrin.h> /* for the following intrinsics */
11
+ #endif
12
+
13
+ #if defined(_MSC_VER) && defined(__AVX2__)
14
+ # pragma intrinsic(__lzcnt)
15
+ # pragma intrinsic(__lzcnt64)
16
+ #endif
17
+
18
+ #define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
19
+ #define roomof(x, y) (((x) + (y) - 1) / (y))
20
+ #define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
21
+
22
+ #define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
23
+ (a) == 0 ? 0 : \
24
+ (a) == -1 ? (b) < -(max) : \
25
+ (a) > 0 ? \
26
+ ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
27
+ ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
28
+
29
+ #ifdef HAVE_UINT128_T
30
+ # define bit_length(x) \
31
+ (unsigned int) \
32
+ (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
33
+ sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \
34
+ 128 - nlz_int128((uint128_t)(x)))
35
+ #else
36
+ # define bit_length(x) \
37
+ (unsigned int) \
38
+ (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
39
+ 64 - nlz_int64((uint64_t)(x)))
40
+ #endif
41
+
42
+ static inline unsigned nlz_int32(uint32_t x);
43
+ static inline unsigned nlz_int64(uint64_t x);
44
+ #ifdef HAVE_UINT128_T
45
+ static inline unsigned nlz_int128(uint128_t x);
46
+ #endif
47
+
48
+ static inline unsigned int
49
+ nlz_int32(uint32_t x)
50
+ {
51
+ #if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT)
52
+ /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC.
53
+ * AMD CPUs have had this instruction for decades (since K10) but for
54
+ * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum
55
+ * safety. */
56
+ return (unsigned int)__lzcnt(x);
57
+
58
+ #elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U32)
59
+ return (unsigned int)_lzcnt_u32(x);
60
+
61
+ #elif defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE)
62
+ unsigned long r;
63
+ return _BitScanReverse(&r, x) ? (31 - (int)r) : 32;
64
+
65
+ #elif __has_builtin(__builtin_clz)
66
+ STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32);
67
+ return x ? (unsigned int)__builtin_clz(x) : 32;
68
+
69
+ #else
70
+ uint32_t y;
71
+ unsigned n = 32;
72
+ y = x >> 16; if (y) {n -= 16; x = y;}
73
+ y = x >> 8; if (y) {n -= 8; x = y;}
74
+ y = x >> 4; if (y) {n -= 4; x = y;}
75
+ y = x >> 2; if (y) {n -= 2; x = y;}
76
+ y = x >> 1; if (y) {return n - 2;}
77
+ return (unsigned int)(n - x);
78
+ #endif
79
+ }
80
+
81
+ static inline unsigned int
82
+ nlz_int64(uint64_t x)
83
+ {
84
+ #if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64)
85
+ return (unsigned int)__lzcnt64(x);
86
+
87
+ #elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64)
88
+ return (unsigned int)_lzcnt_u64(x);
89
+
90
+ #elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64)
91
+ unsigned long r;
92
+ return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64;
93
+
94
+ #elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc))
95
+ if (x == 0) {
96
+ return 64;
97
+ }
98
+ else if (sizeof(long) * CHAR_BIT == 64) {
99
+ return (unsigned int)__builtin_clzl((unsigned long)x);
100
+ }
101
+ else if (sizeof(long long) * CHAR_BIT == 64) {
102
+ return (unsigned int)__builtin_clzll((unsigned long long)x);
103
+ }
104
+ else {
105
+ /* :FIXME: Is there a way to make this branch a compile-time error? */
106
+ __builtin_unreachable();
107
+ }
108
+
109
+ #else
110
+ uint64_t y;
111
+ unsigned int n = 64;
112
+ y = x >> 32; if (y) {n -= 32; x = y;}
113
+ y = x >> 16; if (y) {n -= 16; x = y;}
114
+ y = x >> 8; if (y) {n -= 8; x = y;}
115
+ y = x >> 4; if (y) {n -= 4; x = y;}
116
+ y = x >> 2; if (y) {n -= 2; x = y;}
117
+ y = x >> 1; if (y) {return n - 2;}
118
+ return (unsigned int)(n - x);
119
+
120
+ #endif
121
+ }
122
+
123
+ #ifdef HAVE_UINT128_T
124
+ static inline unsigned int
125
+ nlz_int128(uint128_t x)
126
+ {
127
+ uint64_t y = (uint64_t)(x >> 64);
128
+
129
+ if (x == 0) {
130
+ return 128;
131
+ }
132
+ else if (y == 0) {
133
+ return (unsigned int)nlz_int64(x) + 64;
134
+ }
135
+ else {
136
+ return (unsigned int)nlz_int64(y);
137
+ }
138
+ }
139
+ #endif
140
+
141
+ #endif /* BIGDECIMAL_BITS_H */
@@ -3,10 +3,7 @@ require 'mkmf'
3
3
 
4
4
  def check_bigdecimal_version(gemspec_path)
5
5
  message "checking RUBY_BIGDECIMAL_VERSION... "
6
-
7
- bigdecimal_version =
8
- IO.readlines(gemspec_path)
9
- .grep(/\Abigdecimal_version\s+=\s+/)[0][/\'([^\']+)\'/, 1]
6
+ bigdecimal_version = File.read(gemspec_path).match(/^\s*s\.version\s+=\s+['"]([^'"]+)['"]\s*$/)[1]
10
7
 
11
8
  version_components = bigdecimal_version.split('.')
12
9
  bigdecimal_version = version_components[0, 3].join('.')
@@ -16,6 +13,20 @@ def check_bigdecimal_version(gemspec_path)
16
13
  message "#{bigdecimal_version}\n"
17
14
  end
18
15
 
16
+ def have_builtin_func(name, check_expr, opt = "", &b)
17
+ checking_for checking_message(name.funcall_style, nil, opt) do
18
+ if try_compile(<<SRC, opt, &b)
19
+ int foo;
20
+ int main() { #{check_expr}; return 0; }
21
+ SRC
22
+ $defs.push(format("-DHAVE_BUILTIN_%s", name.tr_cpp))
23
+ true
24
+ else
25
+ false
26
+ end
27
+ end
28
+ end
29
+
19
30
  gemspec_name = gemspec_path = nil
20
31
  unless ['', '../../'].any? {|dir|
21
32
  gemspec_name = "#{dir}bigdecimal.gemspec"
@@ -28,11 +39,34 @@ end
28
39
 
29
40
  check_bigdecimal_version(gemspec_path)
30
41
 
42
+ have_builtin_func("__builtin_clz", "__builtin_clz(0)")
43
+ have_builtin_func("__builtin_clzl", "__builtin_clzl(0)")
44
+ have_builtin_func("__builtin_clzll", "__builtin_clzll(0)")
45
+
46
+ have_header("float.h")
47
+ have_header("math.h")
48
+ have_header("stdbool.h")
49
+ have_header("stdlib.h")
50
+
51
+ have_header("x86intrin.h")
52
+ have_func("_lzcnt_u32", "x86intrin.h")
53
+ have_func("_lzcnt_u64", "x86intrin.h")
54
+
55
+ have_header("intrin.h")
56
+ have_func("__lzcnt", "intrin.h")
57
+ have_func("__lzcnt64", "intrin.h")
58
+ have_func("_BitScanReverse", "intrin.h")
59
+ have_func("_BitScanReverse64", "intrin.h")
60
+
31
61
  have_func("labs", "stdlib.h")
32
62
  have_func("llabs", "stdlib.h")
33
63
  have_func("finite", "math.h")
34
64
  have_func("isfinite", "math.h")
35
65
 
66
+ have_header("ruby/atomic.h")
67
+ have_header("ruby/internal/has/builtin.h")
68
+ have_header("ruby/internal/static_assert.h")
69
+
36
70
  have_type("struct RRational", "ruby.h")
37
71
  have_func("rb_rational_num", "ruby.h")
38
72
  have_func("rb_rational_den", "ruby.h")
@@ -0,0 +1,68 @@
1
+ #ifndef BIGDECIMAL_HAS_FEATURE_H
2
+ #define BIGDECIMAL_HAS_FEATURE_H
3
+
4
+ /* ======== __has_feature ======== */
5
+
6
+ #ifndef __has_feature
7
+ # define __has_feature(_) 0
8
+ #endif
9
+
10
+ /* ======== __has_extension ======== */
11
+
12
+ #ifndef __has_extension
13
+ # define __has_extension __has_feature
14
+ #endif
15
+
16
+ /* ======== __has_builtin ======== */
17
+
18
+ #ifdef HAVE_RUBY_INTERNAL_HAS_BUILTIN_H
19
+ # include <ruby/internal/has/builtin.h>
20
+ #endif
21
+
22
+ #ifdef RBIMPL_HAS_BUILTIN
23
+ # define BIGDECIMAL_HAS_BUILTIN(...) RBIMPL_HAS_BUILTIN(__VA_ARGS__)
24
+
25
+ #else
26
+ # /* The following section is copied from CRuby's builtin.h */
27
+ #
28
+ # ifdef __has_builtin
29
+ # if defined(__INTEL_COMPILER)
30
+ # /* :TODO: Intel C Compiler has __has_builtin (since 19.1 maybe?), and is
31
+ # * reportedly broken. We have to skip them. However the situation can
32
+ # * change. They might improve someday. We need to revisit here later. */
33
+ # elif defined(__GNUC__) && ! __has_builtin(__builtin_alloca)
34
+ # /* FreeBSD's <sys/cdefs.h> defines its own *broken* version of
35
+ # * __has_builtin. Cygwin copied that content to be a victim of the
36
+ # * broken-ness. We don't take them into account. */
37
+ # else
38
+ # define HAVE___HAS_BUILTIN 1
39
+ # endif
40
+ # endif
41
+ #
42
+ # if defined(HAVE___HAS_BUILTIN)
43
+ # define BIGDECIMAL_HAS_BUILTIN(_) __has_builtin(_)
44
+ #
45
+ # elif defined(__GNUC__)
46
+ # define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _
47
+ # if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 6))
48
+ # define BIGDECIMAL_HAS_BUILTIN___builtin_clz 1
49
+ # define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 1
50
+ # else
51
+ # define BIGDECIMAL_HAS_BUILTIN___builtin_clz 0
52
+ # define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 0
53
+ # endif
54
+ # elif defined(_MSC_VER)
55
+ # define BIGDECIMAL_HAS_BUILTIN(_) 0
56
+ #
57
+ # else
58
+ # define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _
59
+ # define BIGDECIMAL_HAS_BUILTIN___builtin_clz HAVE_BUILTIN___BUILTIN_CLZ
60
+ # define BIGDECIMAL_HAS_BUILTIN___builtin_clzl HAVE_BUILTIN___BUILTIN_CLZL
61
+ # endif
62
+ #endif /* RBIMPL_HAS_BUILTIN */
63
+
64
+ #ifndef __has_builtin
65
+ # define __has_builtin(...) BIGDECIMAL_HAS_BUILTIN(__VA_ARGS__)
66
+ #endif
67
+
68
+ #endif /* BIGDECIMAL_HAS_FEATURE_H */