simdjson
3.11.0
Ridiculously Fast JSON
portability.h
1
#ifndef SIMDJSON_PORTABILITY_H
2
#define SIMDJSON_PORTABILITY_H
3
4
#include <cstddef>
5
#include <cstdint>
6
#include <cstdlib>
7
#include <cfloat>
8
#include <cassert>
9
#ifndef _WIN32
10
// strcasecmp, strncasecmp
11
#include <strings.h>
12
#endif
13
14
// We are using size_t without namespace std:: throughout the project
15
using
std::size_t;
16
17
#ifdef _MSC_VER
18
#define SIMDJSON_VISUAL_STUDIO 1
29
#ifdef __clang__
30
// clang under visual studio
31
#define SIMDJSON_CLANG_VISUAL_STUDIO 1
32
#else
33
// just regular visual studio (best guess)
34
#define SIMDJSON_REGULAR_VISUAL_STUDIO 1
35
#endif
// __clang__
36
#endif
// _MSC_VER
37
38
#if (defined(__x86_64__) || defined(_M_AMD64)) && !defined(_M_ARM64EC)
39
#define SIMDJSON_IS_X86_64 1
40
#elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
41
#define SIMDJSON_IS_ARM64 1
42
#elif defined(__riscv) && __riscv_xlen == 64
43
#define SIMDJSON_IS_RISCV64 1
44
#elif defined(__loongarch_lp64)
45
#define SIMDJSON_IS_LOONGARCH64 1
46
#elif defined(__PPC64__) || defined(_M_PPC64)
47
#if defined(__ALTIVEC__)
48
#define SIMDJSON_IS_PPC64_VMX 1
49
#endif
// defined(__ALTIVEC__)
50
#else
51
#define SIMDJSON_IS_32BITS 1
52
53
#if defined(_M_IX86) || defined(__i386__)
54
#define SIMDJSON_IS_X86_32BITS 1
55
#elif defined(__arm__) || defined(_M_ARM)
56
#define SIMDJSON_IS_ARM_32BITS 1
57
#elif defined(__PPC__) || defined(_M_PPC)
58
#define SIMDJSON_IS_PPC_32BITS 1
59
#endif
60
61
#endif
// defined(__x86_64__) || defined(_M_AMD64)
62
#ifndef SIMDJSON_IS_32BITS
63
#define SIMDJSON_IS_32BITS 0
64
#endif
65
66
#if SIMDJSON_IS_32BITS
67
#ifndef SIMDJSON_NO_PORTABILITY_WARNING
68
// In the future, we should allow programmers
69
// to get warning.
70
#endif
// SIMDJSON_NO_PORTABILITY_WARNING
71
#endif
// SIMDJSON_IS_32BITS
72
73
#define SIMDJSON_CAT_IMPLEMENTATION_(a,...) a ## __VA_ARGS__
74
#define SIMDJSON_CAT(a,...) SIMDJSON_CAT_IMPLEMENTATION_(a, __VA_ARGS__)
75
76
#define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a,...) #a SIMDJSON_STRINGIFY(__VA_ARGS__)
77
#define SIMDJSON_STRINGIFY(a,...) SIMDJSON_CAT_IMPLEMENTATION_(a, __VA_ARGS__)
78
79
// this is almost standard?
80
#undef SIMDJSON_STRINGIFY_IMPLEMENTATION_
81
#undef SIMDJSON_STRINGIFY
82
#define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a) #a
83
#define SIMDJSON_STRINGIFY(a) SIMDJSON_STRINGIFY_IMPLEMENTATION_(a)
84
85
// Our fast kernels require 64-bit systems.
86
//
87
// On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions.
88
// Furthermore, the number of SIMD registers is reduced.
89
//
90
// On 32-bit ARM, we would have smaller registers.
91
//
92
// The simdjson users should still have the fallback kernel. It is
93
// slower, but it should run everywhere.
94
95
//
96
// Enable valid runtime implementations, and select SIMDJSON_BUILTIN_IMPLEMENTATION
97
//
98
99
// We are going to use runtime dispatch.
100
#if SIMDJSON_IS_X86_64
101
#ifdef __clang__
102
// clang does not have GCC push pop
103
// warning: clang attribute push can't be used within a namespace in clang up
104
// til 8.0 so SIMDJSON_TARGET_REGION and SIMDJSON_UNTARGET_REGION must be *outside* of a
105
// namespace.
106
#define SIMDJSON_TARGET_REGION(T) \
107
_Pragma(SIMDJSON_STRINGIFY( \
108
clang attribute push(__attribute__((target(T))), apply_to = function)))
109
#define SIMDJSON_UNTARGET_REGION _Pragma("clang attribute pop"
)
110
#elif defined(__GNUC__)
111
// GCC is easier
112
#define SIMDJSON_TARGET_REGION(T) \
113
_Pragma("GCC push_options"
) _Pragma(SIMDJSON_STRINGIFY(GCC target(T)))
114
#define SIMDJSON_UNTARGET_REGION _Pragma("GCC pop_options"
)
115
#endif
// clang then gcc
116
117
#endif
// x86
118
119
// Default target region macros don't do anything.
120
#ifndef SIMDJSON_TARGET_REGION
121
#define SIMDJSON_TARGET_REGION(T)
122
#define SIMDJSON_UNTARGET_REGION
123
#endif
124
125
// Is threading enabled?
126
#if defined(_REENTRANT) || defined(_MT)
127
#ifndef SIMDJSON_THREADS_ENABLED
128
#define SIMDJSON_THREADS_ENABLED
129
#endif
130
#endif
131
132
// workaround for large stack sizes under -O0.
133
// https://github.com/simdjson/simdjson/issues/691
134
#ifdef __APPLE__
135
#ifndef __OPTIMIZE__
136
// Apple systems have small stack sizes in secondary threads.
137
// Lack of compiler optimization may generate high stack usage.
138
// Users may want to disable threads for safety, but only when
139
// in debug mode which we detect by the fact that the __OPTIMIZE__
140
// macro is not defined.
141
#undef SIMDJSON_THREADS_ENABLED
142
#endif
143
#endif
144
145
146
#if defined(__clang__)
147
#define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"
)))
148
#elif defined(__GNUC__)
149
#define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
150
#else
151
#define SIMDJSON_NO_SANITIZE_UNDEFINED
152
#endif
153
154
#if defined(__clang__) || defined(__GNUC__)
155
#define simdjson_pure [[gnu::pure]]
156
#else
157
#define simdjson_pure
158
#endif
159
160
#if defined(__clang__) || defined(__GNUC__)
161
#if defined(__has_feature)
162
# if __has_feature(memory_sanitizer)
163
#define SIMDJSON_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory"
)))
164
# endif
// if __has_feature(memory_sanitizer)
165
#endif
// defined(__has_feature)
166
#endif
167
// make sure it is defined as 'nothing' if it is unapplicable.
168
#ifndef SIMDJSON_NO_SANITIZE_MEMORY
169
#define SIMDJSON_NO_SANITIZE_MEMORY
170
#endif
171
172
#if SIMDJSON_VISUAL_STUDIO
173
// This is one case where we do not distinguish between
174
// regular visual studio and clang under visual studio.
175
// clang under Windows has _stricmp (like visual studio) but not strcasecmp (as clang normally has)
176
#define simdjson_strcasecmp _stricmp
177
#define simdjson_strncasecmp _strnicmp
178
#else
179
// The strcasecmp, strncasecmp, and strcasestr functions do not work with multibyte strings (e.g. UTF-8).
180
// So they are only useful for ASCII in our context.
181
// https://www.gnu.org/software/libunistring/manual/libunistring.html#char-_002a-strings
182
#define simdjson_strcasecmp strcasecmp
183
#define simdjson_strncasecmp strncasecmp
184
#endif
185
186
#if defined(NDEBUG) || defined(__OPTIMIZE__) || (defined(_MSC_VER) && !defined(_DEBUG))
187
// If NDEBUG is set, or __OPTIMIZE__ is set, or we are under MSVC in release mode,
188
// then do away with asserts and use __assume.
189
#if SIMDJSON_VISUAL_STUDIO
190
#define SIMDJSON_UNREACHABLE() __assume(0)
191
#define SIMDJSON_ASSUME(COND) __assume(COND)
192
#else
193
#define SIMDJSON_UNREACHABLE() __builtin_unreachable();
194
#define SIMDJSON_ASSUME(COND) do { if (!(COND)) __builtin_unreachable(); } while (0)
195
#endif
196
197
#else
// defined(NDEBUG) || defined(__OPTIMIZE__) || (defined(_MSC_VER) && !defined(_DEBUG))
198
// This should only ever be enabled in debug mode.
199
#define SIMDJSON_UNREACHABLE() assert(0);
200
#define SIMDJSON_ASSUME(COND) assert(COND)
201
202
#endif
203
204
205
206
#if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
207
#define SIMDJSON_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
208
#elif defined _WIN32
209
#define SIMDJSON_IS_BIG_ENDIAN 0
210
#else
211
#if defined(__APPLE__) || defined(__FreeBSD__)
212
#include <machine/endian.h>
213
#elif defined(sun) || defined(__sun)
214
#include <sys/byteorder.h>
215
#elif defined(__MVS__)
216
#include <sys/endian.h>
217
#else
218
#ifdef __has_include
219
#if __has_include(<endian.h>)
220
#include <endian.h>
221
#endif
//__has_include(<endian.h>)
222
#endif
//__has_include
223
#endif
224
#
225
#ifndef __BYTE_ORDER__
226
// safe choice
227
#define SIMDJSON_IS_BIG_ENDIAN 0
228
#endif
229
#
230
#ifndef __ORDER_LITTLE_ENDIAN__
231
// safe choice
232
#define SIMDJSON_IS_BIG_ENDIAN 0
233
#endif
234
#
235
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
236
#define SIMDJSON_IS_BIG_ENDIAN 0
237
#else
238
#define SIMDJSON_IS_BIG_ENDIAN 1
239
#endif
240
#endif
241
242
243
#endif
// SIMDJSON_PORTABILITY_H
include
simdjson
portability.h
Generated by
1.9.1