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