/src/jsoncons/include/jsoncons/config/compiler_support.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2013-2025 Daniel Parker |
2 | | // Distributed under the Boost license, Version 1.0. |
3 | | // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4 | | |
5 | | // See https://github.com/danielaparker/jsoncons for latest version |
6 | | |
7 | | #ifndef JSONCONS_CONFIG_COMPILER_SUPPORT_HPP |
8 | | #define JSONCONS_CONFIG_COMPILER_SUPPORT_HPP |
9 | | |
10 | | #include <cmath> |
11 | | #include <cstdint> |
12 | | #include <cstring> // std::memcpy |
13 | | #include <limits> // std::numeric_limits |
14 | | |
15 | | #if !defined(JSONCONS_NO_EXCEPTIONS) |
16 | 20.3k | #define JSONCONS_THROW(exception) throw exception |
17 | 0 | #define JSONCONS_RETHROW throw |
18 | 44.8M | #define JSONCONS_TRY try |
19 | | #define JSONCONS_CATCH(exception) catch(exception) |
20 | | #else |
21 | | #define JSONCONS_THROW(exception) std::terminate() |
22 | | #define JSONCONS_RETHROW std::terminate() |
23 | | #define JSONCONS_TRY if (true) |
24 | | #define JSONCONS_CATCH(exception) if (false) |
25 | | #endif |
26 | | |
27 | | #if defined(__GNUC__) |
28 | | # if defined(__GNUC_PATCHLEVEL__) |
29 | | # define JSONCONS_GCC_AVAILABLE(major, minor, patch) \ |
30 | | ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ |
31 | | >= ((major) * 10000 + (minor) * 100 + (patch))) |
32 | | # else |
33 | | # define JSONCONS_GCC_AVAILABLE(major, minor, patch) \ |
34 | | ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) \ |
35 | | >= ((major) * 10000 + (minor) * 100 + (patch))) |
36 | | # endif |
37 | | # else |
38 | | # define JSONCONS_GCC_AVAILABLE(major, minor, patch) 0 |
39 | | #endif |
40 | | |
41 | | #if defined(__clang__) |
42 | | # define JSONCONS_CLANG_AVAILABLE(major, minor, patch) \ |
43 | | ((__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) \ |
44 | | >= ((major) * 10000 + (minor) * 100 + (patch))) |
45 | | # else |
46 | | # define JSONCONS_CLANG_AVAILABLE(major, minor, patch) 0 |
47 | | #endif |
48 | | |
49 | | // Uncomment the following line to suppress deprecated names (recommended for new code) |
50 | | //#define JSONCONS_NO_DEPRECATED |
51 | | |
52 | | // The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor |
53 | | // MIT license |
54 | | |
55 | | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577 |
56 | | |
57 | | #if defined(__GNUC__) || defined(__clang__) |
58 | 30.0M | #define JSONCONS_LIKELY(x) __builtin_expect(!!(x), 1) |
59 | 1.69G | #define JSONCONS_UNLIKELY(x) __builtin_expect(!!(x), 0) |
60 | 0 | #define JSONCONS_UNREACHABLE() __builtin_unreachable() |
61 | | #elif defined(_MSC_VER) |
62 | | #define JSONCONS_LIKELY(x) x |
63 | | #define JSONCONS_UNLIKELY(x) x |
64 | | #define JSONCONS_UNREACHABLE() __assume(0) |
65 | | #else |
66 | | #define JSONCONS_LIKELY(x) x |
67 | | #define JSONCONS_UNLIKELY(x) x |
68 | | #define JSONCONS_UNREACHABLE() do {} while (0) |
69 | | #endif |
70 | | |
71 | | // Deprecated symbols markup |
72 | | #if (defined(__cplusplus) && __cplusplus >= 201402L) |
73 | | #define JSONCONS_DEPRECATED_MSG(msg) [[deprecated(msg)]] |
74 | | #endif |
75 | | |
76 | | #if !defined(JSONCONS_DEPRECATED_MSG) && defined(__GNUC__) && defined(__has_extension) |
77 | | #if __has_extension(attribute_deprecated_with_message) |
78 | | #define JSONCONS_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) |
79 | | #endif |
80 | | #endif |
81 | | |
82 | | #if !defined(JSONCONS_DEPRECATED_MSG) && defined(_MSC_VER) |
83 | | #if (_MSC_VER) >= 1920 |
84 | | #define JSONCONS_DEPRECATED_MSG(msg) [[deprecated(msg)]] |
85 | | #else |
86 | | #define JSONCONS_DEPRECATED_MSG(msg) __declspec(deprecated(msg)) |
87 | | #endif |
88 | | #endif |
89 | | |
90 | | // Following boost/atomic/detail/config.hpp |
91 | | #if !defined(JSONCONS_DEPRECATED_MSG) && (\ |
92 | | (defined(__GNUC__) && ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0)) >= 405) ||\ |
93 | | (defined(__SUNPRO_CC) && (__SUNPRO_CC + 0) >= 0x5130)) |
94 | | #define JSONCONS_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) |
95 | | #endif |
96 | | |
97 | | #if !defined(JSONCONS_DEPRECATED_MSG) && defined(__clang__) && defined(__has_extension) |
98 | | #if __has_extension(attribute_deprecated_with_message) |
99 | | #define JSONCONS_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) |
100 | | #else |
101 | | #define JSONCONS_DEPRECATED_MSG(msg) __attribute__((deprecated)) |
102 | | #endif |
103 | | #endif |
104 | | |
105 | | #if !defined(JSONCONS_DEPRECATED_MSG) |
106 | | #define JSONCONS_DEPRECATED_MSG(msg) |
107 | | #endif |
108 | | |
109 | | #if defined(ANDROID) || defined(__ANDROID__) |
110 | | #if __ANDROID_API__ >= 21 |
111 | | #define JSONCONS_HAS_STRTOLD_L |
112 | | #else |
113 | | #define JSONCONS_NO_LOCALECONV |
114 | | #endif |
115 | | #endif |
116 | | |
117 | | #if defined(_MSC_VER) |
118 | | #define JSONCONS_HAS_MSC_STRTOD_L |
119 | | #define JSONCONS_HAS_FOPEN_S |
120 | | #endif |
121 | | |
122 | | #ifndef JSONCONS_HAS_CP14 |
123 | | #if defined(_MSVC_LANG) |
124 | | #if _MSVC_LANG >= 201402L |
125 | | #define JSONCONS_HAS_CP14 |
126 | | #endif |
127 | | #elif __cplusplus >= 201402L |
128 | | #define JSONCONS_HAS_CP14 |
129 | | #endif |
130 | | #endif |
131 | | |
132 | | #if !defined(JSONCONS_HAS_STD_FROM_CHARS) |
133 | | # if defined(__GNUC__) |
134 | | # if (__GNUC__ >= 11) |
135 | | # if (__cplusplus >= 201703) |
136 | | # if !defined(__MINGW32__) |
137 | | # define JSONCONS_HAS_STD_FROM_CHARS 1 |
138 | | # endif // !defined(__MINGW32__) |
139 | | # endif // (__cplusplus >= 201703) |
140 | | # endif // (__GNUC__ >= 11) |
141 | | # endif // defined(__GNUC__) |
142 | | # if defined(_MSC_VER) |
143 | | # if (_MSC_VER >= 1924 && _MSVC_LANG >= 201703) |
144 | | # define JSONCONS_HAS_STD_FROM_CHARS 1 |
145 | | # endif // (_MSC_VER >= 1924 && MSVC_LANG >= 201703) |
146 | | # endif // defined(_MSC_VER) |
147 | | #endif |
148 | | |
149 | | #if defined(JSONCONS_HAS_STD_FROM_CHARS) && JSONCONS_HAS_STD_FROM_CHARS |
150 | | #include <charconv> |
151 | | #endif |
152 | | |
153 | | #if !defined(JSONCONS_HAS_2017) |
154 | | # if defined(__clang__) |
155 | | # if (__cplusplus >= 201703) |
156 | | # define JSONCONS_HAS_2017 1 |
157 | | # endif // (__cplusplus >= 201703) |
158 | | # endif // defined(__clang__) |
159 | | # if defined(__GNUC__) |
160 | | # if (__GNUC__ >= 7) |
161 | | # if (__cplusplus >= 201703) |
162 | | # define JSONCONS_HAS_2017 1 |
163 | | # endif // (__cplusplus >= 201703) |
164 | | # endif // (__GNUC__ >= 7) |
165 | | # endif // defined(__GNUC__) |
166 | | # if defined(_MSC_VER) |
167 | | # if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703) |
168 | | # define JSONCONS_HAS_2017 1 |
169 | | # endif // (_MSC_VER >= 1910 && MSVC_LANG >= 201703) |
170 | | # endif // defined(_MSC_VER) |
171 | | #endif |
172 | | |
173 | | #if defined(JSONCONS_HAS_2017) |
174 | | #define JSONCONS_NODISCARD [[nodiscard]] |
175 | | #define JSONCONS_IF_CONSTEXPR if constexpr |
176 | | #define JSONCONS_INLINE_CONSTEXPR inline constexpr |
177 | | #else |
178 | | #define JSONCONS_NODISCARD |
179 | | #define JSONCONS_IF_CONSTEXPR if |
180 | | #define JSONCONS_INLINE_CONSTEXPR constexpr |
181 | | #endif |
182 | | |
183 | | #if !defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) |
184 | | #if defined(JSONCONS_HAS_2017) |
185 | | # if __has_include(<memory_resource>) |
186 | | # define JSONCONS_HAS_POLYMORPHIC_ALLOCATOR 1 |
187 | | # endif // __has_include(<string_view>) |
188 | | #endif |
189 | | #endif |
190 | | |
191 | | #if !defined(JSONCONS_HAS_STD_STRING_VIEW) |
192 | | # if (defined JSONCONS_HAS_2017) |
193 | | # if defined(__clang__) |
194 | | # if __has_include(<string_view>) |
195 | | # define JSONCONS_HAS_STD_STRING_VIEW 1 |
196 | | # endif // __has_include(<string_view>) |
197 | | # else |
198 | | # define JSONCONS_HAS_STD_STRING_VIEW 1 |
199 | | # endif |
200 | | # endif // defined(JSONCONS_HAS_2017) |
201 | | #endif // !defined(JSONCONS_HAS_STD_STRING_VIEW) |
202 | | |
203 | | #if !defined(JSONCONS_HAS_STD_BYTE) |
204 | | # if (defined JSONCONS_HAS_2017) |
205 | | # define JSONCONS_HAS_STD_BYTE 1 |
206 | | # endif // defined(JSONCONS_HAS_2017) |
207 | | #endif // !defined(JSONCONS_HAS_STD_BYTE) |
208 | | |
209 | | #if !defined(JSONCONS_HAS_STD_OPTIONAL) |
210 | | # if (defined JSONCONS_HAS_2017) |
211 | | # if defined(__clang__) |
212 | | # if __has_include(<optional>) |
213 | | # define JSONCONS_HAS_STD_OPTIONAL 1 |
214 | | # endif // __has_include(<string_view>) |
215 | | # else |
216 | | # define JSONCONS_HAS_STD_OPTIONAL 1 |
217 | | # endif |
218 | | # endif // defined(JSONCONS_HAS_2017) |
219 | | #endif // !defined(JSONCONS_HAS_STD_OPTIONAL) |
220 | | |
221 | | #if !defined(JSONCONS_HAS_STD_VARIANT) |
222 | | # if (defined JSONCONS_HAS_2017) |
223 | | # if defined(__clang__) |
224 | | # if defined(__APPLE__) |
225 | | # if JSONCONS_CLANG_AVAILABLE(10,0,1) |
226 | | # define JSONCONS_HAS_STD_VARIANT 1 |
227 | | # endif |
228 | | # elif __has_include(<variant>) |
229 | | # define JSONCONS_HAS_STD_VARIANT 1 |
230 | | # endif // __has_include(<variant>) |
231 | | # else |
232 | | # define JSONCONS_HAS_STD_VARIANT 1 |
233 | | # endif |
234 | | # endif // defined(JSONCONS_HAS_2017) |
235 | | #endif // !defined(JSONCONS_HAS_STD_VARIANT) |
236 | | |
237 | | #if !defined(JSONCONS_HAS_FILESYSTEM) |
238 | | # if (defined JSONCONS_HAS_2017) |
239 | | # if defined(__clang__) |
240 | | # if __has_include(<filesystem>) |
241 | | # define JSONCONS_HAS_FILESYSTEM 1 |
242 | | # endif // __has_include(<filesystem>) |
243 | | # else |
244 | | # define JSONCONS_HAS_FILESYSTEM 1 |
245 | | # endif |
246 | | # endif // defined(JSONCONS_HAS_2017) |
247 | | #endif // !defined(JSONCONS_HAS_FILESYSTEM) |
248 | | |
249 | | #if (!defined(JSONCONS_NO_EXCEPTIONS)) |
250 | | // Check if exceptions are disabled. |
251 | | # if defined( __cpp_exceptions) && __cpp_exceptions == 0 |
252 | | # define JSONCONS_NO_EXCEPTIONS 1 |
253 | | # endif |
254 | | #endif |
255 | | |
256 | | #if !defined(JSONCONS_NO_EXCEPTIONS) |
257 | | |
258 | | #if defined(__GNUC__) && !defined(__EXCEPTIONS) |
259 | | # define JSONCONS_NO_EXCEPTIONS 1 |
260 | | #elif defined(_MSC_VER) |
261 | | #if defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 |
262 | | # define JSONCONS_NO_EXCEPTIONS 1 |
263 | | #elif !defined(_CPPUNWIND) |
264 | | # define JSONCONS_NO_EXCEPTIONS 1 |
265 | | #endif |
266 | | #endif |
267 | | #endif |
268 | | |
269 | | #if !defined(JSONCONS_HAS_STD_MAKE_UNIQUE) |
270 | | #if defined(__clang__) && defined(__cplusplus) |
271 | | #if defined(__APPLE__) |
272 | | #if __clang_major__ >= 6 && __cplusplus >= 201402L // Xcode 6 |
273 | | #define JSONCONS_HAS_STD_MAKE_UNIQUE |
274 | | #endif |
275 | | #elif ((__clang_major__*100 +__clang_minor__) >= 340) && __cplusplus >= 201402L |
276 | | #define JSONCONS_HAS_STD_MAKE_UNIQUE |
277 | | #endif |
278 | | #elif defined(__GNUC__) |
279 | | #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L |
280 | | #define JSONCONS_HAS_STD_MAKE_UNIQUE |
281 | | #endif |
282 | | #elif defined(_MSC_VER) |
283 | | #if _MSC_VER >= 1800 |
284 | | #define JSONCONS_HAS_STD_MAKE_UNIQUE |
285 | | #endif |
286 | | #endif |
287 | | #endif // !defined(JSONCONS_HAS_STD_MAKE_UNIQUE) |
288 | | |
289 | | #ifndef JSONCONS_HAS_CP14_CONSTEXPR |
290 | | #if defined(_MSC_VER) |
291 | | #if _MSC_VER >= 1910 |
292 | | #define JSONCONS_HAS_CP14_CONSTEXPR |
293 | | #endif |
294 | | #elif defined(__GNUC__) |
295 | | #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 600 && __cplusplus >= 201402L |
296 | | #define JSONCONS_HAS_CP14_CONSTEXPR |
297 | | #endif |
298 | | #endif |
299 | | #endif |
300 | | |
301 | | #if defined(JSONCONS_HAS_CP14_CONSTEXPR) |
302 | | # define JSONCONS_CPP14_CONSTEXPR constexpr |
303 | | #else |
304 | | # define JSONCONS_CPP14_CONSTEXPR |
305 | | #endif |
306 | | |
307 | | // Follows boost |
308 | | |
309 | | // gcc and clang |
310 | | #if !defined(__CUDA_ARCH__) |
311 | | #if (defined(__clang__) || defined(__GNUC__)) && defined(__cplusplus) |
312 | | #if defined(__SIZEOF_INT128__) && !defined(_MSC_VER) |
313 | | # define JSONCONS_HAS_INT128 |
314 | | #endif |
315 | | |
316 | | #if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) |
317 | | #if (__clang_major__ >= 4) && defined(__has_include) |
318 | | #if __has_include(<quadmath.h>) |
319 | | # define JSONCONS_HAS_FLOAT128 |
320 | | #endif |
321 | | #endif |
322 | | #endif |
323 | | #endif |
324 | | |
325 | | #if defined(__GNUC__) |
326 | | #if defined(_GLIBCXX_USE_FLOAT128) |
327 | | # define JSONCONS_HAS_FLOAT128 |
328 | | #endif |
329 | | #endif |
330 | | |
331 | | #if defined(__clang__) |
332 | | #if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) |
333 | | #if (__clang_major__ >= 4) && defined(__has_include) |
334 | | #if __has_include(<quadmath.h>) |
335 | | # define JSONCONS_HAS_FLOAT128 |
336 | | #endif |
337 | | #endif |
338 | | #endif |
339 | | #endif |
340 | | #endif // __CUDA_ARCH__ |
341 | | |
342 | | #ifndef JSONCONS_FORCE_INLINE |
343 | | # ifdef _MSC_VER |
344 | | # define JSONCONS_FORCE_INLINE __forceinline |
345 | | # elif defined(__GNUC__) || defined(__clang__) |
346 | | # define JSONCONS_FORCE_INLINE inline __attribute__((always_inline)) |
347 | | # else |
348 | | # define JSONCONS_FORCE_INLINE inline |
349 | | # endif |
350 | | #endif // JSONCONS_FORCE_INLINE |
351 | | |
352 | | |
353 | | /** compiler builtin check (since gcc 10.0, clang 2.6, icc 2021) */ |
354 | | #ifndef JSONCONS_HAS_BUILTIN |
355 | | # ifdef __has_builtin |
356 | | # define JSONCONS_HAS_BUILTIN(x) __has_builtin(x) |
357 | | # else |
358 | | # define JSONCONS_HAS_BUILTIN(x) 0 |
359 | | # endif |
360 | | #endif |
361 | | |
362 | | /** compiler attribute check (since gcc 5.0, clang 2.9, icc 17) */ |
363 | | #ifndef JSONCONS_HAS_ATTRIBUTE |
364 | | # ifdef __has_attribute |
365 | | # define JSONCONS_HAS_ATTRIBUTE(x) __has_attribute(x) |
366 | | # else |
367 | | # define JSONCONS_HAS_ATTRIBUTE(x) 0 |
368 | | # endif |
369 | | #endif |
370 | | |
371 | | /** compiler feature check (since clang 2.6, icc 17) */ |
372 | | #ifndef JSONCONS_HAS_FEATURE |
373 | | # ifdef __has_feature |
374 | | # define JSONCONS_HAS_FEATURE(x) __has_feature(x) |
375 | | # else |
376 | | # define JSONCONS_HAS_FEATURE(x) 0 |
377 | | # endif |
378 | | #endif |
379 | | |
380 | | /** include check (since gcc 5.0, clang 2.7, icc 16, msvc 2017 15.3) */ |
381 | | #ifndef JSONCONS_HAS_INCLUDE |
382 | | # ifdef __has_include |
383 | | # define JSONCONS_HAS_INCLUDE(x) __has_include(x) |
384 | | # else |
385 | | # define JSONCONS_HAS_INCLUDE(x) 0 |
386 | | # endif |
387 | | #endif |
388 | | |
389 | | /** noinline for compiler */ |
390 | | #ifndef JSONCONS_NOINLINE |
391 | | # if YYJSON_MSC_VER >= 1400 |
392 | | # define JSONCONS_NOINLINE __declspec(noinline) |
393 | | # elif JSONCONS_HAS_ATTRIBUTE(noinline) || YYJSON_GCC_VER >= 4 |
394 | | # define JSONCONS_NOINLINE __attribute__((noinline)) |
395 | | # else |
396 | | # define JSONCONS_NOINLINE |
397 | | # endif |
398 | | #endif |
399 | | |
400 | | /** align for compiler */ |
401 | | #ifndef JSONCONS_ALIGN |
402 | | # if YYJSON_MSC_VER >= 1300 |
403 | | # define JSONCONS_ALIGN(x) __declspec(align(x)) |
404 | | # elif JSONCONS_HAS_ATTRIBUTE(aligned) || defined(__GNUC__) |
405 | | # define JSONCONS_ALIGN(x) __attribute__((aligned(x))) |
406 | | # elif YYJSON_CPP_VER >= 201103L |
407 | | # define JSONCONS_ALIGN(x) alignas(x) |
408 | | # else |
409 | | # define JSONCONS_ALIGN(x) |
410 | | # endif |
411 | | #endif |
412 | | |
413 | | // Follows boost config/detail/suffix.hpp |
414 | | #if defined(JSONCONS_HAS_INT128) && defined(__cplusplus) |
415 | | namespace jsoncons{ |
416 | | # ifdef __GNUC__ |
417 | | __extension__ typedef __int128 int128_type; |
418 | | __extension__ typedef unsigned __int128 uint128_type; |
419 | | # else |
420 | | typedef __int128 int128_type; |
421 | | typedef unsigned __int128 uint128_type; |
422 | | # endif |
423 | | } |
424 | | #endif |
425 | | #if defined(JSONCONS_HAS_FLOAT128) && defined(__cplusplus) |
426 | | namespace jsoncons { |
427 | | # ifdef __GNUC__ |
428 | | __extension__ typedef __float128 float128_type; |
429 | | # else |
430 | | typedef __float128 float128_type; |
431 | | # endif |
432 | | } |
433 | | #endif |
434 | | |
435 | | #if defined(_MSC_VER) && _MSC_VER <= 1900 |
436 | | #define JSONCONS_COPY(first,last,d_first) std::copy(first, last, stdext::make_checked_array_iterator(d_first, static_cast<std::size_t>(std::distance(first, last)))) |
437 | | #else |
438 | | #define JSONCONS_COPY(first,last,d_first) std::copy(first, last, d_first) |
439 | | #endif |
440 | | |
441 | | #if defined(JSONCONS_HAS_CP14) |
442 | | #define JSONCONS_CONSTEXPR constexpr |
443 | | #else |
444 | | #define JSONCONS_CONSTEXPR |
445 | | #endif |
446 | | |
447 | | #if !defined(JSONCONS_HAS_STD_REGEX) |
448 | | #if defined(__clang__) |
449 | | #define JSONCONS_HAS_STD_REGEX 1 |
450 | | #elif (defined(__GNUC__) && (__GNUC__ == 4)) && (defined(__GNUC__) && __GNUC_MINOR__ < 9) |
451 | | // GCC 4.8 has broken regex support: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631 |
452 | | #else |
453 | | #define JSONCONS_HAS_STD_REGEX 1 |
454 | | #endif |
455 | | #endif |
456 | | |
457 | | #if !defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) |
458 | | #if defined(__clang__) && !JSONCONS_CLANG_AVAILABLE(11,0,0) |
459 | | #elif defined(__GNUC__) && !JSONCONS_GCC_AVAILABLE(10,0,0) |
460 | | #else |
461 | | #define JSONCONS_HAS_STATEFUL_ALLOCATOR 1 |
462 | | #endif |
463 | | #endif |
464 | | |
465 | | // The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor |
466 | | // MIT license |
467 | | |
468 | | #ifdef __F16C__ |
469 | | # include <immintrin.h> |
470 | | #endif |
471 | | |
472 | | #ifndef __has_builtin |
473 | | # define __has_builtin(x) 0 |
474 | | #endif |
475 | | |
476 | | #if defined(__GNUC__) |
477 | | #if (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) || (__has_builtin(__builtin_bswap64) && __has_builtin(__builtin_bswap32)) |
478 | 2.78M | # define JSONCONS_BYTE_SWAP_64 __builtin_bswap64 |
479 | 19.8M | # define JSONCONS_BYTE_SWAP_32 __builtin_bswap32 |
480 | | # ifdef __INTEL_COMPILER |
481 | | # define JSONCONS_BYTE_SWAP_16 _bswap16 |
482 | | # elif (__GNUC__ * 100 + __GNUC_MINOR__ >= 608) || __has_builtin(__builtin_bswap16) |
483 | 127M | # define JSONCONS_BYTE_SWAP_16 __builtin_bswap16 |
484 | | # endif |
485 | | #endif |
486 | | #elif defined(__sun) |
487 | | # include <sys/byteorder.h> |
488 | | #elif defined(_MSC_VER) |
489 | | // MSVC, which implies sizeof(long) == 4 |
490 | | # define JSONCONS_BYTE_SWAP_64 _byteswap_uint64 |
491 | | # define JSONCONS_BYTE_SWAP_32 _byteswap_ulong |
492 | | # define JSONCONS_BYTE_SWAP_16 _byteswap_ushort |
493 | | #endif |
494 | | |
495 | | namespace jsoncons { |
496 | | namespace binary { |
497 | | |
498 | | static inline bool add_check_overflow(std::size_t v1, std::size_t v2, std::size_t *r) |
499 | 0 | { |
500 | 0 | #if ((defined(__GNUC__) && (__GNUC__ >= 5)) && !defined(__INTEL_COMPILER)) || __has_builtin(__builtin_add_overflow) |
501 | 0 | return __builtin_add_overflow(v1, v2, r); |
502 | 0 | #else |
503 | 0 | // unsigned additions are well-defined |
504 | 0 | *r = v1 + v2; |
505 | 0 | return v1 > v1 + v2; |
506 | 0 | #endif |
507 | 0 | } Unexecuted instantiation: fuzz_parse.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_json_encoder.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_csv_encoder.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_csv.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_bson_encoder.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_bson_parser_max.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_msgpack_parser_max.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_cbor_encoder.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_ubjson_parser_max.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_cbor.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_json_parser_max.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_ubjson.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_json_cursor.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_bson.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_ubjson_encoder.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_cbor_parser_max.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_msgpack.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) Unexecuted instantiation: fuzz_msgpack_encoder.cpp:jsoncons::binary::add_check_overflow(unsigned long, unsigned long, unsigned long*) |
508 | | |
509 | | #if defined(__apple_build_version__) && ((__clang_major__ < 8) || ((__clang_major__ == 8) && (__clang_minor__ < 1))) |
510 | | #define APPLE_MISSING_INTRINSICS 1 |
511 | | #endif |
512 | | |
513 | | inline |
514 | | uint16_t encode_half(double val) |
515 | 0 | { |
516 | 0 | #if defined(__F16C__) && !defined(APPLE_MISSING_INTRINSICS) |
517 | 0 | return _cvtss_sh((float)val, 3); |
518 | 0 | #else |
519 | 0 | uint64_t v; |
520 | 0 | std::memcpy(&v, &val, sizeof(v)); |
521 | 0 | int64_t sign = static_cast<int64_t>(v >> 63 << 15); |
522 | 0 | int64_t exp = (v >> 52) & 0x7ff; |
523 | 0 | int64_t mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */ |
524 | 0 | exp -= 1023; |
525 | 0 | if (exp == 1024) { |
526 | 0 | /* infinity or NaN */ |
527 | 0 | exp = 16; |
528 | 0 | mant >>= 1; |
529 | 0 | } else if (exp >= 16) { |
530 | 0 | /* overflow, as largest number */ |
531 | 0 | exp = 15; |
532 | 0 | mant = 1023; |
533 | 0 | } else if (exp >= -14) { |
534 | 0 | /* regular normal */ |
535 | 0 | } else if (exp >= -24) { |
536 | 0 | /* subnormal */ |
537 | 0 | mant |= 1024; |
538 | 0 | mant >>= -(exp + 14); |
539 | 0 | exp = -15; |
540 | 0 | } else { |
541 | 0 | /* underflow, make zero */ |
542 | 0 | return 0; |
543 | 0 | } |
544 | 0 |
|
545 | 0 | /* safe cast here as bit operations above guarantee not to overflow */ |
546 | 0 | return static_cast<uint16_t>(sign | ((exp + 15) << 10) | mant); |
547 | 0 | #endif |
548 | 0 | } |
549 | | |
550 | | /* this function was copied & adapted from RFC 7049 Appendix D */ |
551 | | inline |
552 | | double decode_half(uint16_t half) |
553 | 116M | { |
554 | | #if defined(__F16C__) && !defined(APPLE_MISSING_INTRINSICS) |
555 | | return _cvtsh_ss(half); |
556 | | #else |
557 | 116M | int64_t exp = (half >> 10) & 0x1f; |
558 | 116M | int64_t mant = half & 0x3ff; |
559 | 116M | double val; |
560 | 116M | if (exp == 0) |
561 | 17.1M | { |
562 | 17.1M | val = ldexp(static_cast<double>(mant), -24); |
563 | 17.1M | } |
564 | 99.3M | else if (exp != 31) |
565 | 92.5M | { |
566 | 92.5M | val = ldexp(static_cast<double>(mant) + 1024.0, static_cast<int>(exp - 25)); |
567 | 92.5M | } |
568 | 6.86M | else |
569 | 6.86M | { |
570 | 6.86M | val = mant == 0 ? std::numeric_limits<double>::infinity() : std::nan(""); |
571 | 6.86M | } |
572 | 116M | return half & 0x8000 ? -val : val; |
573 | 116M | #endif |
574 | 116M | } |
575 | | |
576 | | } // namespace binary |
577 | | } // namespace jsoncons |
578 | | // allow to disable exceptions |
579 | | |
580 | | #if defined(JSONCONS_HAS_2017) |
581 | 4.64M | # define JSONCONS_FALLTHROUGH [[fallthrough]] |
582 | | #elif defined(__clang__) |
583 | | # define JSONCONS_FALLTHROUGH [[clang::fallthrough]] |
584 | | #elif defined(__GNUC__) && ((__GNUC__ >= 7)) |
585 | | # define JSONCONS_FALLTHROUGH __attribute__((fallthrough)) |
586 | | #elif defined (__GNUC__) |
587 | | # define JSONCONS_FALLTHROUGH // FALLTHRU |
588 | | #else |
589 | | # define JSONCONS_FALLTHROUGH |
590 | | #endif |
591 | | |
592 | | #endif // JSONCONS_CONFIG_COMPILER_SUPPORT_HPP |