simdjson 5.0.2
Ridiculously Fast JSON
Loading...
Searching...
No Matches
compiler_check.h
1#ifndef SIMDJSON_COMPILER_CHECK_H
2#define SIMDJSON_COMPILER_CHECK_H
3
4#ifndef __cplusplus
5#error simdjson requires a C++ compiler
6#endif
7
8#ifndef SIMDJSON_CPLUSPLUS
9#if defined(_MSVC_LANG) && !defined(__clang__)
10#define SIMDJSON_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
11#else
12#define SIMDJSON_CPLUSPLUS __cplusplus
13#endif
14#endif
15
16// C++ 26
17// While C++26 is a working draft, compilers report 202400L in C++26 mode
18// (both GCC 16 and Clang 21 do). Update when the standard is finalized.
19#if !defined(SIMDJSON_CPLUSPLUS26) && (SIMDJSON_CPLUSPLUS >= 202400L)
20#define SIMDJSON_CPLUSPLUS26 1
21#endif
22
23// C++ 23
24#if !defined(SIMDJSON_CPLUSPLUS23) && (SIMDJSON_CPLUSPLUS >= 202302L)
25#define SIMDJSON_CPLUSPLUS23 1
26#endif
27
28// C++ 20
29#if !defined(SIMDJSON_CPLUSPLUS20) && (SIMDJSON_CPLUSPLUS >= 202002L)
30#define SIMDJSON_CPLUSPLUS20 1
31#endif
32
33// C++ 17
34#if !defined(SIMDJSON_CPLUSPLUS17) && (SIMDJSON_CPLUSPLUS >= 201703L)
35#define SIMDJSON_CPLUSPLUS17 1
36#endif
37
38// C++ 14
39#if !defined(SIMDJSON_CPLUSPLUS14) && (SIMDJSON_CPLUSPLUS >= 201402L)
40#define SIMDJSON_CPLUSPLUS14 1
41#endif
42
43// C++ 11
44#if !defined(SIMDJSON_CPLUSPLUS11) && (SIMDJSON_CPLUSPLUS >= 201103L)
45#define SIMDJSON_CPLUSPLUS11 1
46#endif
47
48#ifndef SIMDJSON_CPLUSPLUS11
49#error simdjson requires a compiler compliant with the C++11 standard
50#endif
51
52#ifndef SIMDJSON_IF_CONSTEXPR
53#if SIMDJSON_CPLUSPLUS17
54#define SIMDJSON_IF_CONSTEXPR if constexpr
55#else
56#define SIMDJSON_IF_CONSTEXPR if
57#endif
58#endif
59
60#ifndef SIMDJSON_CONSTEXPR_LAMBDA
61#if SIMDJSON_CPLUSPLUS17
62#define SIMDJSON_CONSTEXPR_LAMBDA constexpr
63#else
64#define SIMDJSON_CONSTEXPR_LAMBDA
65#endif
66#endif
67
68
69
70#ifdef __has_include
71#if __has_include(<version>)
72#include <version>
73#endif
74#endif
75
76// Static reflection.
77//
78// The reflection-based APIs (simdjson::to, document::get<T>, the builder,
79// compile-time JSON, annotations) need considerably more than the reflection
80// operator. We turn them on only when the compiler advertises all of:
81//
82// P2996 reflection (^^, splicers, <meta>) __cpp_impl_reflection,
83// __cpp_lib_reflection
84// P1306 expansion statements (template for) __cpp_expansion_statements
85// P3491 std::define_static_string / _array __cpp_lib_define_static
86//
87// Two further features we rely on have, as of this writing, no feature-test
88// macro of their own, so they cannot be checked directly:
89//
90// P3394 annotations ([[=x]], std::meta::annotations_of) -- used for
91// the annotations of simdjson/annotations.h (rename, skip, ...).
92// P3289 consteval blocks (consteval { ... }) -- used by compile_time_json.
93//
94// Every implementation that defines the four macros above also implements
95// those two, so requiring the four is sufficient in practice. If that ever
96// stops being true, define SIMDJSON_STATIC_REFLECTION=0 to opt out.
97//
98// SIMDJSON_STATIC_REFLECTION may always be defined by the user (or by the
99// build system) to 0 or 1 to override the detection.
100//
101// Note that C++26 mode alone is not enough: GCC 16 requires -freflection,
102// and only then does it define __cpp_impl_reflection.
103#ifndef SIMDJSON_STATIC_REFLECTION
104#if defined(SIMDJSON_CPLUSPLUS26) && \
105 defined(__cpp_impl_reflection) && __cpp_impl_reflection >= 202506L && \
106 defined(__cpp_lib_reflection) && __cpp_lib_reflection >= 202506L && \
107 defined(__cpp_expansion_statements) && \
108 __cpp_expansion_statements >= 202506L && \
109 defined(__cpp_lib_define_static) && __cpp_lib_define_static >= 202506L
110// __cpp_lib_reflection is the feature-test macro for <meta>, so there is no
111// need for a separate __has_include check (which would have to be guarded for
112// compilers that lack __has_include).
113#define SIMDJSON_STATIC_REFLECTION 1
114#else
115#define SIMDJSON_STATIC_REFLECTION 0
116#endif
117#endif // SIMDJSON_STATIC_REFLECTION
118
119#if defined(__apple_build_version__)
120#if __apple_build_version__ < 14000000
121#define SIMDJSON_CONCEPT_DISABLED 1 // apple-clang/13 doesn't support std::convertible_to
122#endif
123#endif
124
125#if defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 201911L
126#include <ranges>
127#define SIMDJSON_SUPPORTS_RANGES 1
128#else
129#define SIMDJSON_SUPPORTS_RANGES 0
130#endif
131
132#if defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
133#if __cpp_concepts >= 201907L
134#include <utility>
135#define SIMDJSON_SUPPORTS_CONCEPTS 1
136#else
137#define SIMDJSON_SUPPORTS_CONCEPTS 0
138#endif
139#else // defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
140#define SIMDJSON_SUPPORTS_CONCEPTS 0
141#endif // defined(__cpp_concepts) && !defined(SIMDJSON_CONCEPT_DISABLED)
142
143// copy SIMDJSON_SUPPORTS_CONCEPTS to SIMDJSON_SUPPORTS_DESERIALIZATION.
144#if SIMDJSON_SUPPORTS_CONCEPTS
145#define SIMDJSON_SUPPORTS_DESERIALIZATION 1
146#else
147#define SIMDJSON_SUPPORTS_DESERIALIZATION 0
148#endif
149
150// The C++20 char8_t type (and std::u8string/std::u8string_view) is available.
151// Because all strings that simdjson produces are valid UTF-8, we can offer
152// char8_t variants of our string accessors when this macro is set.
153#if !defined(SIMDJSON_SUPPORTS_CHAR8_T)
154#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
155#define SIMDJSON_SUPPORTS_CHAR8_T 1
156#else
157#define SIMDJSON_SUPPORTS_CHAR8_T 0
158#endif
159#endif // !defined(SIMDJSON_SUPPORTS_CHAR8_T)
160
161// The C++23 fixed-width floating-point types std::float32_t and std::float64_t
162// (<stdfloat>) are available. They are optional even in C++23: a compiler that
163// provides them predefines __STDCPP_FLOAT32_T__ and __STDCPP_FLOAT64_T__.
164// When these macros are set, we offer get_float32() and get_float64().
165#if !defined(SIMDJSON_SUPPORTS_FLOAT32_T)
166#if defined(__STDCPP_FLOAT32_T__) && defined(__has_include)
167#if __has_include(<stdfloat>)
168#define SIMDJSON_SUPPORTS_FLOAT32_T 1
169#endif
170#endif
171#ifndef SIMDJSON_SUPPORTS_FLOAT32_T
172#define SIMDJSON_SUPPORTS_FLOAT32_T 0
173#endif
174#endif // !defined(SIMDJSON_SUPPORTS_FLOAT32_T)
175
176#if !defined(SIMDJSON_SUPPORTS_FLOAT64_T)
177#if defined(__STDCPP_FLOAT64_T__) && defined(__has_include)
178#if __has_include(<stdfloat>)
179#define SIMDJSON_SUPPORTS_FLOAT64_T 1
180#endif
181#endif
182#ifndef SIMDJSON_SUPPORTS_FLOAT64_T
183#define SIMDJSON_SUPPORTS_FLOAT64_T 0
184#endif
185#endif // !defined(SIMDJSON_SUPPORTS_FLOAT64_T)
186
187#if SIMDJSON_SUPPORTS_FLOAT32_T || SIMDJSON_SUPPORTS_FLOAT64_T
188#include <stdfloat>
189#endif
190
191
192#if !defined(SIMDJSON_CONSTEVAL)
193#if defined(__cpp_consteval) && __cpp_consteval >= 201811L && defined(__cpp_lib_constexpr_string) && __cpp_lib_constexpr_string >= 201907L
194#define SIMDJSON_CONSTEVAL 1
195#else
196#define SIMDJSON_CONSTEVAL 0
197#endif // defined(__cpp_consteval) && __cpp_consteval >= 201811L && defined(__cpp_lib_constexpr_string) && __cpp_lib_constexpr_string >= 201907L
198#endif // !defined(SIMDJSON_CONSTEVAL)
199
200// SIMDJSON_CONSTEXPR_STRING is 'constexpr' when the standard library supports
201// constexpr std::string (e.g., libstdc++ 12 or better), and empty otherwise. It
202// lets functions that build a std::string be constant expressions when possible
203// while still compiling against older standard libraries.
204#if !defined(SIMDJSON_CONSTEXPR_STRING)
205#if defined(__cpp_lib_constexpr_string) && __cpp_lib_constexpr_string >= 201907L
206#define SIMDJSON_CONSTEXPR_STRING constexpr
207#else
208#define SIMDJSON_CONSTEXPR_STRING
209#endif // defined(__cpp_lib_constexpr_string) && __cpp_lib_constexpr_string >= 201907L
210#endif // !defined(SIMDJSON_CONSTEXPR_STRING)
211#endif // SIMDJSON_COMPILER_CHECK_H