DAW JSON Link
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 
13 #include "daw_json_option_bits.h"
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 
27 namespace 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<
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(...)
constexpr std::string_view to_string(JsonBaseParseTypes pt)
ZeroTerminatedString
Input is a zero terminated string. If this cannot be detected, you can specify it here....
CheckedParseMode
Enable all structure, buffer, and type checking. The default is yes, but no still does some checking ...
ExcludeSpecialEscapes
Exclude characters under 0x20 that are not explicitly allowed.
ForceFullNameCheck
If the hashes of all members being looked are unique, the lookup of names as they are found in the do...
PolicyCommentTypes
Allow comments in JSON. The supported modes are none, C++ style comments, and # hash style comments....
AllowEscapedNames
Allow the escape character '\' in names. This forces a slower parser and is generally not needed....
MinifiedDocument
When document is minified, it is assumed that there is no whitespace in the document....
MustVerifyEndOfDataIsValid
Continue checking that the data is whitespace or empty after the end of top level object is parsed fr...
IEEE754Precise
Use precise IEEE754 parsing of real numbers. The default is no, and results is much faster parsing wi...
ExecModeTypes
Allow for different optimizations. Currently only the compile_time path is fully supported....
UseExactMappingsByDefault
Set the default parser policy to require all JSON members in the parsed object be mapped....
Customization point traits.
DAW_JSON_REQUIRES(boost::describe::has_describe_members< T >::value and use_boost_describe_v< T >) struct json_data_contract< T >
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:25