DAW JSON Link
Loading...
Searching...
No Matches
daw_json_parse_options_impl.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
15
16#include <daw/cpp_17.h>
17#include <daw/daw_attributes.h>
18#include <daw/daw_string_view.h>
19#include <daw/daw_traits.h>
20#include <daw/daw_unreachable.h>
21
22#include <climits>
23#include <cstddef>
24#include <cstdint>
25#include <utility>
26
27namespace daw::json {
28 inline namespace DAW_JSON_VER {
29 namespace options {
30 constexpr daw::string_view to_string( ExecModeTypes mode ) {
31 switch( mode ) {
32 case ExecModeTypes::compile_time:
33 return "compile_time";
34 case ExecModeTypes::runtime:
35 return "runtime";
36 case ExecModeTypes::simd:
37 return "simd";
38 }
39 DAW_UNREACHABLE( );
40 }
41 } // namespace options
42
43 namespace json_details {
44 template<>
45 inline constexpr unsigned json_option_bits_width<options::ExecModeTypes> =
46 2;
47
48 template<>
49 inline constexpr auto default_json_option_value<options::ExecModeTypes> =
50 options::ExecModeTypes::compile_time;
51
52 template<>
53 inline constexpr unsigned
54 json_option_bits_width<options::ZeroTerminatedString> = 1;
55
56 template<>
57 inline constexpr auto
58 default_json_option_value<options::ZeroTerminatedString> =
59 options::ZeroTerminatedString::no;
60
61 template<>
62 inline constexpr unsigned
63 json_option_bits_width<options::PolicyCommentTypes> = 2;
64
65 template<>
66 inline constexpr auto
67 default_json_option_value<options::PolicyCommentTypes> =
68 options::PolicyCommentTypes::none;
69
70 template<>
71 inline constexpr unsigned
72 json_option_bits_width<options::CheckedParseMode> = 1;
73
74 template<>
75 inline constexpr auto
76 default_json_option_value<options::CheckedParseMode> =
77 options::CheckedParseMode::yes;
78
79 template<>
80 inline constexpr unsigned
81 json_option_bits_width<options::MinifiedDocument> = 1;
82
83 template<>
84 inline constexpr auto
85 default_json_option_value<options::MinifiedDocument> =
86 options::MinifiedDocument::no;
87
88 template<>
89 inline constexpr unsigned
90 json_option_bits_width<options::AllowEscapedNames> = 1;
91
92 template<>
93 inline constexpr auto
94 default_json_option_value<options::AllowEscapedNames> =
95 options::AllowEscapedNames::no;
96
97 template<>
98 inline constexpr unsigned
99 json_option_bits_width<options::IEEE754Precise> = 1;
100
101 template<>
102 inline constexpr auto default_json_option_value<options::IEEE754Precise> =
103 options::IEEE754Precise::no;
104
105 template<>
106 inline constexpr unsigned
107 json_option_bits_width<options::ForceFullNameCheck> = 1;
108
109 template<>
110 inline constexpr auto
111 default_json_option_value<options::ForceFullNameCheck> =
112 options::ForceFullNameCheck::no;
113
114 template<>
115 inline constexpr unsigned
116 json_option_bits_width<options::UseExactMappingsByDefault> = 1;
117
118 template<>
119 inline constexpr auto
120 default_json_option_value<options::UseExactMappingsByDefault> =
121 options::UseExactMappingsByDefault::no;
122
123 template<>
124 inline constexpr unsigned
125 json_option_bits_width<options::MustVerifyEndOfDataIsValid> = 1;
126
127 template<>
128 inline constexpr auto
129 default_json_option_value<options::MustVerifyEndOfDataIsValid> =
130 options::MustVerifyEndOfDataIsValid::no;
131
132 template<>
133 inline constexpr unsigned
134 json_option_bits_width<options::ExpectLongNames> = 1;
135
136 template<>
137 inline constexpr auto
138 default_json_option_value<options::ExpectLongNames> =
139 options::ExpectLongNames::no;
140
141 /*
142 template<>
143 inline constexpr unsigned
144 json_option_bits_width<options::TemporarilyMutateBuffer> = 1;
145
146 template<>
147 inline constexpr auto
148 default_json_option_value<options::TemporarilyMutateBuffer> =
149 options::TemporarilyMutateBuffer::no;
150 */
151
152 template<>
153 inline constexpr unsigned
154 json_option_bits_width<options::ExcludeSpecialEscapes> = 1;
155
156 template<>
157 inline constexpr auto
158 default_json_option_value<options::ExcludeSpecialEscapes> =
159 options::ExcludeSpecialEscapes::no;
160
161 using policy_list = typename option_list_impl<
162 options::ExecModeTypes, options::ZeroTerminatedString,
163 options::PolicyCommentTypes, options::CheckedParseMode,
164 options::AllowEscapedNames, options::IEEE754Precise,
165 options::ForceFullNameCheck, options::MinifiedDocument,
166 options::UseExactMappingsByDefault, options::MustVerifyEndOfDataIsValid,
167 options::ExcludeSpecialEscapes, options::ExpectLongNames>::type;
168
169 template<typename Policy, typename Policies>
170 inline constexpr unsigned basic_policy_bits_start =
171 option_bits_start_impl<Policy, Policies>::template calc<>(
172 std::make_index_sequence<pack_size_v<Policies>>{ } );
173
174 template<typename Policy>
175 inline constexpr unsigned policy_bits_start =
176 basic_policy_bits_start<Policy, policy_list>;
177
178 DAW_CONSTEVAL inline json_options_t set_bits( json_options_t value ) {
179 return value;
180 }
181
182 template<typename PolicyFlag,
183 typename... PolicyFlags DAW_JSON_ENABLEIF(
184 are_option_flags<PolicyFlag, PolicyFlags...> )>
185 DAW_JSON_REQUIRES( are_option_flags<PolicyFlag, PolicyFlags...> )
186 DAW_CONSTEVAL json_options_t
187 set_bits( json_options_t value, PolicyFlag pol, PolicyFlags... pols ) {
188 static_assert( are_option_flags<PolicyFlags...>,
189 "Only registered policy types are allowed" );
190
191 auto new_bits = static_cast<unsigned>( pol );
192 constexpr unsigned mask =
193 ( (1U << json_option_bits_width<PolicyFlag>)-1U );
194 new_bits &= mask;
195 new_bits <<= policy_bits_start<PolicyFlag>;
196 value &= ~( mask << policy_bits_start<PolicyFlag> );
197 value |= new_bits;
198 if constexpr( sizeof...( PolicyFlags ) > 0 ) {
199 if constexpr( sizeof...( pols ) > 0 ) {
200 return set_bits( value, pols... );
201 } else {
202 return value;
203 }
204 } else {
205 return value;
206 }
207 }
208
209 template<typename Policy>
210 DAW_CONSTEVAL json_options_t set_bits_for( Policy e ) {
211 static_assert( is_option_flag<Policy>,
212 "Only registered policy types are allowed" );
213 auto new_bits = static_cast<json_options_t>( e );
214 new_bits <<= policy_bits_start<Policy>;
215 return new_bits;
216 }
217
218 template<typename>
219 struct default_policy_flag_t;
220
221 template<typename... Policies>
222 struct default_policy_flag_t<pack_list<Policies...>> {
223 static constexpr json_options_t value =
224 ( set_bits_for<Policies>( default_json_option_value<Policies> ) |
225 ... );
226 };
227
228 /***
229 * The defaults for all known policies encoded as a json_options_t
230 */
231 inline static constexpr json_options_t default_policy_flag =
232 default_policy_flag_t<policy_list>::value;
233
234 template<typename Policy, typename Result = Policy>
235 DAW_CONSTEVAL Result get_bits_for( json_options_t value ) {
236 static_assert( is_option_flag<Policy>,
237 "Only registered policy types are allowed" );
238 constexpr unsigned mask = ( 1U << (policy_bits_start<Policy> +
239 json_option_bits_width<Policy>)) -
240 1U;
241 value &= mask;
242 value >>= policy_bits_start<Policy>;
243 return static_cast<Result>( Policy{ value } );
244 }
245 } // namespace json_details
246 // ***********************************************
247
248 /***
249 * Create the parser options flag for BasicParsePolicy
250 * @tparam Policies Policy types that satisfy the `is_policy_flag` trait.
251 * @param policies A list of parser options to change from the defaults.
252 * @return A json_options_t that encodes the options for the parser
253 */
254 template<typename... Policies>
255 DAW_CONSTEVAL json_options_t parse_options( Policies... policies ) {
256 static_assert( json_details::are_option_flags<Policies...>,
257 "Only registered policy types are allowed" );
258 auto result = json_details::default_policy_flag;
259 if constexpr( sizeof...( Policies ) > 0 ) {
260 result |= ( json_details::set_bits_for( policies ) | ... );
261 }
262 return result;
263 }
264 } // namespace DAW_JSON_VER
265} // namespace daw::json
#define DAW_JSON_ENABLEIF(...)
#define DAW_JSON_REQUIRES(...)
constexpr std::string_view to_string(JsonBaseParseTypes pt)
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20