1#ifndef SIMDJSON_COMMON_DEFS_H
2#define SIMDJSON_COMMON_DEFS_H
3
4#include <cassert>
5#include "simdjson/portability.h"
6
7namespace simdjson {
8
9namespace internal {
10/**
11 * @private
12 * Our own implementation of the C++17 to_chars function.
13 * Defined in src/to_chars
14 */
15char *to_chars(char *first, const char *last, double value);
16/**
17 * @private
18 * A number parsing routine.
19 * Defined in src/from_chars
20 */
21double from_chars(const char *first) noexcept;
22double from_chars(const char *first, const char* end) noexcept;
23
24}
25
26#ifndef SIMDJSON_EXCEPTIONS
27#if __cpp_exceptions
28#define SIMDJSON_EXCEPTIONS 1
29#else
30#define SIMDJSON_EXCEPTIONS 0
31#endif
32#endif
33
34/** The maximum document size supported by simdjson. */
35constexpr size_t SIMDJSON_MAXSIZE_BYTES = 0xFFFFFFFF;
36
37/**
38 * The amount of padding needed in a buffer to parse JSON.
39 *
40 * The input buf should be readable up to buf + SIMDJSON_PADDING
41 * this is a stopgap; there should be a better description of the
42 * main loop and its behavior that abstracts over this
43 * See https://github.com/simdjson/simdjson/issues/174
44 */
45constexpr size_t SIMDJSON_PADDING = 64;
46
47/**
48 * By default, simdjson supports this many nested objects and arrays.
49 *
50 * This is the default for parser::max_depth().
51 */
52constexpr size_t DEFAULT_MAX_DEPTH = 1024;
53
54} // namespace simdjson
55
56#if defined(__GNUC__)
57 // Marks a block with a name so that MCA analysis can see it.
58 #define SIMDJSON_BEGIN_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-BEGIN " #name);
59 #define SIMDJSON_END_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-END " #name);
60 #define SIMDJSON_DEBUG_BLOCK(name, block) BEGIN_DEBUG_BLOCK(name); block; END_DEBUG_BLOCK(name);
61#else
62 #define SIMDJSON_BEGIN_DEBUG_BLOCK(name)
63 #define SIMDJSON_END_DEBUG_BLOCK(name)
64 #define SIMDJSON_DEBUG_BLOCK(name, block)
65#endif
66
67// Align to N-byte boundary
68#define SIMDJSON_ROUNDUP_N(a, n) (((a) + ((n)-1)) & ~((n)-1))
69#define SIMDJSON_ROUNDDOWN_N(a, n) ((a) & ~((n)-1))
70
71#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
72
73#if SIMDJSON_REGULAR_VISUAL_STUDIO
74
75 #define simdjson_really_inline __forceinline
76 #define simdjson_never_inline __declspec(noinline)
77
78 #define simdjson_unused
79 #define simdjson_warn_unused
80
81 #ifndef simdjson_likely
82 #define simdjson_likely(x) x
83 #endif
84 #ifndef simdjson_unlikely
85 #define simdjson_unlikely(x) x
86 #endif
87
88 #define SIMDJSON_PUSH_DISABLE_WARNINGS __pragma(warning( push ))
89 #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS __pragma(warning( push, 0 ))
90 #define SIMDJSON_DISABLE_VS_WARNING(WARNING_NUMBER) __pragma(warning( disable : WARNING_NUMBER ))
91 // Get rid of Intellisense-only warnings (Code Analysis)
92 // Though __has_include is C++17, it is supported in Visual Studio 2017 or better (_MSC_VER>=1910).
93 #ifdef __has_include
94 #if __has_include(<CppCoreCheck\Warnings.h>)
95 #include <CppCoreCheck\Warnings.h>
96 #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS SIMDJSON_DISABLE_VS_WARNING(ALL_CPPCORECHECK_WARNINGS)
97 #endif
98 #endif
99
100 #ifndef SIMDJSON_DISABLE_UNDESIRED_WARNINGS
101 #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS
102 #endif
103
104 #define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_VS_WARNING(4996)
105 #define SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING
106 #define SIMDJSON_POP_DISABLE_WARNINGS __pragma(warning( pop ))
107
108#else // SIMDJSON_REGULAR_VISUAL_STUDIO
109
110 #define simdjson_really_inline inline __attribute__((always_inline))
111 #define simdjson_never_inline inline __attribute__((noinline))
112
113 #define simdjson_unused __attribute__((unused))
114 #define simdjson_warn_unused __attribute__((warn_unused_result))
115
116 #ifndef simdjson_likely
117 #define simdjson_likely(x) __builtin_expect(!!(x), 1)
118 #endif
119 #ifndef simdjson_unlikely
120 #define simdjson_unlikely(x) __builtin_expect(!!(x), 0)
121 #endif
122
123 #define SIMDJSON_PUSH_DISABLE_WARNINGS _Pragma("GCC diagnostic push")
124 // gcc doesn't seem to disable all warnings with all and extra, add warnings here as necessary
125 // We do it separately for clang since it has different warnings.
126 #ifdef __clang__
127 // clang is missing -Wmaybe-uninitialized.
128 #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \
129 SIMDJSON_DISABLE_GCC_WARNING(-Weffc++) \
130 SIMDJSON_DISABLE_GCC_WARNING(-Wall) \
131 SIMDJSON_DISABLE_GCC_WARNING(-Wconversion) \
132 SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \
133 SIMDJSON_DISABLE_GCC_WARNING(-Wattributes) \
134 SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough) \
135 SIMDJSON_DISABLE_GCC_WARNING(-Wnon-virtual-dtor) \
136 SIMDJSON_DISABLE_GCC_WARNING(-Wreturn-type) \
137 SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \
138 SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \
139 SIMDJSON_DISABLE_GCC_WARNING(-Wunused-variable)
140 #else // __clang__
141 #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \
142 SIMDJSON_DISABLE_GCC_WARNING(-Weffc++) \
143 SIMDJSON_DISABLE_GCC_WARNING(-Wall) \
144 SIMDJSON_DISABLE_GCC_WARNING(-Wconversion) \
145 SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \
146 SIMDJSON_DISABLE_GCC_WARNING(-Wattributes) \
147 SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough) \
148 SIMDJSON_DISABLE_GCC_WARNING(-Wnon-virtual-dtor) \
149 SIMDJSON_DISABLE_GCC_WARNING(-Wreturn-type) \
150 SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \
151 SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \
152 SIMDJSON_DISABLE_GCC_WARNING(-Wunused-variable) \
153 SIMDJSON_DISABLE_GCC_WARNING(-Wmaybe-uninitialized)
154 #endif // __clang__
155
156 #define SIMDJSON_PRAGMA(P) _Pragma(#P)
157 #define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING)
158 #if SIMDJSON_CLANG_VISUAL_STUDIO
159 #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS SIMDJSON_DISABLE_GCC_WARNING(-Wmicrosoft-include)
160 #else
161 #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS
162 #endif
163 #define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wdeprecated-declarations)
164 #define SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wstrict-overflow)
165 #define SIMDJSON_POP_DISABLE_WARNINGS _Pragma("GCC diagnostic pop")
166
167
168
169#endif // MSC_VER
170
171#if defined(simdjson_inline)
172 // Prefer the user's definition of simdjson_inline; don't define it ourselves.
173#elif defined(__GNUC__) && !defined(__OPTIMIZE__)
174 // If optimizations are disabled, forcing inlining can lead to significant
175 // code bloat and high compile times. Don't use simdjson_really_inline for
176 // unoptimized builds.
177 #define simdjson_inline inline
178#else
179 // Force inlining for most simdjson functions.
180 #define simdjson_inline simdjson_really_inline
181#endif
182
183#if SIMDJSON_VISUAL_STUDIO
184 /**
185 * Windows users need to do some extra work when building
186 * or using a dynamic library (DLL). When building, we need
187 * to set SIMDJSON_DLLIMPORTEXPORT to __declspec(dllexport).
188 * When *using* the DLL, the user needs to set
189 * SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport).
190 *
191 * Static libraries not need require such work.
192 *
193 * It does not matter here whether you are using
194 * the regular visual studio or clang under visual
195 * studio, you still need to handle these issues.
196 *
197 * Non-Windows systems do not have this complexity.
198 */
199 #if SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY
200 // We set SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY when we build a DLL under Windows.
201 // It should never happen that both SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY and
202 // SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY are set.
203 #define SIMDJSON_DLLIMPORTEXPORT __declspec(dllexport)
204 #elif SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY
205 // Windows user who call a dynamic library should set SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY to 1.
206 #define SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport)
207 #else
208 // We assume by default static linkage
209 #define SIMDJSON_DLLIMPORTEXPORT
210 #endif
211
212/**
213 * Workaround for the vcpkg package manager. Only vcpkg should
214 * ever touch the next line. The SIMDJSON_USING_LIBRARY macro is otherwise unused.
215 */
216#if SIMDJSON_USING_LIBRARY
217#define SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport)
218#endif
219/**
220 * End of workaround for the vcpkg package manager.
221 */
222#else
223 #define SIMDJSON_DLLIMPORTEXPORT
224#endif
225
226// C++17 requires string_view.
227#if SIMDJSON_CPLUSPLUS17
228#define SIMDJSON_HAS_STRING_VIEW
229#include <string_view> // by the standard, this has to be safe.
230#endif
231
232// This macro (__cpp_lib_string_view) has to be defined
233// for C++17 and better, but if it is otherwise defined,
234// we are going to assume that string_view is available
235// even if we do not have C++17 support.
236#ifdef __cpp_lib_string_view
237#define SIMDJSON_HAS_STRING_VIEW
238#endif
239
240// Some systems have string_view even if we do not have C++17 support,
241// and even if __cpp_lib_string_view is undefined, it is the case
242// with Apple clang version 11.
243// We must handle it. *This is important.*
244#ifndef SIMDJSON_HAS_STRING_VIEW
245#if defined __has_include
246// do not combine the next #if with the previous one (unsafe)
247#if __has_include (<string_view>)
248// now it is safe to trigger the include
249#include <string_view> // though the file is there, it does not follow that we got the implementation
250#if defined(_LIBCPP_STRING_VIEW)
251// Ah! So we under libc++ which under its Library Fundamentals Technical Specification, which preceded C++17,
252// included string_view.
253// This means that we have string_view *even though* we may not have C++17.
254#define SIMDJSON_HAS_STRING_VIEW
255#endif // _LIBCPP_STRING_VIEW
256#endif // __has_include (<string_view>)
257#endif // defined __has_include
258#endif // def SIMDJSON_HAS_STRING_VIEW
259// end of complicated but important routine to try to detect string_view.
260
261//
262// Backfill std::string_view using nonstd::string_view on systems where
263// we expect that string_view is missing. Important: if we get this wrong,
264// we will end up with two string_view definitions and potential trouble.
265// That is why we work so hard above to avoid it.
266//
267#ifndef SIMDJSON_HAS_STRING_VIEW
268SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
269#include "simdjson/nonstd/string_view.hpp"
270SIMDJSON_POP_DISABLE_WARNINGS
271
272namespace std {
273 using string_view = nonstd::string_view;
274}
275#endif // SIMDJSON_HAS_STRING_VIEW
276#undef SIMDJSON_HAS_STRING_VIEW // We are not going to need this macro anymore.
277
278/// If EXPR is an error, returns it.
279#define SIMDJSON_TRY(EXPR) { auto _err = (EXPR); if (_err) { return _err; } }
280
281// Unless the programmer has already set SIMDJSON_DEVELOPMENT_CHECKS,
282// we want to set it under debug builds. We detect a debug build
283// under Visual Studio when the _DEBUG macro is set. Under the other
284// compilers, we use the fact that they define __OPTIMIZE__ whenever
285// they allow optimizations.
286// It is possible that this could miss some cases where SIMDJSON_DEVELOPMENT_CHECKS
287// is helpful, but the programmer can set the macro SIMDJSON_DEVELOPMENT_CHECKS.
288// It could also wrongly set SIMDJSON_DEVELOPMENT_CHECKS (e.g., if the programmer
289// sets _DEBUG in a release build under Visual Studio, or if some compiler fails to
290// set the __OPTIMIZE__ macro).
291#ifndef SIMDJSON_DEVELOPMENT_CHECKS
292#ifdef _MSC_VER
293// Visual Studio seems to set _DEBUG for debug builds.
294#ifdef _DEBUG
295#define SIMDJSON_DEVELOPMENT_CHECKS 1
296#endif // _DEBUG
297#else // _MSC_VER
298// All other compilers appear to set __OPTIMIZE__ to a positive integer
299// when the compiler is optimizing.
300#ifndef __OPTIMIZE__
301#define SIMDJSON_DEVELOPMENT_CHECKS 1
302#endif // __OPTIMIZE__
303#endif // _MSC_VER
304#endif // SIMDJSON_DEVELOPMENT_CHECKS
305
306// The SIMDJSON_CHECK_EOF macro is a feature flag for the "don't require padding"
307// feature.
308
309#if SIMDJSON_CPLUSPLUS17
310// if we have C++, then fallthrough is a default attribute
311# define simdjson_fallthrough [[fallthrough]]
312// check if we have __attribute__ support
313#elif defined(__has_attribute)
314// check if we have the __fallthrough__ attribute
315#if __has_attribute(__fallthrough__)
316// we are good to go:
317# define simdjson_fallthrough __attribute__((__fallthrough__))
318#endif // __has_attribute(__fallthrough__)
319#endif // SIMDJSON_CPLUSPLUS17
320// on some systems, we simply do not have support for fallthrough, so use a default:
321#ifndef simdjson_fallthrough
322# define simdjson_fallthrough do {} while (0) /* fallthrough */
323#endif // simdjson_fallthrough
324
325
326#if SIMDJSON_DEVELOPMENT_CHECKS
327#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { assert ((expr)); } while (0)
328#else
329#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { } while (0)
330#endif
331
332#ifndef SIMDJSON_UTF8VALIDATION
333#define SIMDJSON_UTF8VALIDATION 1
334#endif
335
336#endif // SIMDJSON_COMMON_DEFS_H
337