DAW JSON Link
daw_json_parse_options.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#pragma once
10
11#include "version.h"
12
14
15#include <daw/cpp_17.h>
16#include <daw/daw_attributes.h>
17#include <daw/daw_traits.h>
18
19#include <ciso646>
20#include <climits>
21#include <cstddef>
22#include <cstdint>
23#include <utility>
24
25namespace daw::json {
26 inline namespace DAW_JSON_VER {
27 /***
28 * Allow for different optimizations. Currently only the compile_time path
29 * is fully supported. The others may offer faster parsing. The default is
30 * compile_time, it provides constexpr parsing and generally is faster
31 * currently.
32 */
33 enum class ExecModeTypes : unsigned {
35 runtime, /* testing */
36 simd /* testing */
37 }; // 2bits
38
39 namespace json_details {
40 template<>
41 inline constexpr unsigned json_option_bits_width<ExecModeTypes> = 2;
42
43 template<>
46 } // namespace json_details
47
48 /***
49 * Input is a zero terminated string. If this cannot be detected, you can
50 * specify it here. Offers some optimization possibilities in the parser.
51 * Default is no, to try and detect, but use the safer assumption that the
52 * buffer does not end in zero.
53 */
54 enum class ZeroTerminatedString : unsigned { no, yes }; // 1bit
55 namespace json_details {
56 template<>
58 1;
59
60 template<>
63 } // namespace json_details
64
65 /***
66 * Allow comments in JSON. The supported modes are none, C++ style
67 * comments, and # hash style comments. Default is none, no comments
68 * allowed
69 */
70 enum class PolicyCommentTypes : unsigned { none, cpp, hash }; // 2bits
71 namespace json_details {
72 template<>
73 inline constexpr unsigned json_option_bits_width<PolicyCommentTypes> = 2;
74
75 template<>
78 } // namespace json_details
79 /***
80 * Enable all structure, buffer, and type checking. The default is yes, but
81 * no still does some checking and can be faster.
82 */
83 enum class CheckedParseMode : unsigned { yes, no }; // 1bit
84 namespace json_details {
85 template<>
86 inline constexpr unsigned json_option_bits_width<CheckedParseMode> = 1;
87
88 template<>
91 } // namespace json_details
92
93 /***
94 * When document is minified, it is assumed that there is no whitespace in
95 * the document. Not all policies support this.
96 */
97 enum class MinifiedDocument : unsigned { no, yes }; // 1 bit
98 namespace json_details {
99 template<>
100 inline constexpr unsigned json_option_bits_width<MinifiedDocument> = 1;
101
102 template<>
105 } // namespace json_details
106
107 /***
108 * Allow the escape character '\' in names. This forces a slower parser and
109 * is generally not needed. The default is no, and the end of string
110 * matching only needs to look for a `"`, not skip `\"` in names.
111 */
112 enum class AllowEscapedNames : unsigned { no, yes }; // 1bit
113 namespace json_details {
114 template<>
115 inline constexpr unsigned json_option_bits_width<AllowEscapedNames> = 1;
116
117 template<>
120 } // namespace json_details
121
122 /***
123 * Testing
124 * Use precise IEEE754 parsing of real numbers. The default is no, and
125 * results is much faster parsing with very small errors of 0-2ulp.
126 */
127 enum class IEEE754Precise : unsigned { no, yes }; // 1bit
128 namespace json_details {
129 template<>
130 inline constexpr unsigned json_option_bits_width<IEEE754Precise> = 1;
131
132 template<>
135 } // namespace json_details
136
137 /***
138 * If the hashes of all members being looked are unique, the lookup of names
139 * as they are found in the document stops at hash checking by default. You
140 * can force a full string check by setting to yes.
141 */
142 enum class ForceFullNameCheck : unsigned { no, yes }; // 1bit
143 namespace json_details {
144 template<>
145 inline constexpr unsigned json_option_bits_width<ForceFullNameCheck> = 1;
146
147 template<>
150 } // namespace json_details
151 /***
152 * Set the default parser policy to require all JSON members in the parsed
153 * object be mapped. See also, the ignore_unknown_members and
154 * exact_class_mapping traits to set overrides
155 */
156 enum class UseExactMappingsByDefault : unsigned { no, yes }; // 1bit
157 namespace json_details {
158 template<>
159 inline constexpr unsigned
161
162 template<>
163 inline constexpr auto
166 } // namespace json_details
167
168 /***
169 * Continue checking that the data is whitespace or empty after the end of
170 * top level object is parsed from from_json
171 */
172 enum class MustVerifyEndOfDataIsValid : unsigned { no, yes };
173 namespace json_details {
174 template<>
175 inline constexpr unsigned
177
178 template<>
179 inline constexpr auto
182 } // namespace json_details
183
184 enum class ExpectLongStrings : unsigned { no, yes };
185 namespace json_details {
186 template<>
187 inline constexpr unsigned json_option_bits_width<ExpectLongStrings> = 1;
188
189 template<>
192 } // namespace json_details
193
194 /***
195 * When enabled, the parser can temporarily set a character to the desired
196 * token. This allows for safe searching without bounds checking. If the
197 * buffer is not mutable, it will not be enabled.
198 */
199 enum class TemporarilyMutateBuffer : unsigned { no, yes }; // 1bit
200 namespace json_details {
201 template<>
202 inline constexpr unsigned
204
205 template<>
208 } // namespace json_details
209
210 /***
211 * Exclude characters under 0x20 that are not explicitly allowed.
212 */
213 enum class ExcludeSpecialEscapes : unsigned { no, yes }; // 1bit
214 namespace json_details {
215 template<>
217 1;
218
219 template<>
222 } // namespace json_details
223 /* *****************************************
224 * Implementation details
225 */
226 namespace json_details {
232 ExpectLongStrings>::type;
233
234 template<typename Policy, typename Policies>
235 inline constexpr unsigned basic_policy_bits_start =
237 std::make_index_sequence<pack_size_v<Policies>>{ } );
238
239 template<typename Policy>
240 inline constexpr unsigned policy_bits_start =
241 basic_policy_bits_start<Policy, policy_list>;
242
243 template<typename Policy>
244 constexpr void set_bits_in( json_options_t &value, Policy e ) {
245 static_assert( is_option_flag<Policy>,
246 "Only registered policy types are allowed" );
247 auto new_bits = static_cast<unsigned>( e );
248 constexpr unsigned mask = (1U << json_option_bits_width<Policy>)-1U;
249 new_bits &= mask;
250 new_bits <<= policy_bits_start<Policy>;
251 value &= ~mask;
252 value |= new_bits;
253 }
254
255 template<typename Policy, typename... Policies>
256 constexpr json_options_t set_bits( json_options_t value, Policy pol,
257 Policies... pols ) {
258 static_assert( ( is_option_flag<Policies> and ... ),
259 "Only registered policy types are allowed" );
260
261 auto new_bits = static_cast<unsigned>( pol );
262 constexpr unsigned mask = ( (1U << json_option_bits_width<Policy>)-1U );
263 new_bits &= mask;
264 new_bits <<= policy_bits_start<Policy>;
265 value &= ~( mask << policy_bits_start<Policy> );
266 value |= new_bits;
267 if constexpr( sizeof...( Policies ) > 0 ) {
268 if constexpr( sizeof...( pols ) > 0 ) {
269 return set_bits( value, pols... );
270 } else {
271 return value;
272 }
273 } else {
274 return value;
275 }
276 }
277
278 template<typename Policy>
279 constexpr json_options_t set_bits_for( Policy e ) {
280 static_assert( is_option_flag<Policy>,
281 "Only registered policy types are allowed" );
282 auto new_bits = static_cast<json_options_t>( e );
283 new_bits <<= policy_bits_start<Policy>;
284 return new_bits;
285 }
286
287 template<typename>
289
290 template<typename... Policies>
291 struct default_policy_flag_t<pack_list<Policies...>> {
292 static constexpr json_options_t value =
293 ( set_bits_for<Policies>( default_json_option_value<Policies> ) |
294 ... );
295 };
296
297 /***
298 * The defaults for all known policies encoded as a json_options_t
299 */
300 inline static constexpr json_options_t default_policy_flag =
302
303 template<typename Policy, typename Result = Policy>
304 constexpr Result get_bits_for( json_options_t value ) {
305 static_assert( is_option_flag<Policy>,
306 "Only registered policy types are allowed" );
307 constexpr unsigned mask = ( 1U << (policy_bits_start<Policy> +
308 json_option_bits_width<Policy>)) -
309 1U;
310 value &= mask;
311 value >>= policy_bits_start<Policy>;
312 return static_cast<Result>( Policy{ value } );
313 }
314 } // namespace json_details
315 // ***********************************************
316
317 /***
318 * Create the parser options flag for BasicParsePolicy
319 * @tparam Policies Policy types that satisfy the `is_policy_flag` trait.
320 * @param policies A list of parser options to change from the defaults.
321 * @return A json_options_t that encodes the options for the parser
322 */
323 template<typename... Policies>
325 parse_options( Policies... policies ) {
326 static_assert( ( json_details::is_option_flag<Policies> and ... ),
327 "Only registered policy types are allowed" );
329 if constexpr( sizeof...( Policies ) > 0 ) {
330 result |= ( json_details::set_bits_for( policies ) | ... );
331 }
332 return result;
333 }
334 } // namespace DAW_JSON_VER
335} // namespace daw::json
constexpr auto default_json_option_value< PolicyCommentTypes >
Definition: daw_json_parse_options.h:76
constexpr unsigned basic_policy_bits_start
Definition: daw_json_parse_options.h:235
static constexpr json_options_t set_bits_for(JsonOptionList< OptionList... >, Option e)
Definition: daw_json_option_bits.h:161
constexpr auto default_json_option_value< UseExactMappingsByDefault >
Definition: daw_json_parse_options.h:164
constexpr auto default_json_option_value< MinifiedDocument >
Definition: daw_json_parse_options.h:103
constexpr auto default_json_option_value< ExecModeTypes >
Definition: daw_json_parse_options.h:44
constexpr auto default_json_option_value< IEEE754Precise >
Definition: daw_json_parse_options.h:133
constexpr auto default_json_option_value< MustVerifyEndOfDataIsValid >
Definition: daw_json_parse_options.h:180
constexpr unsigned json_option_bits_width< ExcludeSpecialEscapes >
Definition: daw_json_parse_options.h:216
constexpr json_options_t set_bits(JsonOptionList< OptionList... >, json_options_t value, Option pol, Options... pols)
Definition: daw_json_option_bits.h:138
constexpr unsigned json_option_bits_width< UseExactMappingsByDefault >
Definition: daw_json_parse_options.h:160
constexpr auto default_json_option_value< CheckedParseMode >
Definition: daw_json_parse_options.h:89
typename option_list_impl< ExecModeTypes, ZeroTerminatedString, PolicyCommentTypes, CheckedParseMode, AllowEscapedNames, IEEE754Precise, ForceFullNameCheck, MinifiedDocument, UseExactMappingsByDefault, TemporarilyMutateBuffer, MustVerifyEndOfDataIsValid, ExcludeSpecialEscapes, ExpectLongStrings >::type policy_list
Definition: daw_json_parse_options.h:232
constexpr auto default_json_option_value< TemporarilyMutateBuffer >
Definition: daw_json_parse_options.h:206
constexpr auto default_json_option_value< ForceFullNameCheck >
Definition: daw_json_parse_options.h:148
constexpr unsigned json_option_bits_width< CheckedParseMode >
Definition: daw_json_parse_options.h:86
constexpr unsigned json_option_bits_width< ExecModeTypes >
Definition: daw_json_parse_options.h:41
std::uint32_t json_options_t
Definition: daw_json_option_bits.h:23
constexpr unsigned json_option_bits_width< MinifiedDocument >
Definition: daw_json_parse_options.h:100
static constexpr json_options_t default_policy_flag
Definition: daw_json_parse_options.h:300
constexpr auto default_json_option_value< ExpectLongStrings >
Definition: daw_json_parse_options.h:190
constexpr unsigned json_option_bits_width< IEEE754Precise >
Definition: daw_json_parse_options.h:130
constexpr unsigned json_option_bits_width< TemporarilyMutateBuffer >
Definition: daw_json_parse_options.h:203
constexpr unsigned json_option_bits_width< ForceFullNameCheck >
Definition: daw_json_parse_options.h:145
constexpr unsigned json_option_bits_width< PolicyCommentTypes >
Definition: daw_json_parse_options.h:73
constexpr auto default_json_option_value< AllowEscapedNames >
Definition: daw_json_parse_options.h:118
constexpr void set_bits_in(JsonOptionList< OptionList... >, json_options_t &value, Option e)
Definition: daw_json_option_bits.h:124
constexpr auto default_json_option_value< ZeroTerminatedString >
Definition: daw_json_parse_options.h:61
constexpr Result get_bits_for(JsonOptionList< OptionList... >, json_options_t value)
Definition: daw_json_option_bits.h:167
constexpr unsigned json_option_bits_width< ZeroTerminatedString >
Definition: daw_json_parse_options.h:57
constexpr unsigned json_option_bits_width< MustVerifyEndOfDataIsValid >
Definition: daw_json_parse_options.h:176
constexpr unsigned policy_bits_start
Definition: daw_json_parse_options.h:240
constexpr auto default_json_option_value< ExcludeSpecialEscapes >
Definition: daw_json_parse_options.h:220
constexpr unsigned json_option_bits_width< ExpectLongStrings >
Definition: daw_json_parse_options.h:187
constexpr unsigned json_option_bits_width< AllowEscapedNames >
Definition: daw_json_parse_options.h:115
UseExactMappingsByDefault
Definition: daw_json_parse_options.h:156
constexpr json_details::json_options_t parse_options(Policies... policies)
Definition: daw_json_parse_options.h:325
ForceFullNameCheck
Definition: daw_json_parse_options.h:142
IEEE754Precise
Definition: daw_json_parse_options.h:127
CheckedParseMode
Definition: daw_json_parse_options.h:83
ExpectLongStrings
Definition: daw_json_parse_options.h:184
ExecModeTypes
Definition: daw_json_parse_options.h:33
MustVerifyEndOfDataIsValid
Definition: daw_json_parse_options.h:172
PolicyCommentTypes
Definition: daw_json_parse_options.h:70
AllowEscapedNames
Definition: daw_json_parse_options.h:112
MinifiedDocument
Definition: daw_json_parse_options.h:97
ExcludeSpecialEscapes
Definition: daw_json_parse_options.h:213
ZeroTerminatedString
Definition: daw_json_parse_options.h:54
TemporarilyMutateBuffer
Definition: daw_json_parse_options.h:199
Definition: daw_from_json.h:22
Definition: daw_json_parse_options.h:288
Definition: daw_json_option_bits.h:58
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:16