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