simdjson  3.1.6
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 SIMDJSON_REGULAR_VISUAL_STUDIO
36 // https://en.wikipedia.org/wiki/C_alternative_tokens
37 // This header should have no effect, except maybe
38 // under Visual Studio.
39 #include <iso646.h>
40 #endif
41 
42 #if defined(__x86_64__) || defined(_M_AMD64)
43 #define SIMDJSON_IS_X86_64 1
44 #elif defined(__aarch64__) || defined(_M_ARM64)
45 #define SIMDJSON_IS_ARM64 1
46 #elif defined(__PPC64__) || defined(_M_PPC64)
47 #define SIMDJSON_IS_PPC64 1
48 #else
49 #define SIMDJSON_IS_32BITS 1
50 
51 // We do not support 32-bit platforms, but it can be
52 // handy to identify them.
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 #pragma message("The simdjson library is designed \
69 for 64-bit processors and it seems that you are not \
70 compiling for a known 64-bit platform. All fast kernels \
71 will be disabled and performance may be poor. Please \
72 use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.")
73 #endif // SIMDJSON_NO_PORTABILITY_WARNING
74 #endif // SIMDJSON_IS_32BITS
75 
76 // this is almost standard?
77 #undef SIMDJSON_STRINGIFY_IMPLEMENTATION_
78 #undef SIMDJSON_STRINGIFY
79 #define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a) #a
80 #define SIMDJSON_STRINGIFY(a) SIMDJSON_STRINGIFY_IMPLEMENTATION_(a)
81 
82 // Our fast kernels require 64-bit systems.
83 //
84 // On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions.
85 // Furthermore, the number of SIMD registers is reduced.
86 //
87 // On 32-bit ARM, we would have smaller registers.
88 //
89 // The simdjson users should still have the fallback kernel. It is
90 // slower, but it should run everywhere.
91 
92 //
93 // Enable valid runtime implementations, and select SIMDJSON_BUILTIN_IMPLEMENTATION
94 //
95 
96 // We are going to use runtime dispatch.
97 #if SIMDJSON_IS_X86_64
98 #ifdef __clang__
99 // clang does not have GCC push pop
100 // warning: clang attribute push can't be used within a namespace in clang up
101 // til 8.0 so SIMDJSON_TARGET_REGION and SIMDJSON_UNTARGET_REGION must be *outside* of a
102 // namespace.
103 #define SIMDJSON_TARGET_REGION(T) \
104  _Pragma(SIMDJSON_STRINGIFY( \
105  clang attribute push(__attribute__((target(T))), apply_to = function)))
106 #define SIMDJSON_UNTARGET_REGION _Pragma("clang attribute pop")
107 #elif defined(__GNUC__)
108 // GCC is easier
109 #define SIMDJSON_TARGET_REGION(T) \
110  _Pragma("GCC push_options") _Pragma(SIMDJSON_STRINGIFY(GCC target(T)))
111 #define SIMDJSON_UNTARGET_REGION _Pragma("GCC pop_options")
112 #endif // clang then gcc
113 
114 #endif // x86
115 
116 // Default target region macros don't do anything.
117 #ifndef SIMDJSON_TARGET_REGION
118 #define SIMDJSON_TARGET_REGION(T)
119 #define SIMDJSON_UNTARGET_REGION
120 #endif
121 
122 // Is threading enabled?
123 #if defined(_REENTRANT) || defined(_MT)
124 #ifndef SIMDJSON_THREADS_ENABLED
125 #define SIMDJSON_THREADS_ENABLED
126 #endif
127 #endif
128 
129 // workaround for large stack sizes under -O0.
130 // https://github.com/simdjson/simdjson/issues/691
131 #ifdef __APPLE__
132 #ifndef __OPTIMIZE__
133 // Apple systems have small stack sizes in secondary threads.
134 // Lack of compiler optimization may generate high stack usage.
135 // Users may want to disable threads for safety, but only when
136 // in debug mode which we detect by the fact that the __OPTIMIZE__
137 // macro is not defined.
138 #undef SIMDJSON_THREADS_ENABLED
139 #endif
140 #endif
141 
142 
143 #if defined(__clang__)
144 #define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
145 #elif defined(__GNUC__)
146 #define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
147 #else
148 #define SIMDJSON_NO_SANITIZE_UNDEFINED
149 #endif
150 
151 
152 #if defined(__clang__) || defined(__GNUC__)
153 #if defined(__has_feature)
154 # if __has_feature(memory_sanitizer)
155 #define SIMDJSON_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
156 # endif // if __has_feature(memory_sanitizer)
157 #endif // defined(__has_feature)
158 #endif
159 // make sure it is defined as 'nothing' if it is unapplicable.
160 #ifndef SIMDJSON_NO_SANITIZE_MEMORY
161 #define SIMDJSON_NO_SANITIZE_MEMORY
162 #endif
163 
164 #if SIMDJSON_VISUAL_STUDIO
165 // This is one case where we do not distinguish between
166 // regular visual studio and clang under visual studio.
167 // clang under Windows has _stricmp (like visual studio) but not strcasecmp (as clang normally has)
168 #define simdjson_strcasecmp _stricmp
169 #define simdjson_strncasecmp _strnicmp
170 #else
171 // The strcasecmp, strncasecmp, and strcasestr functions do not work with multibyte strings (e.g. UTF-8).
172 // So they are only useful for ASCII in our context.
173 // https://www.gnu.org/software/libunistring/manual/libunistring.html#char-_002a-strings
174 #define simdjson_strcasecmp strcasecmp
175 #define simdjson_strncasecmp strncasecmp
176 #endif
177 
178 #ifdef NDEBUG
179 
180 #if SIMDJSON_VISUAL_STUDIO
181 #define SIMDJSON_UNREACHABLE() __assume(0)
182 #define SIMDJSON_ASSUME(COND) __assume(COND)
183 #else
184 #define SIMDJSON_UNREACHABLE() __builtin_unreachable();
185 #define SIMDJSON_ASSUME(COND) do { if (!(COND)) __builtin_unreachable(); } while (0)
186 #endif
187 
188 #else // NDEBUG
189 
190 #define SIMDJSON_UNREACHABLE() assert(0);
191 #define SIMDJSON_ASSUME(COND) assert(COND)
192 
193 #endif
194 
195 #endif // SIMDJSON_PORTABILITY_H