DAW JSON Link
daw_json_parse_value.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_assert.h"
17 #include "daw_json_parse_name.h"
18 #include "daw_json_parse_real.h"
24 #include "daw_json_traits.h"
25 
26 #include <daw/daw_attributes.h>
27 #include <daw/daw_traits.h>
28 
29 #include <ciso646>
30 #include <cstddef>
31 #include <cstdint>
32 #include <iterator>
33 #include <tuple>
34 
35 namespace daw::json {
36  inline namespace DAW_JSON_VER {
37  namespace json_details {
38  /***
39  * Depending on the type of literal, it may always be quoted, sometimes,
40  * or never. This method handles the always and sometimes cases.
41  * In checked input, ensures State has more data.
42  * @tparam literal_as_string Is the literal being parsed enclosed in
43  * quotes.
44  * @tparam ParseState ParseState idiom
45  * @param parse_state Current parsing state
46  */
47  template<LiteralAsStringOpt literal_as_string, typename ParseState>
48  DAW_ATTRIB_INLINE inline constexpr void
50  if constexpr( literal_as_string == LiteralAsStringOpt::Always ) {
51  daw_json_assert_weak( parse_state.is_quotes_checked( ),
52  ErrorReason::InvalidNumberUnexpectedQuoting,
53  parse_state );
54  parse_state.remove_prefix( );
55  } else if constexpr( literal_as_string == LiteralAsStringOpt::Maybe ) {
56  daw_json_assert_weak( parse_state.has_more( ),
57  ErrorReason::UnexpectedEndOfData, parse_state );
58  if( parse_state.front( ) == '"' ) {
59  parse_state.remove_prefix( );
60  }
61  }
62  }
63 
64  template<typename JsonMember, bool KnownBounds, typename ParseState>
65  [[nodiscard,
66  maybe_unused]] DAW_ATTRIB_INLINE inline constexpr json_result<JsonMember>
68  using constructor_t = typename JsonMember::constructor_t;
69  using element_t = typename JsonMember::base_type;
70 
71  if constexpr( KnownBounds ) {
72  return construct_value(
73  template_args<json_result<JsonMember>, constructor_t>, parse_state,
74  parse_real<element_t, true>( parse_state ) );
75  } else {
76  if constexpr( JsonMember::literal_as_string !=
78  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
79  parse_state );
80  }
82  parse_state.has_more( ) and
84  ErrorReason::InvalidNumberStart, parse_state );
85 
86  auto result = construct_value(
87  template_args<json_result<JsonMember>, constructor_t>, parse_state,
88  parse_real<element_t, false>( parse_state ) );
89  if constexpr( JsonMember::literal_as_string !=
91  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
92  parse_state );
93  }
96  ErrorReason::InvalidEndOfValue, parse_state );
97  return result;
98  }
99  }
100 
101  template<typename JsonMember, bool KnownBounds, typename ParseState>
102  [[nodiscard,
103  maybe_unused]] DAW_ATTRIB_INLINE inline constexpr json_result<JsonMember>
105  using constructor_t = typename JsonMember::constructor_t;
106  using element_t = typename JsonMember::base_type;
107  using int_type =
108  typename std::conditional_t<std::is_enum_v<element_t>,
109  std::underlying_type<element_t>,
110  daw::traits::identity<element_t>>::type;
111 
112  static_assert( daw::is_signed<int_type>::value,
113  "Expected signed type" );
114  if constexpr( KnownBounds ) {
117  ErrorReason::InvalidNumberStart, parse_state );
118  } else {
119  if constexpr( JsonMember::literal_as_string !=
121  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
122  parse_state );
123  } else if constexpr( not ParseState::is_zero_terminated_string ) {
124  daw_json_assert_weak( parse_state.has_more( ),
125  ErrorReason::UnexpectedEndOfData,
126  parse_state );
127  }
128  }
129  auto const sign = static_cast<int_type>(
131 
132  if constexpr( KnownBounds ) {
133  return construct_value(
134  template_args<json_result<JsonMember>, constructor_t>, parse_state,
135  static_cast<element_t>(
136  sign * static_cast<int_type>(
137  unsigned_parser<element_t, JsonMember::range_check,
138  KnownBounds>( ParseState::exec_tag,
139  parse_state ) ) ) );
140  } else {
141  auto result = construct_value(
142  template_args<json_result<JsonMember>, constructor_t>, parse_state,
143  static_cast<element_t>(
144  sign * static_cast<int_type>(
145  unsigned_parser<element_t, JsonMember::range_check,
146  KnownBounds>( ParseState::exec_tag,
147  parse_state ) ) ) );
148  if constexpr( JsonMember::literal_as_string !=
150  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
151  parse_state );
152  }
153  parse_state.trim_left( );
156  ErrorReason::InvalidEndOfValue, parse_state );
157  return result;
158  }
159  }
160 
161  template<typename JsonMember, bool KnownBounds, typename ParseState>
162  [[nodiscard,
163  maybe_unused]] DAW_ATTRIB_INLINE inline constexpr json_result<JsonMember>
164  parse_value( ParseState &parse_state,
166  using constructor_t = typename JsonMember::constructor_t;
167  using element_t = typename JsonMember::base_type;
168 
169  if constexpr( KnownBounds ) {
170  if constexpr( JsonMember::literal_as_string !=
172  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
173  parse_state );
174  }
176 
177  return construct_value(
178  template_args<json_result<JsonMember>, constructor_t>, parse_state,
179  unsigned_parser<element_t, JsonMember::range_check, KnownBounds>(
180  ParseState::exec_tag, parse_state ) );
181  } else {
182  if constexpr( JsonMember::literal_as_string !=
184  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
185  parse_state );
186  if constexpr( not ParseState::is_zero_terminated_string ) {
187  daw_json_assert_weak( parse_state.has_more( ),
188  ErrorReason::UnexpectedEndOfData,
189  parse_state );
190  }
191  } else if constexpr( not ParseState::is_zero_terminated_string ) {
192  daw_json_assert_weak( parse_state.has_more( ),
193  ErrorReason::UnexpectedEndOfData,
194  parse_state );
195  }
198  ErrorReason::InvalidNumber, parse_state );
199  auto result = construct_value(
200  template_args<json_result<JsonMember>, constructor_t>, parse_state,
201  unsigned_parser<element_t, JsonMember::range_check, KnownBounds>(
202  ParseState::exec_tag, parse_state ) );
203  if constexpr( JsonMember::literal_as_string !=
205  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
206  parse_state );
207  if constexpr( not ParseState::is_zero_terminated_string ) {
208  daw_json_assert_weak( parse_state.has_more( ),
209  ErrorReason::UnexpectedEndOfData,
210  parse_state );
211  }
212  }
215  ErrorReason::InvalidEndOfValue, parse_state );
216  return result;
217  }
218  }
219 
220  template<typename JsonMember, bool KnownBounds, typename ParseState>
221  [[nodiscard,
222  maybe_unused]] DAW_ATTRIB_INLINE inline constexpr json_result<JsonMember>
224 
225  using constructor_t = typename JsonMember::constructor_t;
226  if constexpr( KnownBounds ) {
227  // skip_value will leave a null parse_state
228  if( parse_state.is_null( ) ) {
229  if constexpr( JsonMember::nullable == JsonNullable::Nullable ) {
230  return construct_value(
231  template_args<json_result<JsonMember>, constructor_t>,
232  parse_state );
233  } else {
234  daw_json_error( missing_member(
235  std::string_view( std::data( JsonMember::name ),
236  std::size( JsonMember::name ) ) ) );
237  }
238  }
239  return parse_value<JsonMember, true>(
241  } else if constexpr( ParseState::is_unchecked_input ) {
242  if( not parse_state.has_more( ) ) {
243  if constexpr( JsonMember::nullable == JsonNullable::Nullable ) {
244  return construct_value(
245  template_args<json_result<JsonMember>, constructor_t>,
246  parse_state );
247  } else {
248  daw_json_error( missing_member(
249  std::string_view( std::data( JsonMember::name ),
250  std::size( JsonMember::name ) ) ) );
251  }
252  } else if( parse_state.front( ) == 'n' ) {
253  parse_state.remove_prefix( 4 );
254  parse_state.trim_left_unchecked( );
255  parse_state.remove_prefix( );
256  return construct_value(
257  template_args<json_result<JsonMember>, constructor_t>,
258  parse_state );
259  }
260  return parse_value<JsonMember>(
262  } else {
263  if( parse_state.starts_with( "null" ) ) {
264  parse_state.remove_prefix( 4 );
267  ErrorReason::InvalidLiteral, parse_state );
268  parse_state.trim_left_checked( );
269  return construct_value(
270  template_args<json_result<JsonMember>, constructor_t>,
271  parse_state );
272  }
273  return parse_value<JsonMember>(
275  }
276  }
277 
278  template<typename JsonMember, bool KnownBounds, typename ParseState>
279  [[nodiscard,
280  maybe_unused]] DAW_ATTRIB_INLINE inline constexpr json_result<JsonMember>
282  using constructor_t = typename JsonMember::constructor_t;
283 
284  if constexpr( KnownBounds ) {
285  // We have already checked if it is a true/false
286  if constexpr( ParseState::is_unchecked_input ) {
287  return static_cast<bool>( parse_state.counter );
288  } else {
289  switch( parse_state.front( ) ) {
290  case 't':
291  return construct_value(
292  template_args<json_result<JsonMember>, constructor_t>,
293  parse_state, true );
294  case 'f':
295  return construct_value(
296  template_args<json_result<JsonMember>, constructor_t>,
297  parse_state, false );
298  }
299  daw_json_error( ErrorReason::InvalidLiteral, parse_state );
300  }
301  } else {
302  // Beginning quotes
303  if constexpr( JsonMember::literal_as_string !=
305  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
306  parse_state );
307  }
308  bool result = false;
309  if constexpr( ParseState::is_unchecked_input ) {
310  if( parse_state.front( ) == 't' ) /* true */ {
311  result = true;
312  parse_state.remove_prefix( 4 );
313  } else /* false */ {
314  parse_state.remove_prefix( 5 );
315  }
316  } else {
317  if( parse_state.starts_with( "true" ) ) {
318  parse_state.remove_prefix( 4 );
319  result = true;
320  } else if( parse_state.starts_with( "false" ) ) {
321  parse_state.remove_prefix( 5 );
322  } else {
323  daw_json_error( ErrorReason::InvalidLiteral, parse_state );
324  }
325  }
326  // Trailing quotes
327  if constexpr( JsonMember::literal_as_string !=
329  skip_quote_when_literal_as_string<JsonMember::literal_as_string>(
330  parse_state );
331  }
332  parse_state.trim_left( );
335  ErrorReason::InvalidEndOfValue, parse_state );
336  return construct_value(
337  template_args<json_result<JsonMember>, constructor_t>, parse_state,
338  result );
339  }
340  }
341 
342  template<typename JsonMember, bool KnownBounds, typename ParseState>
343  [[nodiscard,
344  maybe_unused]] DAW_ATTRIB_INLINE inline constexpr json_result<JsonMember>
345  parse_value( ParseState &parse_state,
347 
348  using constructor_t = typename JsonMember::constructor_t;
349  if constexpr( KnownBounds ) {
350  if constexpr( JsonMember::empty_is_null == EmptyStringNull::yes ) {
351  if( parse_state.empty( ) ) {
352  return construct_value(
353  template_args<json_result<JsonMember>, constructor_t>,
354  parse_state );
355  }
356  }
357  return construct_value(
358  template_args<json_result<JsonMember>, constructor_t>, parse_state,
359  std::data( parse_state ), std::size( parse_state ) );
360  } else {
361  if constexpr( JsonMember::allow_escape_character ==
363  auto const str = skip_string( parse_state );
364  if constexpr( JsonMember::empty_is_null == EmptyStringNull::yes ) {
365  if( str.empty( ) ) {
366  return construct_value(
367  template_args<json_result<JsonMember>, constructor_t>,
368  parse_state );
369  }
370  }
371  return construct_value(
372  template_args<json_result<JsonMember>, constructor_t>,
373  parse_state, std::data( str ), std::size( str ) );
374  } else {
375  parse_state.remove_prefix( );
376 
377  char const *const first = parse_state.first;
378  parse_state.template move_to_next_of<'"'>( );
379  char const *const last = parse_state.first;
380  parse_state.remove_prefix( );
381  if constexpr( JsonMember::empty_is_null == EmptyStringNull::yes ) {
382  if( first == last ) {
383  return construct_value(
384  template_args<json_result<JsonMember>, constructor_t>,
385  parse_state );
386  }
387  return construct_value(
388  template_args<json_result<JsonMember>, constructor_t>,
389  parse_state, first, static_cast<std::size_t>( last - first ) );
390  } else {
391  return construct_value(
392  template_args<json_result<JsonMember>, constructor_t>,
393  parse_state, first, static_cast<std::size_t>( last - first ) );
394  }
395  }
396  }
397  }
398 
399  /***
400  * We know that we are constructing a std::string or
401  * std::optional<std::string> We can take advantage of this and reduce
402  * the allocator time by presizing the string up front and then using a
403  * pointer to the data( ).
404  */
405  template<typename JsonMember>
407  : std::disjunction<
408  can_single_allocation_string<json_result<JsonMember>>,
409  can_single_allocation_string<json_base_type<JsonMember>>> {};
410 
411  template<typename T>
412  using json_member_constructor_t = typename T::constructor_t;
413 
414  template<typename T>
415  using json_member_parse_to_t = typename T::parse_to_t;
416 
417  template<typename T>
418  inline constexpr bool has_json_member_constructor_v =
419  daw::is_detected<json_member_constructor_t, T>::value;
420 
421  template<typename T>
422  inline constexpr bool has_json_member_parse_to_v =
423  daw::is_detected<json_member_constructor_t, T>::value;
424 
425  template<typename JsonMember, bool KnownBounds, typename ParseState>
426  [[nodiscard, maybe_unused]] constexpr json_result<JsonMember>
427  parse_value( ParseState &parse_state,
429  static_assert( has_json_member_constructor_v<JsonMember> );
430  static_assert( has_json_member_parse_to_v<JsonMember> );
431 
432  using constructor_t = typename JsonMember::constructor_t;
434  constexpr bool AllowHighEightbits =
435  JsonMember::eight_bit_mode != EightBitModes::DisallowHigh;
436  auto parse_state2 =
437  KnownBounds ? parse_state : skip_string( parse_state );
438  // FIXME this needs std::string, fix
439  if( not AllowHighEightbits or needs_slow_path( parse_state2 ) ) {
440  // There are escapes in the string
441  return parse_string_known_stdstring<AllowHighEightbits, JsonMember,
442  true>( parse_state2 );
443  }
444  // There are no escapes in the string, we can just use the ptr/size
445  // ctor
446  return construct_value(
447  template_args<json_result<JsonMember>, constructor_t>, parse_state,
448  std::data( parse_state2 ), daw::data_end( parse_state2 ) );
449  } else {
450  auto parse_state2 =
451  KnownBounds ? parse_state : skip_string( parse_state );
452  constexpr bool AllowHighEightbits =
453  JsonMember::eight_bit_mode != EightBitModes::DisallowHigh;
454  if( not AllowHighEightbits or needs_slow_path( parse_state2 ) ) {
455  // There are escapes in the string
456  return parse_string_known_stdstring<AllowHighEightbits, JsonMember,
457  true>( parse_state2 );
458  }
459  // There are no escapes in the string, we can just use the ptr/size
460  // ctor
461  return construct_value(
462  template_args<json_result<JsonMember>, constructor_t>, parse_state,
463  std::data( parse_state2 ), daw::data_end( parse_state2 ) );
464  }
465  }
466 
467  template<typename JsonMember, bool KnownBounds, typename ParseState>
468  [[nodiscard,
469  maybe_unused]] DAW_ATTRIB_INLINE inline constexpr json_result<JsonMember>
471 
472  daw_json_assert_weak( parse_state.has_more( ),
473  ErrorReason::UnexpectedEndOfData, parse_state );
474  auto str = KnownBounds ? parse_state : skip_string( parse_state );
475  using constructor_t = typename JsonMember::constructor_t;
476  return construct_value(
477  template_args<json_result<JsonMember>, constructor_t>, parse_state,
478  std::data( str ), std::size( str ) );
479  }
480 
481  template<typename JsonMember, bool KnownBounds, typename ParseState>
482  [[nodiscard, maybe_unused]] constexpr json_result<JsonMember>
484 
485  auto const str = [&] {
486  if constexpr( JsonMember::custom_json_type ==
488  if constexpr( KnownBounds ) {
489  return parse_state;
490  } else {
491  return skip_string( parse_state );
492  }
493  } else if constexpr( JsonMember::custom_json_type ==
495  return KnownBounds ? parse_state : skip_literal( parse_state );
496  } else {
497  static_assert( JsonMember::custom_json_type ==
499  // If we are a root object, parse_state will have the quotes and
500  // KnownBounds cannot be true This tells us that there is an array
501  // start '[' or a member name previous to current position
502  if constexpr( KnownBounds ) {
503  auto result = parse_state;
504  if( *( result.first - 1 ) == '"' ) {
505  result.first--;
506  }
507  return result;
508  } else {
509  if( parse_state.front( ) == '"' ) {
510  auto result = skip_string( parse_state );
511  result.first--;
512  return result;
513  }
514  return skip_value( parse_state );
515  }
516  }
517  }( );
519  str.has_more( ) and not( str.front( ) == '[' or str.front( ) == '{' ),
520  ErrorReason::InvalidStartOfValue, str );
521  using constructor_t = typename JsonMember::from_converter_t;
522  return construct_value(
523  template_args<json_result<JsonMember>, constructor_t>, parse_state,
524  std::string_view( std::data( str ), std::size( str ) ) );
525  }
526 
527  inline namespace {
528  template<typename ParseState>
529  struct trim_left_cleanup {
530  ParseState &parse_state;
531 
532  CPP20CONSTEXPR ~trim_left_cleanup( ) noexcept( false ) {
533 #if defined( DAW_HAS_CONSTEXPR_SCOPE_GUARD )
534  if( DAW_IS_CONSTANT_EVALUATED( ) ) {
535  parse_state.trim_left_checked( );
536  } else {
537 #endif
538  if( std::uncaught_exceptions( ) == 0 ) {
539  parse_state.trim_left_checked( );
540  }
541 #if defined( DAW_HAS_CONSTEXPR_SCOPE_GUARD )
542  }
543 #endif
544  }
545  };
546  } // namespace
547 
548  template<typename JsonMember, bool KnownBounds, typename ParseState>
549  [[nodiscard,
550  maybe_unused]] DAW_ATTRIB_FLATTEN constexpr json_result<JsonMember>
552 
553  using element_t = typename JsonMember::base_type;
554  daw_json_assert_weak( parse_state.has_more( ),
555  ErrorReason::UnexpectedEndOfData, parse_state );
556 
557  if constexpr( is_guaranteed_rvo_v<ParseState> ) {
558  // This relies on non-trivial dtor's being allowed. So C++20
559  // constexpr or not in a constant expression. It does allow for
560  // construction of classes without move/copy special members
561  if constexpr( not KnownBounds ) {
562  auto const run_after_parse =
563  trim_left_cleanup<ParseState>{ parse_state };
564  (void)run_after_parse;
566  parse_state, template_arg<JsonMember> );
567  } else {
569  parse_state, template_arg<JsonMember> );
570  }
571  } else {
572  if constexpr( KnownBounds ) {
574  parse_state, template_arg<JsonMember> );
575  } else {
576  if constexpr( force_aggregate_construction_v<element_t> ) {
577  auto const run_after_parse =
578  trim_left_cleanup<ParseState>{ parse_state };
579  (void)run_after_parse;
581  parse_state, template_arg<JsonMember> );
582  } else {
583  auto result =
585  parse_state, template_arg<JsonMember> );
586  // TODO: make trim_left
587  parse_state.trim_left_checked( );
588  return result;
589  }
590  }
591  }
592  }
593 
602  template<typename JsonMember, bool KnownBounds, typename ParseState>
603  [[nodiscard,
604  maybe_unused]] DAW_ATTRIB_FLATTEN constexpr json_result<JsonMember>
605  parse_value( ParseState &parse_state,
607 
608  static_assert( JsonMember::expected_type == JsonParseTypes::KeyValue,
609  "Expected a json_key_value" );
610  daw_json_assert_weak( parse_state.is_opening_brace_checked( ),
611  ErrorReason::ExpectedKeyValueToStartWithBrace,
612  parse_state );
613 
614  parse_state.remove_prefix( );
615  parse_state.trim_left( );
616 
617 #if defined( __GNUC__ ) or defined( __clang__ )
618  using iter_t =
620 #else
621  using iter_t =
623 #endif
624  using constructor_t = typename JsonMember::constructor_t;
625  return construct_value(
626  template_args<json_result<JsonMember>, constructor_t>, parse_state,
627  iter_t( parse_state ), iter_t( ) );
628  }
629 
638  template<typename JsonMember, bool KnownBounds, typename ParseState>
639  [[nodiscard,
640  maybe_unused]] DAW_ATTRIB_FLATTEN constexpr json_result<JsonMember>
641  parse_value( ParseState &parse_state,
643 
644  static_assert( JsonMember::expected_type ==
646  "Expected a json_key_value" );
648  parse_state.is_opening_bracket_checked( ),
649  ErrorReason::ExpectedKeyValueArrayToStartWithBracket, parse_state );
650 
651  parse_state.remove_prefix( );
652 
653  using iter_t =
655  using constructor_t = typename JsonMember::constructor_t;
656  return construct_value(
657  template_args<json_result<JsonMember>, constructor_t>, parse_state,
658  iter_t( parse_state ), iter_t( ) );
659  }
660 
661  template<typename JsonMember, bool KnownBounds, typename ParseState>
662  [[nodiscard,
663  maybe_unused]] DAW_ATTRIB_FLATTEN constexpr json_result<JsonMember>
665  parse_state.trim_left( );
666  daw_json_assert_weak( parse_state.is_opening_bracket_checked( ),
667  ErrorReason::InvalidArrayStart, parse_state );
668  parse_state.remove_prefix( );
669  parse_state.trim_left_unchecked( );
670  // TODO: add parse option to disable random access iterators. This is
671  // coding to the implementations
672 
673  using iterator_t =
675  using constructor_t = typename JsonMember::constructor_t;
676  return construct_value(
677  template_args<json_result<JsonMember>, constructor_t>, parse_state,
678  iterator_t( parse_state ), iterator_t( ) );
679  }
680 
681  template<typename JsonMember, bool KnownBounds, typename ParseState>
682  [[nodiscard,
683  maybe_unused]] DAW_ATTRIB_FLATTEN constexpr json_result<JsonMember>
684  parse_value( ParseState &parse_state,
686 
687  using size_member = dependent_member_t<JsonMember>;
688 
689  auto [is_found, parse_state2] = find_range<ParseState>(
690  ParseState( parse_state.class_first, parse_state.last ),
691  size_member::name );
692 
693  daw_json_assert( is_found, ErrorReason::TagMemberNotFound,
694  parse_state );
695  auto const sz = parse_value<size_member>(
696  parse_state2, ParseTag<size_member::expected_type>{ } );
697 
698  if constexpr( KnownBounds and ParseState::is_unchecked_input ) {
699  // We have the requested size and the actual size. Let's see if they
700  // match
701  auto cnt = static_cast<std::ptrdiff_t>( parse_state.counter );
702  daw_json_assert( sz >= 0 and ( cnt < 0 or parse_state.counter == sz ),
703  ErrorReason::NumberOutOfRange, parse_state );
704  }
705  parse_state.trim_left( );
706  daw_json_assert_weak( parse_state.is_opening_bracket_checked( ),
707  ErrorReason::InvalidArrayStart, parse_state );
708  parse_state.remove_prefix( );
709  parse_state.trim_left_unchecked( );
710  // TODO: add parse option to disable random access iterators. This is
711  // coding to the implementations
712  using iterator_t =
714  using constructor_t = typename JsonMember::constructor_t;
715  return construct_value(
716  template_args<json_result<JsonMember>, constructor_t>, parse_state,
717  iterator_t( parse_state ), iterator_t( ),
718  static_cast<std::size_t>( sz ) );
719  }
720 
721  template<JsonBaseParseTypes BPT, typename JsonMembers,
722  typename ParseState>
723  [[nodiscard,
724  maybe_unused]] DAW_ATTRIB_FLATTEN constexpr json_result<JsonMembers>
726  using element_t = typename JsonMembers::json_elements;
727  constexpr std::size_t idx =
728  JsonMembers::base_map::base_map[static_cast<int_fast8_t>( BPT )];
729 
730  if constexpr( idx < pack_size_v<typename element_t::element_map_t> ) {
731  using JsonMember =
732  pack_element_t<idx, typename element_t::element_map_t>;
733  return parse_value<JsonMember>(
735  } else {
736  if constexpr( ParseState::is_unchecked_input ) {
737  DAW_UNREACHABLE( );
738  } else {
739  daw_json_error( ErrorReason::UnexpectedJSONVariantType );
740  }
741  }
742  }
743 
744  template<typename JsonMember, bool /*KnownBounds*/, typename ParseState>
745  [[nodiscard,
746  maybe_unused]] DAW_ATTRIB_INLINE constexpr json_result<JsonMember>
747  parse_value( ParseState &parse_state,
749  switch( parse_state.front( ) ) {
750  case '{':
751  return parse_variant_value<JsonBaseParseTypes::Class, JsonMember>(
752  parse_state );
753  case '[':
754  return parse_variant_value<JsonBaseParseTypes::Array, JsonMember>(
755  parse_state );
756  case 't':
757  case 'f':
758  return parse_variant_value<JsonBaseParseTypes::Bool, JsonMember>(
759  parse_state );
760  case '"':
761  return parse_variant_value<JsonBaseParseTypes::String, JsonMember>(
762  parse_state );
763  case '0':
764  case '1':
765  case '2':
766  case '3':
767  case '4':
768  case '5':
769  case '6':
770  case '7':
771  case '8':
772  case '9':
773  case '+':
774  case '-':
775  return parse_variant_value<JsonBaseParseTypes::Number, JsonMember>(
776  parse_state );
777  }
778  if constexpr( ParseState::is_unchecked_input ) {
779  DAW_UNREACHABLE( );
780  } else {
781  daw_json_error( ErrorReason::InvalidStartOfValue, parse_state );
782  }
783  }
784 
785  template<typename Result, typename TypeList, std::size_t pos = 0,
786  typename ParseState>
787  DAW_ATTRIB_FLATINLINE constexpr Result
788  parse_visit( std::size_t idx, ParseState &parse_state ) {
789  if( idx == pos ) {
790  using JsonMember = pack_element_t<pos, TypeList>;
791  if constexpr( std::is_same_v<json_result<JsonMember>, Result> ) {
792  return parse_value<JsonMember>(
794  } else {
795  return { parse_value<JsonMember>(
797  }
798  }
799  if constexpr( pos + 1 < pack_size_v<TypeList> ) {
800  return parse_visit<Result, TypeList, pos + 1>( idx, parse_state );
801  } else {
802  if constexpr( ParseState::is_unchecked_input ) {
803  DAW_UNREACHABLE( );
804  } else {
805  daw_json_error( ErrorReason::MissingMemberNameOrEndOfClass,
806  parse_state );
807  }
808  }
809  }
810 
811  template<typename JsonMember, bool /*KnownBounds*/, typename ParseState>
812  [[nodiscard,
813  maybe_unused]] DAW_ATTRIB_INLINE inline constexpr json_result<JsonMember>
814  parse_value( ParseState &parse_state,
816  using tag_member = dependent_member_t<JsonMember>;
817  auto [is_found, parse_state2] = find_range<ParseState>(
818  ParseState( parse_state.class_first, parse_state.last ),
819  tag_member::name );
820 
821  daw_json_assert( is_found, ErrorReason::TagMemberNotFound,
822  parse_state );
823  auto index = typename JsonMember::switcher{ }( parse_value<tag_member>(
824  parse_state2, ParseTag<tag_member::expected_type>{ } ) );
825 
826  return parse_visit<json_result<JsonMember>,
827  typename JsonMember::json_elements::element_map_t>(
828  index, parse_state );
829  }
830 
831  template<typename JsonMember, bool KnownBounds, std::size_t N,
832  typename ParseState, bool B>
833  [[nodiscard]] constexpr json_result<JsonMember>
834  parse_value( ParseState &parse_state,
836  using tag_member = dependent_member_t<JsonMember>;
837  auto [is_found, parse_state2] = find_range<ParseState>(
838  ParseState( parse_state.class_first, parse_state.last ),
839  tag_member::name );
840 
841  daw_json_assert( is_found, ErrorReason::TagMemberNotFound,
842  parse_state );
843  auto index = typename JsonMember::switcher{ }( parse_value<tag_member>(
844  parse_state2, ParseTag<tag_member::expected_type>{ } ) );
845 
846  return parse_visit<json_result<JsonMember>,
847  typename JsonMember::json_elements::element_map_t>(
848  index, parse_state );
849  }
850 
851  template<bool AllMembersMustExist, typename ParseState>
853  ParseState &parse_state;
854 
855  DAW_ATTRIB_INLINE
856  CPP20CONSTEXPR inline ~ordered_class_cleanup( ) noexcept( false ) {
857 #if defined( DAW_HAS_CONSTEXPR_SCOPE_GUARD )
858  if( DAW_IS_CONSTANT_EVALUATED( ) ) {
859  if constexpr( AllMembersMustExist ) {
860  parse_state.trim_left( );
861  daw_json_assert_weak( parse_state.front( ) == ']',
862  ErrorReason::UnknownMember, parse_state );
863  parse_state.remove_prefix( );
864  parse_state.trim_left_checked( );
865  } else {
866  (void)parse_state.skip_array( );
867  }
868  } else {
869 #endif
870  if( std::uncaught_exceptions( ) == 0 ) {
871  if constexpr( AllMembersMustExist ) {
872  parse_state.trim_left( );
873  daw_json_assert_weak( parse_state.front( ) == ']',
874  ErrorReason::UnknownMember, parse_state );
875  parse_state.remove_prefix( );
876  parse_state.trim_left_checked( );
877  } else {
878  (void)parse_state.skip_array( );
879  }
880  }
881 #if defined( DAW_HAS_CONSTEXPR_SCOPE_GUARD )
882  }
883 #endif
884  }
885  };
886 
887  template<typename JsonMember, bool KnownBounds, typename ParseState,
888  std::size_t... Is>
889  DAW_ATTRIB_FLATINLINE constexpr json_result<JsonMember>
890  parse_tuple_value( ParseState &parse_state, std::index_sequence<Is...> ) {
891  parse_state.trim_left( );
892  daw_json_assert_weak( parse_state.is_opening_bracket_checked( ),
893  ErrorReason::InvalidArrayStart, parse_state );
894  parse_state.remove_prefix( );
895 
896  using tuple_t = typename JsonMember::base_type;
897 
898  auto const parse_value_help = [&]( auto Idx ) {
899  parse_state.move_next_member_or_end( );
900  constexpr std::size_t index = decltype( Idx )::value;
901  using element_pack = tuple_elements_pack<tuple_t>;
902  using T =
903 #if defined( _MSC_VER ) and not defined( __clang__ )
904  // Bug in MSVC refuses to work here with typename
906 #else
908 #endif
909  return parse_value<T>( parse_state, ParseTag<T::expected_type>{ } );
910  };
911 
912  static_assert( is_a_json_type<JsonMember>::value );
913  using Constructor = typename JsonMember::constructor_t;
914 
915  static_assert(
916  std::is_invocable<Constructor, decltype( parse_value_help(
917  std::integral_constant<
918  std::size_t, Is>{ } ) )...>::value,
919  "Supplied types cannot be used for construction of this type" );
920 
921  parse_state.trim_left( );
922 
923  if constexpr( is_guaranteed_rvo_v<ParseState> ) {
924  auto const run_after_parse = ordered_class_cleanup<
925  json_details::all_json_members_must_exist_v<JsonMember, ParseState>,
926  ParseState>{ parse_state };
927  (void)run_after_parse;
928  if constexpr( force_aggregate_construction_v<JsonMember> ) {
929  return tuple_t{ parse_value_help(
930  std::integral_constant<std::size_t, Is>{ } )... };
931  } else {
932  return construct_value_tp<tuple_t, Constructor>(
933  parse_state,
934  fwd_pack{ parse_value_help(
935  std::integral_constant<std::size_t, Is>{ } )... } );
936  }
937  } else {
938  auto result = [&] {
939  if constexpr( force_aggregate_construction_v<JsonMember> ) {
940  return tuple_t{ parse_value_help(
941  std::integral_constant<std::size_t, Is>{ } )... };
942  } else {
943  return construct_value_tp<tuple_t, Constructor>(
944  parse_state,
945  fwd_pack{ parse_value_help(
946  std::integral_constant<std::size_t, Is>{ } )... } );
947  }
948  }( );
950  tuple_t, ParseState> ) {
951  parse_state.trim_left( );
952  daw_json_assert_weak( parse_state.front( ) == ']',
953  ErrorReason::UnknownMember, parse_state );
954  parse_state.remove_prefix( );
955  parse_state.trim_left( );
956  } else {
957  (void)parse_state.skip_array( );
958  }
959  return result;
960  }
961  }
962 
963  template<typename JsonMember, bool KnownBounds, typename ParseState>
964  DAW_ATTRIB_FLATINLINE constexpr json_result<JsonMember>
966  using tuple_t = typename JsonMember::base_type;
967  using element_pack = tuple_elements_pack<tuple_t>;
968 
969  return parse_tuple_value<JsonMember, KnownBounds>(
970  parse_state, std::make_index_sequence<element_pack::size>{ } );
971  }
972 
973  template<typename JsonMember, bool KnownBounds, typename ParseState>
974  DAW_ATTRIB_FLATINLINE constexpr json_result<JsonMember>
975  parse_value( ParseState &parse_state,
977  using constructor_t = typename JsonMember::constructor_t;
978  if constexpr( KnownBounds ) {
979  return construct_value(
980  template_args<json_result<JsonMember>, constructor_t>, parse_state,
981  std::data( parse_state ), std::size( parse_state ) );
982  } else {
983  auto value_parse_state = skip_value( parse_state );
984  return construct_value(
985  template_args<json_result<JsonMember>, constructor_t>, parse_state,
986  std::data( value_parse_state ), std::size( value_parse_state ) );
987  }
988  }
989 
990  template<std::size_t N, typename JsonClass, bool KnownBounds,
991  typename... JsonClasses, typename ParseState>
992  DAW_ATTRIB_FLATTEN constexpr json_result<JsonClass>
993  parse_nth_class( std::size_t idx, ParseState &parse_state ) {
994  // Precondition of caller to verify/ensure.
995  DAW_ASSUME( idx < sizeof...( JsonClasses ) );
996  using T = typename JsonClass::base_type;
997  using Constructor = typename JsonClass::constructor_t;
998  if constexpr( sizeof...( JsonClasses ) >= N + 8 ) {
999  switch( idx ) {
1000  case N + 0: {
1001  using cur_json_class_t = traits::nth_element<N + 0, JsonClasses...>;
1002  return construct_value(
1003  template_args<T, Constructor>, parse_state,
1004  parse_value<cur_json_class_t>(
1005  parse_state,
1007  }
1008  case N + 1: {
1009  using cur_json_class_t = traits::nth_element<N + 1, JsonClasses...>;
1010  return construct_value(
1011  template_args<T, Constructor>, parse_state,
1012  parse_value<cur_json_class_t>(
1013  parse_state,
1015  }
1016  case N + 2: {
1017  using cur_json_class_t = traits::nth_element<N + 2, JsonClasses...>;
1018  return construct_value(
1019  template_args<T, Constructor>, parse_state,
1020  parse_value<cur_json_class_t>(
1021  parse_state,
1023  }
1024  case N + 3: {
1025  using cur_json_class_t = traits::nth_element<N + 3, JsonClasses...>;
1026  return construct_value(
1027  template_args<T, Constructor>, parse_state,
1028  parse_value<cur_json_class_t>(
1029  parse_state,
1031  }
1032  case N + 4: {
1033  using cur_json_class_t = traits::nth_element<N + 4, JsonClasses...>;
1034  return construct_value(
1035  template_args<T, Constructor>, parse_state,
1036  parse_value<cur_json_class_t>(
1037  parse_state,
1039  }
1040  case N + 5: {
1041  using cur_json_class_t = traits::nth_element<N + 5, JsonClasses...>;
1042  return construct_value(
1043  template_args<T, Constructor>, parse_state,
1044  parse_value<cur_json_class_t>(
1045  parse_state,
1047  }
1048  case N + 6: {
1049  using cur_json_class_t = traits::nth_element<N + 6, JsonClasses...>;
1050  return construct_value(
1051  template_args<T, Constructor>, parse_state,
1052  parse_value<cur_json_class_t>(
1053  parse_state,
1055  }
1056  case N + 7: {
1057  using cur_json_class_t = traits::nth_element<N + 7, JsonClasses...>;
1058  return construct_value(
1059  template_args<T, Constructor>, parse_state,
1060  parse_value<cur_json_class_t>(
1061  parse_state,
1063  }
1064  default:
1065  if constexpr( sizeof...( JsonClasses ) >= N + 8 ) {
1066  return parse_nth_class<N + 8, JsonClass, KnownBounds,
1067  JsonClasses...>( idx, parse_state );
1068  } else {
1069  DAW_UNREACHABLE( );
1070  }
1071  }
1072  } else if constexpr( sizeof...( JsonClasses ) == N + 7 ) {
1073  switch( idx ) {
1074  case N + 0: {
1075  using cur_json_class_t = traits::nth_element<N + 0, JsonClasses...>;
1076  return construct_value(
1077  template_args<T, Constructor>, parse_state,
1078  parse_value<cur_json_class_t>(
1079  parse_state,
1081  }
1082  case N + 1: {
1083  using cur_json_class_t = traits::nth_element<N + 1, JsonClasses...>;
1084  return construct_value(
1085  template_args<T, Constructor>, parse_state,
1086  parse_value<cur_json_class_t>(
1087  parse_state,
1089  }
1090  case N + 2: {
1091  using cur_json_class_t = traits::nth_element<N + 2, JsonClasses...>;
1092  return construct_value(
1093  template_args<T, Constructor>, parse_state,
1094  parse_value<cur_json_class_t>(
1095  parse_state,
1097  }
1098  case N + 3: {
1099  using cur_json_class_t = traits::nth_element<N + 3, JsonClasses...>;
1100  return construct_value(
1101  template_args<T, Constructor>, parse_state,
1102  parse_value<cur_json_class_t>(
1103  parse_state,
1105  }
1106  case N + 4: {
1107  using cur_json_class_t = traits::nth_element<N + 4, JsonClasses...>;
1108  return construct_value(
1109  template_args<T, Constructor>, parse_state,
1110  parse_value<cur_json_class_t>(
1111  parse_state,
1113  }
1114  case N + 5: {
1115  using cur_json_class_t = traits::nth_element<N + 5, JsonClasses...>;
1116  return construct_value(
1117  template_args<T, Constructor>, parse_state,
1118  parse_value<cur_json_class_t>(
1119  parse_state,
1121  }
1122  default: {
1123  DAW_ASSUME( idx == N + 6 );
1124  using cur_json_class_t = traits::nth_element<N + 6, JsonClasses...>;
1125  return construct_value(
1126  template_args<T, Constructor>, parse_state,
1127  parse_value<cur_json_class_t>(
1128  parse_state,
1130  }
1131  }
1132  } else if constexpr( sizeof...( JsonClasses ) == N + 6 ) {
1133  switch( idx ) {
1134  case N + 0: {
1135  using cur_json_class_t = traits::nth_element<N + 0, JsonClasses...>;
1136  return construct_value(
1137  template_args<T, Constructor>, parse_state,
1138  parse_value<cur_json_class_t>(
1139  parse_state,
1141  }
1142  case N + 1: {
1143  using cur_json_class_t = traits::nth_element<N + 1, JsonClasses...>;
1144  return construct_value(
1145  template_args<T, Constructor>, parse_state,
1146  parse_value<cur_json_class_t>(
1147  parse_state,
1149  }
1150  case N + 2: {
1151  using cur_json_class_t = traits::nth_element<N + 2, JsonClasses...>;
1152  return construct_value(
1153  template_args<T, Constructor>, parse_state,
1154  parse_value<cur_json_class_t>(
1155  parse_state,
1157  }
1158  case N + 3: {
1159  using cur_json_class_t = traits::nth_element<N + 3, JsonClasses...>;
1160  return construct_value(
1161  template_args<T, Constructor>, parse_state,
1162  parse_value<cur_json_class_t>(
1163  parse_state,
1165  }
1166  case N + 4: {
1167  using cur_json_class_t = traits::nth_element<N + 4, JsonClasses...>;
1168  return construct_value(
1169  template_args<T, Constructor>, parse_state,
1170  parse_value<cur_json_class_t>(
1171  parse_state,
1173  }
1174  default: {
1175  DAW_ASSUME( idx == N + 5 );
1176  using cur_json_class_t = traits::nth_element<N + 5, JsonClasses...>;
1177  return construct_value(
1178  template_args<T, Constructor>, parse_state,
1179  parse_value<cur_json_class_t>(
1180  parse_state,
1182  }
1183  }
1184  } else if constexpr( sizeof...( JsonClasses ) == N + 5 ) {
1185  switch( idx ) {
1186  case N + 0: {
1187  using cur_json_class_t = traits::nth_element<N + 0, JsonClasses...>;
1188  return construct_value(
1189  template_args<T, Constructor>, parse_state,
1190  parse_value<cur_json_class_t>(
1191  parse_state,
1193  }
1194  case N + 1: {
1195  using cur_json_class_t = traits::nth_element<N + 1, JsonClasses...>;
1196  return construct_value(
1197  template_args<T, Constructor>, parse_state,
1198  parse_value<cur_json_class_t>(
1199  parse_state,
1201  }
1202  case N + 2: {
1203  using cur_json_class_t = traits::nth_element<N + 2, JsonClasses...>;
1204  return construct_value(
1205  template_args<T, Constructor>, parse_state,
1206  parse_value<cur_json_class_t>(
1207  parse_state,
1209  }
1210  case N + 3: {
1211  using cur_json_class_t = traits::nth_element<N + 3, JsonClasses...>;
1212  return construct_value(
1213  template_args<T, Constructor>, parse_state,
1214  parse_value<cur_json_class_t>(
1215  parse_state,
1217  }
1218  default: {
1219  DAW_ASSUME( idx == N + 4 );
1220  using cur_json_class_t = traits::nth_element<N + 4, JsonClasses...>;
1221  return construct_value(
1222  template_args<T, Constructor>, parse_state,
1223  parse_value<cur_json_class_t>(
1224  parse_state,
1226  }
1227  }
1228  } else if constexpr( sizeof...( JsonClasses ) == N + 4 ) {
1229  switch( idx ) {
1230  case N + 0: {
1231  using cur_json_class_t = traits::nth_element<N + 0, JsonClasses...>;
1232  return construct_value(
1233  template_args<T, Constructor>, parse_state,
1234  parse_value<cur_json_class_t>(
1235  parse_state,
1237  }
1238  case N + 1: {
1239  using cur_json_class_t = traits::nth_element<N + 1, JsonClasses...>;
1240  return construct_value(
1241  template_args<T, Constructor>, parse_state,
1242  parse_value<cur_json_class_t>(
1243  parse_state,
1245  }
1246  case N + 2: {
1247  using cur_json_class_t = traits::nth_element<N + 2, JsonClasses...>;
1248  return construct_value(
1249  template_args<T, Constructor>, parse_state,
1250  parse_value<cur_json_class_t>(
1251  parse_state,
1253  }
1254  default: {
1255  DAW_ASSUME( idx == N + 3 );
1256  using cur_json_class_t = traits::nth_element<N + 3, JsonClasses...>;
1257  return construct_value(
1258  template_args<T, Constructor>, parse_state,
1259  parse_value<cur_json_class_t>(
1260  parse_state,
1262  }
1263  }
1264  } else if constexpr( sizeof...( JsonClasses ) == N + 3 ) {
1265  switch( idx ) {
1266  case N + 0: {
1267  using cur_json_class_t = traits::nth_element<N + 0, JsonClasses...>;
1268  return construct_value(
1269  template_args<T, Constructor>, parse_state,
1270  parse_value<cur_json_class_t>(
1271  parse_state,
1273  }
1274  case N + 1: {
1275  using cur_json_class_t = traits::nth_element<N + 1, JsonClasses...>;
1276  return construct_value(
1277  template_args<T, Constructor>, parse_state,
1278  parse_value<cur_json_class_t>(
1279  parse_state,
1281  }
1282  default: {
1283  DAW_ASSUME( idx == N + 2 );
1284  using cur_json_class_t = traits::nth_element<N + 2, JsonClasses...>;
1285  return construct_value(
1286  template_args<T, Constructor>, parse_state,
1287  parse_value<cur_json_class_t>(
1288  parse_state,
1290  }
1291  }
1292  } else if constexpr( sizeof...( JsonClasses ) == N + 2 ) {
1293  if( idx == N ) {
1294  using cur_json_class_t = traits::nth_element<N + 0, JsonClasses...>;
1295  return construct_value(
1296  template_args<T, Constructor>, parse_state,
1297  parse_value<cur_json_class_t>(
1298  parse_state,
1300  }
1301  using cur_json_class_t = traits::nth_element<N + 1, JsonClasses...>;
1302  return construct_value(
1303  template_args<T, Constructor>, parse_state,
1304  parse_value<cur_json_class_t>(
1305  parse_state,
1307  } else {
1308  using cur_json_class_t = traits::nth_element<N + 0, JsonClasses...>;
1309  return construct_value(
1310  template_args<T, Constructor>, parse_state,
1311  parse_value<cur_json_class_t>(
1312  parse_state,
1314  }
1315  }
1316  } // namespace json_details
1317  } // namespace DAW_JSON_VER
1318 } // namespace daw::json
#define daw_json_assert_weak(Bool,...)
Definition: daw_json_assert.h:189
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:178
#define CPP20CONSTEXPR
Definition: daw_json_parse_common.h:40
ParseState & parse_state
Definition: daw_json_parse_value.h:530
static constexpr Unsigned unsigned_parser(constexpr_exec_tag, ParseState &parse_state)
Definition: daw_json_parse_unsigned_int.h:109
constexpr auto parse_string_known_stdstring(ParseState &parse_state)
Definition: daw_json_parse_std_string.h:194
typename json_type_deducer< T, has_json_data_contract_trait_v< T >, json_details::is_a_json_type_v< T >, has_json_link_quick_map_v< T >, is_container_v< T > >::type json_deduced_type
Definition: daw_json_parse_common.h:931
constexpr ParseState skip_value(ParseState &parse_state)
Definition: daw_json_skip.h:298
constexpr bool has_json_member_constructor_v
Definition: daw_json_parse_value.h:418
constexpr DAW_ATTRIB_FLATTEN json_result< JsonClass > parse_nth_class(std::size_t idx, ParseState &parse_state)
Definition: daw_json_parse_value.h:993
constexpr DAW_ATTRIB_FLATTEN json_result< JsonMembers > parse_variant_value(ParseState &parse_state)
Definition: daw_json_parse_value.h:725
constexpr ParseState skip_literal(ParseState &parse_state)
Definition: daw_json_skip.h:387
std::bool_constant< daw::is_detected_v< json_type_t, T > > is_a_json_type
Definition: daw_json_traits.h:426
constexpr DAW_ATTRIB_FLATINLINE Result parse_visit(std::size_t idx, ParseState &parse_state)
Definition: daw_json_parse_value.h:788
constexpr DAW_ATTRIB_FLATINLINE json_result< JsonMember > parse_tuple_value(ParseState &parse_state, std::index_sequence< Is... >)
Definition: daw_json_parse_value.h:890
constexpr bool all_json_members_must_exist_v
Definition: daw_json_traits.h:606
typename JsonMember::dependent_member dependent_member_t
Definition: daw_json_parse_common.h:961
typename T::parse_to_t json_member_parse_to_t
Definition: daw_json_parse_value.h:415
constexpr DAW_ATTRIB_FLATINLINE ParseState skip_string(ParseState &parse_state)
Definition: daw_json_skip.h:56
AllMembersMustExist
Definition: daw_json_location_info.h:198
typename T::constructor_t json_member_constructor_t
Definition: daw_json_parse_value.h:412
static constexpr DAW_ATTRIB_FLATINLINE auto construct_value(template_params< Value, Constructor >, ParseState &parse_state, Args &&...args)
Definition: daw_json_parse_common.h:63
typename JsonMember::parse_to_t json_result
Definition: daw_json_parse_common.h:205
constexpr bool needs_slow_path(ParseState const &parse_state)
Definition: daw_json_parse_string_need_slow.h:23
constexpr DAW_ATTRIB_INLINE void skip_quote_when_literal_as_string(ParseState &parse_state)
Definition: daw_json_parse_value.h:49
constexpr DAW_ATTRIB_INLINE json_result< JsonMember > parse_value(ParseState &parse_state, ParseTag< JsonParseTypes::Real >)
Definition: daw_json_parse_value.h:67
constexpr bool has_json_member_parse_to_v
Definition: daw_json_parse_value.h:422
constexpr DAW_ATTRIB_FLATINLINE int validate_signed_first(ParseState &parse_state)
Definition: daw_json_parse_policy_policy_details.h:73
constexpr DAW_ATTRIB_FLATINLINE bool is_number(char c)
Definition: daw_json_parse_policy_policy_details.h:34
constexpr DAW_ATTRIB_FLATINLINE void validate_unsigned_first(ParseState const &parse_state)
Definition: daw_json_parse_policy_policy_details.h:41
constexpr DAW_ATTRIB_FLATINLINE bool at_end_of_item(char c)
Definition: daw_json_parse_policy_policy_details.h:25
constexpr DAW_ATTRIB_FLATINLINE bool is_number_start(char c)
Definition: daw_json_parse_policy_policy_details.h:106
typename json_data_contract< T >::type json_data_contract_trait_t
Definition: daw_json_traits.h:133
std::integral_constant< JsonParseTypes, v > ParseTag
Definition: daw_json_enums.h:106
DAW_ATTRIB_NOINLINE void daw_json_error(ErrorReason reason)
Definition: daw_json_assert.h:39
JsonBaseParseTypes
Definition: daw_json_enums.h:40
Definition: daw_from_json.h:22
Definition: daw_json_parse_array_iterator.h:63
Definition: daw_json_parse_kv_array_iterator.h:60
Definition: daw_json_parse_kv_class_iterator.h:50
DAW_ATTRIB_INLINE CPP20CONSTEXPR ~ordered_class_cleanup() noexcept(false)
Definition: daw_json_parse_value.h:856
ParseState & parse_state
Definition: daw_json_parse_value.h:853
Allow tuple like types to be used in json_tuple.
Definition: daw_json_traits.h:638
#define DAW_JSON_VER
Definition: version.h:11