DAW JSON Link
daw_json_parse_common.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 "daw_json_assert.h"
12 #include "daw_json_exec_modes.h"
13 #include "daw_json_parse_digit.h"
16 #include "daw_json_traits.h"
17 
18 #include <daw/daw_arith_traits.h>
19 #include <daw/daw_parser_helper_sv.h>
20 #include <daw/daw_string_view.h>
21 #include <daw/daw_traits.h>
22 
23 #include <ciso646>
24 #include <cstddef>
25 #include <iterator>
26 
27 #if defined( __cpp_constexpr_dynamic_alloc )
28 #define CPP20CONSTEXPR constexpr
29 #define HAS_CPP20CONSTEXPR
30 #else
31 #define CPP20CONSTEXPR
32 #endif
33 
34 namespace daw::json {
35  /***
36  *
37  * Allows specifying an unnamed json mapping where the
38  * result is a tuple
39  */
40  template<typename... Members>
42  std::tuple<typename Members::parse_to_t...> members;
43 
44  template<typename... Ts>
45  constexpr tuple_json_mapping( Ts &&...values )
46  : members{ std::forward<Ts>( values )... } {}
47  };
48 } // namespace daw::json
49 
50 namespace daw::json::json_details {
51  template<typename T>
52  using json_type_t = typename T::i_am_a_json_type;
53 
54  template<typename T>
55  inline constexpr bool is_a_json_type_v = daw::is_detected_v<json_type_t, T>;
56 
57  template<typename T>
58  using ordered_member_t = typename T::i_am_an_ordered_member;
59 
60  template<typename T>
61  inline constexpr bool is_an_ordered_member_v =
62  daw::is_detected_v<ordered_member_t, T>;
63 
64  template<typename T>
65  using is_a_json_tagged_variant_test = typename T::i_am_a_json_tagged_variant;
66 
67  template<typename T>
68  inline constexpr bool is_a_json_tagged_variant_v =
69  daw::is_detected_v<is_a_json_tagged_variant_test, T>;
70 
71  template<typename T, bool = false>
72  struct ordered_member_subtype {
73  using type = T;
74  };
75 
76  template<typename T>
77  struct ordered_member_subtype<T, true> {
78  using type = typename T::json_member;
79  };
80 
81  template<typename T>
82  using ordered_member_subtype_t =
83  typename ordered_member_subtype<T, is_an_ordered_member_v<T>>::type;
84 
85  template<typename T>
86  using json_data_contract_trait_t =
88 
89  template<typename T, bool, bool>
90  struct json_data_constract_constructor_impl {
91  using type = default_constructor<T>;
92  };
93 
94  template<typename T>
95  using has_json_data_constract_constructor_test =
96  typename json_data_contract_trait_t<T>::constructor;
97 
98  template<typename T>
99  struct json_data_constract_constructor_impl<T, true, true> {
100  using type = typename json_data_contract_trait_t<T>::constructor;
101  };
102 
103  template<typename T>
104  using json_data_contract_constructor_t =
105  typename json_data_constract_constructor_impl<
106  T, daw::is_detected_v<json_data_contract_trait_t, T>,
107  daw::is_detected_v<has_json_data_constract_constructor_test, T>>::type;
108 
109  template<typename T>
110  using json_class_constructor_t =
111  std::conditional_t<daw::is_detected_v<json_data_contract_constructor_t, T>,
112  json_data_contract_constructor_t<T>,
113  default_constructor<T>>;
114 
115  template<typename T>
116  inline constexpr auto json_class_constructor = json_class_constructor_t<T>{ };
117 
118  template<typename Value, typename Constructor, typename Range,
119  typename... Args>
120  DAW_ATTRIBUTE_FLATTEN static inline constexpr auto
121  construct_value( Constructor &&ctor, Range &rng, Args &&...args ) {
122  if constexpr( Range::has_allocator ) {
123  using alloc_t = typename Range::template allocator_type_as<Value>;
124  auto alloc = rng.template get_allocator_for<Value>( );
125  if constexpr( std::is_invocable_v<Constructor, Args..., alloc_t> ) {
126  return ctor( std::forward<Args>( args )..., std::move( alloc ) );
127  } else if constexpr( daw::traits::is_callable_v<Constructor,
128  std::allocator_arg_t,
129  alloc_t, Args...> ) {
130  return ctor( std::allocator_arg, std::move( alloc ),
131  std::forward<Args>( args )... );
132  } else {
133  static_assert( std::is_invocable_v<Constructor, Args...> );
134  return ctor( std::forward<Args>( args )... );
135  }
136  } else {
137  static_assert( std::is_invocable_v<Constructor, Args...> );
138  if constexpr( std::is_invocable_v<Constructor, Args...> ) {
139  return ctor( std::forward<Args>( args )... );
140  }
141  }
142  }
143 
144  template<typename Allocator>
145  using has_allocate_test =
146  decltype( std::declval<Allocator>( ).allocate( size_t{ 1 } ) );
147 
148  template<typename Allocator>
149  using has_deallocate_test = decltype( std::declval<Allocator>( ).deallocate(
150  static_cast<void *>( nullptr ), size_t{ 1 } ) );
151 
152  template<typename Allocator>
153  inline constexpr bool is_allocator_v =
154  daw::is_detected_v<has_allocate_test, Allocator>
155  and daw::is_detected_v<has_deallocate_test, Allocator>;
156 
157  template<typename T>
158  struct has_json_data_contract_trait
159  : std::bool_constant<
160  not std::is_same_v<daw::json::missing_json_data_contract_for<T>,
161  json_data_contract_trait_t<T>>> {};
162 
163  template<typename T>
164  inline constexpr bool has_json_data_contract_trait_v =
165  has_json_data_contract_trait<T>::value;
166 
167  template<typename Container, typename Value>
168  using detect_push_back = decltype( std::declval<Container &>( ).push_back(
169  std::declval<Value>( ) ) );
170 
171  template<typename Container, typename Value>
172  using detect_insert_end = decltype( std::declval<Container &>( ).insert(
173  std::end( std::declval<Container &>( ) ), std::declval<Value>( ) ) );
174 
175  template<typename Container, typename Value>
176  inline constexpr bool has_push_back_v =
177  daw::is_detected_v<detect_push_back, Container, Value>;
178 
179  template<typename Container, typename Value>
180  inline constexpr bool has_insert_end_v =
181  daw::is_detected_v<detect_insert_end, Container, Value>;
182 
183  template<typename JsonMember>
184  using json_result = typename JsonMember::parse_to_t;
185 
186  template<typename JsonMember>
187  using json_base_type = typename JsonMember::base_type;
188 
189  template<std::size_t I, typename... JsonMembers>
190  using json_result_n =
191  json_result<daw::traits::nth_element<I, JsonMembers...>>;
192 
193  template<typename Container>
194  struct basic_appender {
195  using value_type = typename Container::value_type;
196  using reference = value_type;
197  using pointer = value_type const *;
198  using difference_type = std::ptrdiff_t;
199  using iterator_category = std::output_iterator_tag;
200  Container *m_container;
201 
202  explicit inline constexpr basic_appender( Container &container )
203  : m_container( &container ) {}
204 
205  template<typename Value>
206  inline constexpr void operator( )( Value &&value ) const {
207  if constexpr( has_push_back_v<Container, daw::remove_cvref_t<Value>> ) {
208  m_container->push_back( std::forward<Value>( value ) );
209  } else if constexpr( has_insert_end_v<Container,
210  daw::remove_cvref_t<Value>> ) {
211  m_container->insert( std::end( *m_container ),
212  std::forward<Value>( value ) );
213  } else {
214  static_assert(
215  has_push_back_v<Container, daw::remove_cvref_t<Value>> or
216  has_insert_end_v<Container, daw::remove_cvref_t<Value>>,
217  "basic_appender requires a Container that either has push_back or "
218  "insert with the end iterator as first argument" );
219  }
220  }
221 
222  template<typename Value,
223  std::enable_if_t<
224  not std::is_same_v<basic_appender, daw::remove_cvref_t<Value>>,
225  std::nullptr_t> = nullptr>
226  inline constexpr basic_appender &operator=( Value &&v ) {
227  operator( )( std::forward<Value>( v ) );
228  return *this;
229  }
230 
231  inline constexpr basic_appender &operator++( ) {
232  return *this;
233  }
234 
235  inline constexpr basic_appender operator++( int ) const {
236  return *this;
237  }
238 
239  inline constexpr basic_appender &operator*( ) {
240  return *this;
241  }
242  };
243 
244  template<typename T>
245  using json_parser_to_json_data_t =
247  std::declval<T &>( ) ) );
248 
249  template<typename T>
250  static inline constexpr bool has_json_to_json_data_v =
251  daw::is_detected_v<json_parser_to_json_data_t, T>;
252 
253  template<typename T>
254  using is_submember_tagged_variant_t =
255  typename json_data_contract<T>::type::i_am_a_submember_tagged_variant;
256 
257  template<typename T>
258  static inline constexpr bool is_submember_tagged_variant_v =
259  daw::is_detected_v<is_submember_tagged_variant_t, T>;
260 } // namespace daw::json::json_details
261 
262 namespace daw::json {
263 #if defined( __cpp_nontype_template_parameter_class ) and \
264  not defined( DAW_JSON_NO_CPP_NAMES )
265  // C++ 20 Non-Type Class Template Arguments
266 
271  template<std::size_t N>
272  struct json_name {
273  static_assert( N > 0 );
274  char const m_data[N]{ };
275 
276  private:
277  template<std::size_t... Is>
278  constexpr json_name( char const ( &ptr )[N], std::index_sequence<Is...> )
279  : m_data{ ptr[Is]... } {}
280 
281  public:
282  constexpr json_name( char const ( &ptr )[N] )
283  : json_name( ptr, std::make_index_sequence<N>{ } ) {}
284 
285  constexpr operator daw::string_view( ) const {
286  return { m_data, N - 1 };
287  }
288 
289  // Needed for copy_to_iterator
290  [[nodiscard]] constexpr char const *begin( ) const {
291  return m_data;
292  }
293 
294  // Needed for copy_to_iterator
295  [[nodiscard]] constexpr char const *end( ) const {
296  return m_data + static_cast<ptrdiff_t>( size( ) );
297  }
298 
299  [[nodiscard]] static constexpr std::size_t size( ) {
300  return N - 1;
301  }
302 
303  template<std::size_t M>
304  constexpr bool operator==( json_name<M> const &rhs ) const {
305  if( N != M ) {
306  return false;
307  }
308  for( std::size_t n = 0; n < N; ++n ) {
309  if( m_data[n] != rhs.m_data[n] ) {
310  return false;
311  }
312  }
313  return true;
314  }
315 
316  constexpr bool operator==( daw::string_view rhs ) const {
317  return daw::string_view( m_data, N - 1 ) == rhs;
318  }
319 
320  constexpr bool operator==( std::string_view rhs ) const {
321  return std::string_view( m_data, N - 1 ) == rhs;
322  }
323 
324  constexpr operator std::string_view( ) const {
325  return std::string_view( m_data, N - 1 );
326  }
327  };
328  template<typename... Chars>
329  json_name( Chars... ) -> json_name<sizeof...( Chars )>;
330 
331  template<std::size_t N>
332  json_name( char const ( & )[N] ) -> json_name<N>;
333 
334 #define JSONNAMETYPE daw::json::json_name
335  // Convienience for array members that are required to be unnamed
336  inline constexpr JSONNAMETYPE no_name{ "\a" };
337 
338  namespace json_details {
339  inline constexpr JSONNAMETYPE default_key_name{ "key" };
340  inline constexpr JSONNAMETYPE default_value_name{ "value" };
341  } // namespace json_details
342 
343  template<typename JsonMember>
344  inline constexpr bool is_no_name = ( JsonMember::name == no_name );
345 #else
346 #define JSONNAMETYPE char const *
347  // Convienience for array members that are required to be unnamed
348  inline constexpr char const no_name[] = "\a";
349  namespace json_details {
350 
351  inline constexpr char const default_key_name[] = "key";
352  inline constexpr char const default_value_name[] = "value";
353 
354  } // namespace json_details
355 
356  template<typename JsonMember>
357  inline constexpr bool is_no_name = JsonMember::name == no_name;
358 #endif
359 
360  enum class JsonParseTypes : std::uint_fast8_t {
361  Real,
362  Signed,
363  Unsigned,
364  Bool,
365  StringRaw,
366  StringEscaped,
367  Date,
368  Class,
369  Array,
370  Null,
371  KeyValue,
372  KeyValueArray,
373  Custom,
374  Variant,
375  VariantTagged,
376  Unknown
377  };
378 
379  enum class JsonBaseParseTypes : std::uint_fast8_t {
380  Number,
381  Bool,
382  String,
383  Class,
384  Array,
385  Null,
386  None
387  };
388 
389  constexpr std::string_view to_string( JsonBaseParseTypes pt ) {
390  switch( pt ) {
391  case JsonBaseParseTypes::Number:
392  return "Number";
393  case JsonBaseParseTypes::Bool:
394  return "Bool";
395  case JsonBaseParseTypes::String:
396  return "String";
397  case JsonBaseParseTypes::Class:
398  return "Class";
399  case JsonBaseParseTypes::Array:
400  return "Array";
401  case JsonBaseParseTypes::Null:
402  return "Null";
404  default:
405  return "None";
406  }
407  }
408 
409  enum class JsonNullable { Never = false, Nullable = true };
410  enum class JsonRangeCheck { Never = false, CheckForNarrowing = true };
411  enum class EightBitModes { DisallowHigh = false, AllowFull = true };
412  enum class CustomJsonTypes { Literal, String, Either };
413 
414  /***
415  * In RAW String processing, if we know that there are no escaped double
416  * quotes \" we can stop at the first double quote
417  */
418  enum class AllowEscapeCharacter {
419  /*Full string processing to skip escaped characters*/ Allow,
420  /*There will never be a \" sequence inside the string*/ NotBeforeDblQuote
421  };
422 
423  template<JsonParseTypes ParseType, JsonNullable Nullable>
424  inline constexpr JsonParseTypes get_parse_type_v =
425  Nullable == JsonNullable::Never ? ParseType : JsonParseTypes::Null;
426 
427  namespace json_details {
428  template<typename>
429  inline constexpr std::size_t parse_space_needed_v = 1U;
430 
431  template<>
432  inline constexpr std::size_t parse_space_needed_v<simd_exec_tag> = 16U;
433 
434  template<typename JsonType>
435  static inline constexpr bool is_json_nullable_v =
436  JsonType::expected_type == JsonParseTypes::Null;
437 
438  template<typename T>
439  [[maybe_unused]] auto dereffed_type_impl( daw::tag_t<T> )
440  -> decltype( *( std::declval<T &>( ) ) );
441 
442  template<typename T>
443  using dereffed_type =
444  daw::remove_cvref_t<decltype( dereffed_type_impl( daw::tag<T> ) )>;
445 
446  template<typename T, JsonNullable Nullable>
447  using unwrap_type = std::conditional_t<
448  std::conjunction_v<std::bool_constant<Nullable == JsonNullable::Nullable>,
449  daw::is_detected<dereffed_type, T>>,
450  daw::detected_t<dereffed_type, T>, T>;
451 
452  template<typename T>
453  using can_deref = daw::is_detected<dereffed_type, T>;
454 
455  template<typename T>
456  using cant_deref = daw::not_trait<can_deref<T>>;
457 
458  template<typename T>
459  inline constexpr bool can_deref_v = can_deref<T>::value;
460 
461  template<typename T>
462  inline constexpr JsonParseTypes number_parse_type_impl_v = [] {
463  static_assert( daw::is_arithmetic_v<T>, "Unexpected non-number" );
464  if constexpr( daw::is_floating_point_v<T> ) {
465  return JsonParseTypes::Real;
466  } else if constexpr( daw::is_signed_v<T> ) {
467  return JsonParseTypes::Signed;
468  } else if constexpr( daw::is_unsigned_v<T> ) {
469  return JsonParseTypes::Unsigned;
470  }
471  }( );
472 
473  template<typename T>
474  constexpr auto number_parse_type_test( )
475  -> std::enable_if_t<std::is_enum_v<T>, JsonParseTypes> {
476 
477  return number_parse_type_impl_v<std::underlying_type_t<T>>;
478  }
479  template<typename T>
480  constexpr auto number_parse_type_test( )
481  -> std::enable_if_t<not std::is_enum_v<T>, JsonParseTypes> {
482 
483  return number_parse_type_impl_v<T>;
484  }
485  template<typename T>
486  inline constexpr JsonParseTypes
487  number_parse_type_v = number_parse_type_test<T>( );
488 
489  } // namespace json_details
490 
494  template<JsonParseTypes v>
495  using ParseTag = std::integral_constant<JsonParseTypes, v>;
496 
503  enum class LiteralAsStringOpt : std::uint8_t { Never, Maybe, Always };
504 
505  template<typename T>
507  using iterator_category = std::input_iterator_tag;
508  using value_type = T;
509  using reference = T &;
510  using pointer = T *;
511  using difference_type = std::ptrdiff_t;
512  };
513  static_assert(
514  std::is_same_v<
515  typename std::iterator_traits<TestInputIteratorType<int>>::value_type,
516  int> );
517 } // namespace daw::json
518 
519 namespace daw::json::json_details {
520 
521  /***
522  * Skip a string, after the initial quote has been skipped already
523  */
524  template<typename Range>
525  [[nodiscard]] DAW_ATTRIBUTE_FLATTEN static inline constexpr Range
526  skip_string_nq( Range &rng ) {
527  auto result = rng;
528  result.counter = string_quote::string_quote_parser::parse_nq( rng );
529 
530  daw_json_assert_weak( rng.front( ) == '"', ErrorReason::InvalidString,
531  rng );
532  result.last = rng.first;
533  rng.remove_prefix( );
534  return result;
535  }
536 
537  /***
538  * Skip a string and store the first escaped element's position, if any
539  */
540  template<typename Range>
541  [[nodiscard]] DAW_ATTRIBUTE_FLATTEN static inline constexpr Range
542  skip_string( Range &rng ) {
543  if( rng.empty( ) ) {
544  return rng;
545  }
546  if( *std::prev( rng.first ) != '"' ) {
547  daw_json_assert( rng.front( ) == '"', ErrorReason::InvalidString, rng );
548  rng.remove_prefix( );
549  }
550  daw_json_assert_weak( rng.has_more( ), ErrorReason::InvalidString, rng );
551  return skip_string_nq( rng );
552  }
553 
554  template<typename Range>
555  [[nodiscard]] static constexpr Range skip_true( Range &rng ) {
556  auto result = rng;
557  if constexpr( Range::is_unchecked_input ) {
558  rng.remove_prefix( 4 );
559  } else {
560  rng.remove_prefix( );
561  daw_json_assert( rng.starts_with( "rue" ), ErrorReason::InvalidTrue,
562  rng );
563  rng.remove_prefix( 3 );
564  }
565  result.last = rng.first;
566  rng.trim_left( );
567  daw_json_assert_weak( rng.is_at_token_after_value( ),
568  ErrorReason::InvalidEndOfValue, rng );
569  return result;
570  }
571 
572  template<typename Range>
573  [[nodiscard]] static constexpr Range skip_false( Range &rng ) {
574  auto result = rng;
575  if constexpr( Range::is_unchecked_input ) {
576  rng.remove_prefix( 5 );
577  } else {
578  rng.remove_prefix( );
579  daw_json_assert( rng.starts_with( "alse" ), ErrorReason::InvalidFalse,
580  rng );
581  rng.remove_prefix( 4 );
582  }
583  result.last = rng.first;
584  rng.trim_left( );
585  daw_json_assert_weak( rng.is_at_token_after_value( ),
586  ErrorReason::InvalidEndOfValue, rng );
587  return result;
588  }
589 
590  template<typename Range>
591  [[nodiscard]] static constexpr Range skip_null( Range &rng ) {
592  if constexpr( Range::is_unchecked_input ) {
593  rng.remove_prefix( 4 );
594  } else {
595  rng.remove_prefix( );
596  daw_json_assert( rng.starts_with( "ull" ), ErrorReason::InvalidNull,
597  rng );
598  rng.remove_prefix( 3 );
599  }
600  daw_json_assert_weak( rng.has_more( ), ErrorReason::UnexpectedEndOfData,
601  rng );
602  rng.trim_left( );
603  daw_json_assert_weak( rng.is_at_token_after_value( ),
604  ErrorReason::UnexpectedEndOfData, rng );
605  auto result = rng;
606  result.first = nullptr;
607  result.last = nullptr;
608  return result;
609  }
610 
611  template<bool is_unchecked_input>
612  DAW_ATTRIBUTE_FLATTEN [[nodiscard]] static inline constexpr char const *
613  skip_digits( char const *first, char const *const last ) {
614  if( DAW_JSON_UNLIKELY( first >= last ) ) {
615  return first;
616  }
617  unsigned dig = parse_digit( *first );
618  while( dig < 10 ) {
619  ++first;
620  if constexpr( not is_unchecked_input ) {
621  if( DAW_JSON_UNLIKELY( first >= last ) ) {
622  break;
623  }
624  }
625  dig = parse_digit( *first );
626  }
627  return first;
628  }
629  /***
630  * Skip a number and store the position of it's components in the returned
631  * Range
632  */
633  template<typename Range>
634  [[nodiscard]] static constexpr Range skip_number( Range &rng ) {
635  auto result = rng;
636  char const *first = rng.first;
637  char const *const last = rng.last;
638  daw_json_assert_weak( first < last, ErrorReason::UnexpectedEndOfData, rng );
639  if( *first == '-' ) {
640  ++first;
641  }
642  first = skip_digits<Range::is_unchecked_input>( first, last );
643  char const *decimal = nullptr;
644  if( ( Range::is_unchecked_input or first < last ) and ( *first == '.' ) ) {
645  decimal = first;
646  ++first;
647  first = skip_digits<Range::is_unchecked_input>( first, last );
648  }
649  char const *exp = nullptr;
650  unsigned dig = parse_digit( *first );
651  if( ( Range::is_unchecked_input or ( first < last ) ) &
652  ( ( dig == parsed_constants::e_char ) |
653  ( dig == parsed_constants::E_char ) ) ) {
654  exp = first;
655  ++first;
656  daw_json_assert_weak( first < last, ErrorReason::UnexpectedEndOfData,
657  [&] {
658  auto r = rng;
659  r.first = first;
660  return r;
661  }( ) );
662  dig = parse_digit( *first );
663  if( ( dig == parsed_constants::plus_char ) |
664  ( dig == parsed_constants::minus_char ) ) {
665  ++first;
666  }
667  first = skip_digits<Range::is_unchecked_input>( first, last );
668  }
669 
670  rng.first = first;
671  result.last = first;
672  result.class_first = decimal;
673  result.class_last = exp;
674  return result;
675  }
676 
677  /***
678  * When we don't know ahead of time what we are skipping switch on the first
679  * value and call that types specific skipper
680  * TODO: Investigate if there is a difference for the times we know what the
681  * member should be if that can increase performance
682  */
683  template<typename Range>
684  [[nodiscard]] static inline constexpr Range skip_value( Range &rng ) {
685  daw_json_assert_weak( rng.has_more( ), ErrorReason::UnexpectedEndOfData,
686  rng );
687 
688  // reset counter
689  rng.counter = 0;
690  switch( rng.front( ) ) {
691  case '"':
692  return skip_string( rng );
693  case '[':
694  return rng.skip_array( );
695  case '{':
696  return rng.skip_class( );
697  case 't':
698  return skip_true( rng );
699  case 'f':
700  return skip_false( rng );
701  case 'n':
702  return skip_null( rng );
703  case '-':
704  case '0':
705  case '1':
706  case '2':
707  case '3':
708  case '4':
709  case '5':
710  case '6':
711  case '7':
712  case '8':
713  case '9':
714  return skip_number( rng );
715  }
716  if constexpr( Range::is_unchecked_input ) {
717  DAW_UNREACHABLE( );
718  } else {
719  daw_json_error( ErrorReason::InvalidStartOfValue, rng );
720  }
721  }
722 
723  /***
724  * Used in json_array_iterator::operator++( ) as we know the type we are
725  * skipping
726  */
727  template<typename JsonMember, typename Range>
728  [[nodiscard]] DAW_ATTRIBUTE_FLATTEN inline constexpr Range
729  skip_known_value( Range &rng ) {
730  daw_json_assert_weak( rng.has_more( ), ErrorReason::UnexpectedEndOfData,
731  rng );
732  if constexpr( JsonMember::expected_type == JsonParseTypes::Date or
733  JsonMember::expected_type == JsonParseTypes::StringRaw or
734  JsonMember::expected_type == JsonParseTypes::StringEscaped or
735  JsonMember::expected_type == JsonParseTypes::Custom ) {
736  // json string encodings
737  daw_json_assert_weak( rng.front( ) == '"', ErrorReason::InvalidString,
738  rng );
739  rng.remove_prefix( );
740  return json_details::skip_string_nq( rng );
741  } else if constexpr( JsonMember::expected_type == JsonParseTypes::Real or
742  JsonMember::expected_type == JsonParseTypes::Signed or
743  JsonMember::expected_type ==
744  JsonParseTypes::Unsigned or
745  JsonMember::expected_type == JsonParseTypes::Bool or
746  JsonMember::expected_type == JsonParseTypes::Null ) {
747  // All literals
748  return json_details::skip_number( rng );
749  } else if constexpr( JsonMember::expected_type == JsonParseTypes::Array ) {
750  daw_json_assert_weak( rng.is_opening_bracket_checked( ),
751  ErrorReason::InvalidArrayStart, rng );
752  return rng.skip_array( );
753  } else if constexpr( JsonMember::expected_type == JsonParseTypes::Class ) {
754  daw_json_assert_weak( rng.is_opening_brace_checked( ),
755  ErrorReason::InvalidClassStart, rng );
756  return rng.skip_class( );
757  } else {
758  // Woah there
759  static_assert( JsonMember::expected_type == JsonParseTypes::Class,
760  "Unknown JsonParseTypes value. This is a programmer "
761  "error and the preceding did not check for it" );
762  DAW_UNREACHABLE( );
763  }
764  }
765 } // namespace daw::json::json_details
daw::json::JsonParseTypes::Real
@ Real
daw::json::no_name
constexpr char const no_name[]
Definition: daw_json_parse_common.h:348
daw::json::to_string
constexpr std::string_view to_string(JsonBaseParseTypes pt)
Definition: daw_json_parse_common.h:389
daw_json_assert
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:196
daw::json::StackRangeType::Class
@ Class
daw::json
Definition: daw_json_event_parser.h:17
daw_json_assert_weak
#define daw_json_assert_weak(Bool,...)
Definition: daw_json_assert.h:206
daw::json::EightBitModes
EightBitModes
Definition: daw_json_parse_common.h:411
daw::json::AllowEscapeCharacter::Allow
@ Allow
DAW_JSON_UNLIKELY
#define DAW_JSON_UNLIKELY(Bool)
Definition: daw_json_assert.h:35
daw::json::JsonBaseParseTypes
JsonBaseParseTypes
Definition: daw_json_parse_common.h:379
daw::json::tuple_json_mapping::members
std::tuple< typename Members::parse_to_t... > members
Definition: daw_json_parse_common.h:42
daw_json_traits.h
daw_json_error
static DAW_JSON_NOINLINE void daw_json_error(daw::json::ErrorReason reason)
Definition: daw_json_assert.h:59
daw_json_exec_modes.h
daw::json::AllowEscapeCharacter
AllowEscapeCharacter
Definition: daw_json_parse_common.h:418
daw::json::missing_json_data_contract_for
Definition: daw_json_traits.h:31
daw::json::TestInputIteratorType::iterator_category
std::input_iterator_tag iterator_category
Definition: daw_json_parse_common.h:507
daw::json::TestInputIteratorType
Definition: daw_json_parse_common.h:506
daw::json::LiteralAsStringOpt
LiteralAsStringOpt
Definition: daw_json_parse_common.h:503
JSONNAMETYPE
#define JSONNAMETYPE
Definition: daw_json_parse_common.h:346
daw::json::JsonBaseParseTypes::Number
@ Number
daw::json::JsonRangeCheck::Never
@ Never
daw::json::JsonParseTypes
JsonParseTypes
Definition: daw_json_parse_common.h:360
daw::json::EightBitModes::DisallowHigh
@ DisallowHigh
daw::json::JsonNullable::Never
@ Never
daw_json_parse_digit.h
daw::json::TestInputIteratorType::pointer
T * pointer
Definition: daw_json_parse_common.h:510
daw_json_assert.h
daw::json::JsonNullable
JsonNullable
Definition: daw_json_parse_common.h:409
daw::json::JsonRangeCheck
JsonRangeCheck
Definition: daw_json_parse_common.h:410
daw_json_parse_string_need_slow.h
daw::json::TestInputIteratorType::difference_type
std::ptrdiff_t difference_type
Definition: daw_json_parse_common.h:511
daw::json::TestInputIteratorType::reference
T & reference
Definition: daw_json_parse_common.h:509
daw::json::CustomJsonTypes
CustomJsonTypes
Definition: daw_json_parse_common.h:412
daw::json::tuple_json_mapping::tuple_json_mapping
constexpr tuple_json_mapping(Ts &&...values)
Definition: daw_json_parse_common.h:45
daw::json::LiteralAsStringOpt::Never
@ Never
daw::json::json_data_contract
Definition: daw_json_traits.h:39
daw::json::tuple_json_mapping
Definition: daw_json_parse_common.h:41
daw::json::get_parse_type_v
constexpr JsonParseTypes get_parse_type_v
Definition: daw_json_parse_common.h:424
daw::json::is_no_name
constexpr bool is_no_name
Definition: daw_json_parse_common.h:357
daw::json::ParseTag
std::integral_constant< JsonParseTypes, v > ParseTag
Definition: daw_json_parse_common.h:495
daw::json::TestInputIteratorType::value_type
T value_type
Definition: daw_json_parse_common.h:508
daw_json_parse_string_quote.h
daw::json::CustomJsonTypes::Literal
@ Literal