DAW JSON Link
daw_json_switches.h
Go to the documentation of this file.
1 // Copyright (c) Darrell Wright
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6 // Official repository: https://github.com/beached/daw_json_link
7 //
8 
9 // This file will have all the preprocessor based switches that users can
10 // switch. Many are controllable from cmake via commandline options too.
11 
12 #pragma once
13 
14 #include <daw/daw_consteval.h>
15 #include <daw/daw_cpp_feature_check.h>
16 #include <daw/daw_is_detected.h>
17 #include <daw/stdinc/enable_if.h>
18 
21 #if defined( DAW_HAS_GCC ) and not defined( DAW_JSON_FLATTEN )
22 #if not defined( DAW_NO_FLATTEN )
23 #define DAW_NO_FLATTEN
24 #endif
25 #endif
26 
27 // Does json_link throw itself. Other things like constructors for the user
28 // types may.
29 #if defined( DAW_USE_EXCEPTIONS )
30 #if defined( DAW_JSON_DONT_USE_EXCEPTIONS )
31 #error Conflicting defines DAW_USE_EXCEPTIONS and DAW_JSON_DONT_USE_EXCEPTIONS
32 #endif
33 #if defined( DAW_DONT_USE_EXCEPTIONS )
34 #error Conflicting defines DAW_USE_EXCEPTIONS and DAW_DONT_USE_EXCEPTIONS
35 #endif
36 #else
37 #if not defined( DAW_JSON_DONT_USE_EXCEPTIONS )
38 #define DAW_JSON_DONT_USE_EXCEPTIONS
39 #endif
40 #if not defined( DAW_DONT_USE_EXCEPTIONS )
41 #define DAW_JSON_DONT_USE_EXCEPTIONS
42 #endif
43 #endif
44 
45 // Disable using guaranteed RVO to clean up after return value construction.
46 // Use DAW_NO_CONSTEXPR_SCOPE_GUARD to disable constexpr scope guard.
47 // DAW_HAS_CONSTEXPR_SCOPE_GUARD is defined when it is enabled and in
48 // <daw/daw_scope_guard.h>
49 // This has performance impacts on MSVC as on_exit_success calls
50 // std::uncaught_exceptions( ) which is very slow there
51 #if not defined( DAW_NO_CONSTEXPR_SCOPE_GUARD ) and \
52  not defined( DAW_JSON_ENABLE_FULL_RVO )
53 #define DAW_NO_CONSTEXPR_SCOPE_GUARD
54 #endif
55 
56 // DAW_IS_CONSTANT_EVALUATED is defined when a builtin or
57 // std::is_constant_evaluated( ) is available in
58 // <daw/daw_is_constant_evaluated.h>
59 
60 // Show extra diagnostic information like unmapped members when parsing
61 // by defining DAW_JSON_PARSER_DIAGNOSTICS
62 
63 // DAW_CAN_CONSTANT_EVAL is used to test if we are in a constant expression
64 #if defined( DAW_HAS_GCC_LIKE )
65 #define DAW_CAN_CONSTANT_EVAL( ... ) \
66  ( __builtin_constant_p( __VA_ARGS__ ) == 1 )
67 #else
68 #define DAW_CAN_CONSTANT_EVAL( ... ) true
69 #endif
70 
71 // If the compiler supports CNTTP types allow for strings in json data
72 // contracts. Both support passing local char const[], but the type is
73 // different. To keep old behaviour when using C++20, define
74 // DAW_USE_CPP17_ABI
75 #if not defined( DAW_USE_CPP17_ABI )
76 #if defined( __cpp_nontype_template_parameter_class )
77 #if not defined( DAW_JSON_CNTTP_JSON_NAME )
78 #define DAW_JSON_CNTTP_JSON_NAME
79 #endif
80 #endif
81 #if defined( __cpp_nontype_template_args )
82 #if __cpp_nontype_template_args >= 201911L
83 #if not defined( DAW_JSON_CNTTP_JSON_NAME )
84 #define DAW_JSON_CNTTP_JSON_NAME
85 #endif
86 #endif
87 #endif
88 #if DAW_HAS_CLANG_VER_GTE( 12, 0 ) and DAW_CPP_VERSION >= 202002L
89 // Clang 12 supports enough of CNTTP string literals and compiles the tests
90 // successfully, but does not define the feature macro
91 #if not defined( DAW_JSON_CNTTP_JSON_NAME )
92 #define DAW_JSON_CNTTP_JSON_NAME
93 #endif
94 #endif
95 #endif
96 
97 #if defined( __cpp_constexpr_dynamic_alloc )
98 #define CPP20CONSTEXPR constexpr
99 #else
100 // TODO: rename in v4
101 #define CPP20CONSTEXPR
102 #endif
103 
104 // Fix bug in MSVC
105 #if defined( DAW_HAS_MSVC )
106 #define DAW_JSON_MAKE_LOC_INFO_CONSTEVAL constexpr
107 #else
108 #define DAW_JSON_MAKE_LOC_INFO_CONSTEVAL DAW_CONSTEVAL
109 #endif
110 
111 // Allow experimental SIMD paths, if available
112 // by defining DAW_ALLOW_SSE42 and using the parser policy ExecModeType simd
113 
114 // Use strtod instead of from_chars when avialable by defining
115 // DAW_JSON_USE_STRTOD
116 #if not defined( DAW_JSON_USE_STRTOD ) and not defined( __cpp_lib_to_chars )
117 #define DAW_JSON_USE_STRTOD
118 #endif
119 
120 // define DAW_JSON_DISABLE_RANDOM to disable creating random iterators when the
121 // size is known up front. This is playing to the implementations prior to
122 // C++23 when range constructors are added to containers. It is disabled on
123 // MSVC as that impl does not work with it
124 #if defined( DAW_HAS_MSVC )
125 #if not defined( DAW_JSON_DISABLE_RANDOM )
126 #define DAW_JSON_DISABLE_RANDOM
127 #endif
128 #endif
129 
130 // DAW_JSON_HAS_BUILTIN_UADD is used to switch to a constexpr method of overflow
131 // addition when available
132 #if DAW_HAS_GCC_VER_GTE( 8, 0 ) or defined( DAW_HAS_CLANG ) or \
133  ( DAW_HAS_BUILTIN( __builtin_uadd_overflow ) and \
134  DAW_HAS_BUILTIN( __builtin_uaddl_overflow ) and \
135  DAW_HAS_BUILTIN( __builtin_uaddll_overflow ) )
136 #define DAW_JSON_HAS_BUILTIN_UADD
137 #endif
138 
139 // DAW_JSON_BUGFIX_FROM_JSON_001
140 // Defined for MSVC as it has been ICE'ing on daw_json_ensure in from_json
141 #if defined( DAW_HAS_MSVC )
142 #define DAW_JSON_BUGFIX_FROM_JSON_001
143 #endif
144 
145 // DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002
146 // MSVC cannot always evaluate in the correct order as defined by the standard.
147 // JSON Link uses the left->right guarantees in places like constructors so that
148 // less state is needed. In MSVC one must keep more state in places like
149 // parse_tuple_value
150 #if defined( DAW_HAS_MSVC )
151 #define DAW_JSON_BUGFIX_MSVC_EVAL_ORDER_002
152 #endif
153 
154 // DAW_JSON_BUGFIX_MSVC_KNOWN_LOC_ICE_003
155 // MSVC in C++20 mode will ICE when known locations is evaluated at compile time
156 #if defined( DAW_HAS_MSVC ) and __cpp_constexpr > 201700L
157 #define DAW_JSON_BUGFIX_MSVC_KNOWN_LOC_ICE_003
158 #endif
159 
163 #if not defined( NDEBUG ) or defined( DEBUG ) or \
164  defined( DAW_JSON_PARSER_DIAGNOSTICS ) or defined( DAW_HAS_MSVC )
165 #if not defined( DAW_JSON_ALWAYS_FULL_NAME_MATCH )
166 #define DAW_JSON_ALWAYS_FULL_NAME_MATCH
167 #endif
168 #endif
169 
170 // Allows pack expansions with get<Is> without separate methods. This should
171 // improve symbol sizes
172 #if defined( __cpp_generic_lambdas )
173 #if __cpp_generic_lambdas >= 201707L
174 #define DAW_JSON_USE_GENERIC_LAMBDAS
175 #endif
176 #endif
177 
178 // Use static operator( ) when supported
179 #if defined( __cpp_static_call_operator )
180 #if __cpp_static_call_operator >= 202207L
181 #define DAW_JSON_HAS_STATIC_CALL_OP
182 #endif
183 #endif
184 #if defined( DAW_JSON_HAS_STATIC_CALL_OP )
185 #define DAW_JSON_CPP23_STATIC_CALL_OP static
186 #define DAW_JSON_CPP23_STATIC_CALL_OP_CONST
187 
188 #if DAW_HAS_CLANG_VER_GTE( 17, 0 )
189 #define DAW_JSON_CPP23_STATIC_CALL_OP_DISABLE_WARNING \
190  _Pragma( "clang diagnostic push" ) \
191  _Pragma( "clang diagnostic ignored \"-Wc++23-extensions\"" )
192 
193 #define DAW_JSON_CPP23_STATIC_CALL_OP_ENABLE_WARNING \
194  _Pragma( "clang diagnostic pop" )
195 #else
196 #define DAW_JSON_CPP23_STATIC_CALL_OP_DISABLE_WARNING
197 #define DAW_JSON_CPP23_STATIC_CALL_OP_ENABLE_WARNING
198 #endif
199 #else
200 #define DAW_JSON_CPP23_STATIC_CALL_OP
201 #define DAW_JSON_CPP23_STATIC_CALL_OP_CONST const
202 #define DAW_JSON_CPP23_STATIC_CALL_OP_DISABLE_WARNING
203 #define DAW_JSON_CPP23_STATIC_CALL_OP_ENABLE_WARNING
204 #endif
205 
206 #if defined( __cpp_constexpr_dynamic_alloc )
207 #if __cpp_constexpr_dynamic_alloc >= 201907L
208 #define DAW_JSON_HAS_CPP20_CX_ALLOC
209 #endif
210 #endif
211 
212 #if defined( DAW_JSON_HAS_CPP20_CX_ALLOC )
213 #define DAW_JSON_HAS_CPP20_CX_DTOR
214 #define DAW_JSON_CPP20_CX_DTOR constexpr
215 #else
216 #define DAW_JSON_CPP20_CX_DTOR
217 #endif
218 
219 #if defined( DAW_JSON_HAS_CPP20_CX_ALLOC ) and \
220  defined( __cpp_lib_constexpr_vector )
221 #if __cpp_lib_constexpr_vector >= 201907L
222 #define DAW_JSON_HAS_CPP20_CX_VECTOR
223 #endif
224 #endif
225 
226 #if defined( DAW_JSON_HAS_CPP20_CX_VECTOR )
227 #define DAW_JSON_CX_VECTOR constexpr
228 #else
229 #define DAW_JSON_CX_VECTOR
230 #endif
231 
232 #if defined( DAW_JSON_HAS_CPP20_CX_ALLOC ) and \
233  defined( __cpp_lib_constexpr_string )
234 #if __cpp_lib_constexpr_string >= 201907L
235 #define DAW_JSON_HAS_CPP20_CX_STRING
236 #endif
237 #endif
238 
239 #if defined( DAW_JSON_HAS_CPP20_CX_STRING )
240 #define DAW_JSON_CX_STRING constexpr
241 #else
242 #define DAW_JSON_CX_STRING
243 #endif
244 
245 #if defined( DAW_JSON_HAS_CPP20_CX_STRING ) and \
246  defined( DAW_JSON_HAS_CPP20_CX_VECTOR )
247 #define DAW_JSON_HAS_CPP20_CX_STRVEC
248 #define DAW_JSON_CX_STRVEC constexpr
249 #else
250 #define DAW_JSON_CX_STRVEC
251 #endif
252 
253 // Many of the iterators used offer some extra checking when this is set. By
254 // default in debug mode they are enabled. Prior to C++20 affects the triviality
255 // of their destructors and can prevent their use in constexpr code. Setting
256 // DAW_JSON_NO_FULL_DEBUG_ITERATORS disables the destructor checks when compiler
257 // support for constexpr destructors is unavailable
258 #if defined( DAW_JSON_HAS_CPP20_CX_DTOR )
259 #if not defined( NDEBUG ) and not defined( DAW_JSON_USE_FULL_DEBUG_ITERATORS )
260 #define DAW_JSON_USE_FULL_DEBUG_ITERATORS
261 #endif
262 #endif
263 
264 #if defined( __cpp_lib_containers_ranges )
265 #if __cpp_lib_containers_ranges > 202202L
266 #define DAW_JSON_HAS_CPP23_RANGE_CTOR
267 #endif
268 #endif
269 
270 #if defined( DAW_HAS_CONCEPTS ) and not defined( DAW_JSON_NO_REQUIRES )
271 #define DAW_JSON_USE_REQUIRES
272 #define DAW_JSON_ENABLEIF( ... )
273 #define DAW_JSON_ENABLEIF2( ... )
274 #define DAW_JSON_ENABLEIF_S( ... )
275 #define DAW_JSON_REQUIRES( ... ) requires( __VA_ARGS__ )
276 #else
277 #define DAW_JSON_ENABLEIF( ... ) \
278  , std::enable_if_t<( __VA_ARGS__ ), std::nullptr_t> = nullptr
279 #define DAW_JSON_ENABLEIF2( ... ) \
280  , std::enable_if_t<( __VA_ARGS__ ), std::nullptr_t>
281 #define DAW_JSON_ENABLEIF_S( ... ) , std::enable_if_t<( __VA_ARGS__ )>
282 #define DAW_JSON_REQUIRES( ... )
283 #endif