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 "version.h"
12 
13 #include "daw_json_assert.h"
14 #include "daw_json_enums.h"
15 #include "daw_json_exec_modes.h"
16 #include "daw_json_name.h"
17 #include "daw_json_option_bits.h"
18 #include "daw_json_traits.h"
19 #include "daw_json_type_options.h"
20 
21 #include <daw/daw_arith_traits.h>
22 #include <daw/daw_cpp_feature_check.h>
23 #include <daw/daw_fwd_pack_apply.h>
24 #include <daw/daw_move.h>
25 #include <daw/daw_parser_helper_sv.h>
26 #include <daw/daw_scope_guard.h>
27 #include <daw/daw_string_view.h>
28 #include <daw/daw_traits.h>
29 
30 #include <ciso646>
31 #include <cstddef>
32 #include <iterator>
33 #include <string>
34 #include <string_view>
35 #include <vector>
36 
37 #if defined( __cpp_constexpr_dynamic_alloc )
38 #define CPP20CONSTEXPR constexpr
39 #else
40 #define CPP20CONSTEXPR
41 #endif
42 
43 namespace daw::json {
44  inline namespace DAW_JSON_VER {
45  template<typename ParseState>
46  class basic_json_value;
47 
48  namespace json_details {
49  template<typename T>
50  using ordered_member_subtype_test = typename T::json_member;
51 
52  template<typename T>
54  typename daw::detected_or_t<T, ordered_member_subtype_test, T>;
55 
56  template<typename T, typename Default>
57  inline constexpr auto json_class_constructor =
59 
60  template<typename Value, typename Constructor, typename ParseState,
61  typename... Args>
62  [[maybe_unused]] DAW_ATTRIB_FLATINLINE static inline constexpr auto
63  construct_value( template_params<Value, Constructor>,
64  ParseState &parse_state, Args &&...args ) {
65  // Silence MSVC warning, used in other if constexpr case
66  (void)parse_state;
67  if constexpr( ParseState::has_allocator ) {
68  using alloc_t =
69  typename ParseState::template allocator_type_as<Value>;
70  auto alloc = parse_state.get_allocator_for( template_arg<Value> );
71  if constexpr( std::is_invocable<Constructor, Args...,
72  alloc_t>::value ) {
73  return Constructor{ }( DAW_FWD2( Args, args )...,
74  DAW_MOVE( alloc ) );
75  } else if constexpr( daw::traits::is_callable_v<Constructor,
76  std::allocator_arg_t,
77  alloc_t, Args...> ) {
78  return Constructor{ }( std::allocator_arg, DAW_MOVE( alloc ),
79  DAW_FWD2( Args, args )... );
80  } else {
81  static_assert(
82  std::is_invocable<Constructor, Args...>::value,
83  "Unable to construct value with the supplied arguments" );
84  return Constructor{ }( DAW_FWD2( Args, args )... );
85  }
86  } else {
87  static_assert(
88  std::is_invocable<Constructor, Args...>::value,
89  "Unable to construct value with the supplied arguments" );
90  if constexpr( std::is_invocable<Constructor, Args...>::value ) {
91  return Constructor{ }( DAW_FWD2( Args, args )... );
92  }
93  }
94  }
95 
96  template<typename Constructor>
98  template<typename... TArgs, std::size_t... Is>
99  DAW_ATTRIB_FLATINLINE inline constexpr decltype( auto )
100  operator( )( fwd_pack<TArgs...> &&tp,
101  std::index_sequence<Is...> ) const {
102  return Constructor{ }( get<Is>( DAW_MOVE( tp ) )... );
103  }
104 
105  template<typename... TArgs, typename Allocator, std::size_t... Is>
106  DAW_ATTRIB_FLATINLINE inline constexpr decltype( auto )
107  operator( )( fwd_pack<TArgs...> &&tp, Allocator &alloc,
108  std::index_sequence<Is...> ) const {
109  return Constructor{ }( get<Is>( DAW_MOVE( tp ) )...,
110  DAW_FWD2( Allocator, alloc ) );
111  }
112 
113  template<typename Alloc, typename... TArgs, std::size_t... Is>
114  DAW_ATTRIB_FLATINLINE inline constexpr decltype( auto )
115  operator( )( std::allocator_arg_t, Alloc &&alloc,
116  fwd_pack<TArgs...> &&tp,
117  std::index_sequence<Is...> ) const {
118 
119  return Constructor{ }( std::allocator_arg, DAW_FWD2( Alloc, alloc ),
120  get<Is>( DAW_MOVE( tp ) )... );
121  }
122  };
123 
124  template<typename Constructor>
125  inline constexpr auto construct_value_tp_invoke =
127 
128  template<typename Value, typename Constructor, typename ParseState,
129  typename... Args>
130  [[maybe_unused]] DAW_ATTRIB_FLATINLINE static inline constexpr auto
132  fwd_pack<Args...> &&tp_args ) {
133  if constexpr( ParseState::has_allocator ) {
134  using alloc_t =
135  typename ParseState::template allocator_type_as<Value>;
136  auto alloc = parse_state.get_allocator_for( template_arg<Value> );
137  if constexpr( std::is_invocable<Constructor, Args...,
138  alloc_t>::value ) {
139  return construct_value_tp_invoke<Constructor>(
140  DAW_MOVE( tp_args ), DAW_MOVE( alloc ),
141  std::index_sequence_for<Args...>{ } );
142  } else if constexpr( daw::traits::is_callable_v<Constructor,
143  std::allocator_arg_t,
144  alloc_t, Args...> ) {
145  return construct_value_tp_invoke<Constructor>(
146  std::allocator_arg, DAW_MOVE( alloc ), DAW_MOVE( tp_args ),
147  std::index_sequence_for<Args...>{ } );
148  } else {
149  static_assert(
150  std::is_invocable<Constructor, Args...>::value,
151  "Unable to construct value with the supplied arguments" );
152  return construct_value_tp_invoke<Constructor>(
153  DAW_MOVE( tp_args ), std::index_sequence_for<Args...>{ } );
154  }
155  } else {
156  // Silence MSVC warning, used in other if constexpr case
157  (void)parse_state;
158  static_assert(
159  std::is_invocable<Constructor, Args...>::value,
160  "Unable to construct value with the supplied arguments" );
161  return construct_value_tp_invoke<Constructor>(
162  DAW_MOVE( tp_args ), std::index_sequence_for<Args...>{ } );
163  }
164  }
165 
166  template<typename Allocator>
168  decltype( std::declval<Allocator &>( ).allocate( size_t{ 1 } ) );
169 
170  template<typename Allocator>
172  decltype( std::declval<Allocator &>( ).deallocate(
173  static_cast<void *>( nullptr ), size_t{ 1 } ) );
174 
175  template<typename Allocator>
176  inline constexpr bool is_allocator_v = std::conjunction<
177  daw::is_detected<has_allocate_test, Allocator>,
178  daw::is_detected<has_deallocate_test, Allocator>>::value;
179 
180  template<typename T>
182  not_trait<std::is_same<missing_json_data_contract_for<T>,
184  template<typename T>
185  inline constexpr bool has_json_data_contract_trait_v =
187 
188  template<typename Container, typename Value>
189  using detect_push_back = decltype( std::declval<Container &>( ).push_back(
190  std::declval<Value>( ) ) );
191 
192  template<typename Container, typename Value>
193  using detect_insert_end = decltype( std::declval<Container &>( ).insert(
194  std::end( std::declval<Container &>( ) ), std::declval<Value>( ) ) );
195 
196  template<typename Container, typename Value>
197  inline constexpr bool has_push_back_v =
198  daw::is_detected<detect_push_back, Container, Value>::value;
199 
200  template<typename Container, typename Value>
201  inline constexpr bool has_insert_end_v =
202  daw::is_detected<detect_insert_end, Container, Value>::value;
203 
204  template<typename JsonMember>
205  using json_result = typename JsonMember::parse_to_t;
206 
207  template<typename JsonMember>
208  using json_base_type = typename JsonMember::base_type;
209 
210  template<typename Container>
211  struct basic_appender {
212  using value_type = typename Container::value_type;
214  using pointer = value_type const *;
215  using difference_type = std::ptrdiff_t;
216  using iterator_category = std::output_iterator_tag;
217  Container *m_container;
218 
219  explicit inline constexpr basic_appender( Container &container )
220  : m_container( &container ) {}
221 
222  template<typename Value>
223  DAW_ATTRIB_FLATINLINE inline constexpr void
224  operator( )( Value &&value ) const {
225  if constexpr( has_push_back_v<Container,
226  daw::remove_cvref_t<Value>> ) {
227  m_container->push_back( DAW_FWD2( Value, value ) );
228  } else if constexpr( has_insert_end_v<Container,
229  daw::remove_cvref_t<Value>> ) {
230  m_container->insert( std::end( *m_container ),
231  DAW_FWD2( Value, value ) );
232  } else {
233  static_assert(
234  has_push_back_v<Container, daw::remove_cvref_t<Value>> or
235  has_insert_end_v<Container, daw::remove_cvref_t<Value>>,
236  "basic_appender requires a Container that either has push_back "
237  "or "
238  "insert with the end iterator as first argument" );
239  }
240  }
241 
242  template<
243  typename Value,
244  std::enable_if_t<
245  not std::is_same<basic_appender, daw::remove_cvref_t<Value>>::value,
246  std::nullptr_t> = nullptr>
247  inline constexpr basic_appender &operator=( Value &&v ) {
248  operator( )( DAW_FWD2( Value, v ) );
249  return *this;
250  }
251 
252  inline constexpr basic_appender &operator++( ) {
253  return *this;
254  }
255 
256  inline constexpr basic_appender operator++( int ) {
257  return *this;
258  }
259 
260  inline constexpr basic_appender &operator*( ) {
261  return *this;
262  }
263  };
264 
265  template<typename T>
267  decltype( json_data_contract<T>::to_json_data( std::declval<T &>( ) ) );
268 
269  template<typename T>
270  inline constexpr bool has_json_to_json_data_v =
271  daw::is_detected<json_parser_to_json_data_t, T>::value;
272 
273  template<typename T>
276 
277  template<typename T>
278  inline constexpr bool is_submember_tagged_variant_v =
279  daw::is_detected<is_submember_tagged_variant_t, T>::value;
280 
281  template<typename>
282  inline constexpr std::size_t parse_space_needed_v = 1U;
283 
284  template<>
285  inline constexpr std::size_t parse_space_needed_v<simd_exec_tag> = 16U;
286 
287  template<typename JsonType>
289  std::bool_constant<JsonType::expected_type == JsonParseTypes::Null>;
290 
291  template<typename JsonType>
292  static inline constexpr bool is_json_nullable_v =
294 
295  template<typename T>
297  daw::remove_cvref_t<decltype( *( std::declval<T &>( ) ) )>;
298 
299  template<typename T>
301  typename daw::detected_or<T, dereffed_type_impl, T>::type;
302 
303  template<typename T, JsonNullable Nullable>
304  using unwrap_type =
305  typename std::conditional_t<is_nullable_json_value_v<Nullable>,
306  dereffed_type<T>, T>;
307 
308  /***
309  * Helpers to set options on json_ types
310  */
311 
312  template<json_options_t CurrentOptions, auto option, auto... options>
313  inline constexpr json_options_t class_opts_set =
314  set_bits( class_opts, CurrentOptions, option, options... );
315 
316  template<json_options_t CurrentOptions, auto option, auto... options>
317  inline constexpr json_options_t number_opts_set =
318  set_bits( number_opts, CurrentOptions, option, options... );
319 
320  template<json_options_t CurrentOptions, auto option, auto... options>
321  inline constexpr json_options_t bool_opts_set =
322  set_bits( bool_opts, CurrentOptions, option, options... );
323 
324  template<json_options_t CurrentOptions, auto option, auto... options>
325  inline constexpr json_options_t string_opts_set =
326  set_bits( string_opts, CurrentOptions, option, options... );
327 
328  template<json_options_t CurrentOptions, auto option, auto... options>
330  set_bits( string_raw_opts, CurrentOptions, option, options... );
331 
332  template<json_options_t CurrentOptions, auto option, auto... options>
334  set_bits( json_custom_opts, CurrentOptions, option, options... );
335 
336  template<json_options_t CurrentOptions, auto option, auto... options>
337  inline constexpr json_options_t tuple_opts_set =
338  set_bits( tuple_opts, CurrentOptions, option, options... );
339  } // namespace json_details
340 
341  namespace json_base {
342  template<typename T, typename Constructor = default_constructor<T>,
343  json_details::json_options_t Options = class_opts_def>
344  struct json_class;
345 
346  template<typename T, typename Constructor = nullable_constructor<T>,
347  json_details::json_options_t Options = class_opts_def>
349  json_class<T, Constructor,
350  json_details::class_opts_set<Options, JsonNullDefault>>;
351 
352  template<typename JsonElement, typename Container,
353  typename Constructor = default_constructor<Container>,
355  struct json_array;
356 
357  template<typename JsonElement, typename Container,
358  typename Constructor = nullable_constructor<Container>>
361 
362  template<typename T,
364  typename Constructor = default_constructor<T>>
365  struct json_string_raw;
366 
367  template<typename T,
369  typename Constructor = nullable_constructor<T>>
371  T, json_details::string_raw_opts_set<Options, JsonNullDefault>,
372  Constructor>;
373 
374  template<typename T,
376  typename Constructor = default_constructor<T>>
377  struct json_string;
378 
379  template<typename T,
381  typename Constructor = nullable_constructor<T>>
384  Constructor>;
385 
386  template<typename T, json_details::json_options_t Options = bool_opts_def,
387  typename Constructor = default_constructor<T>>
388  struct json_bool;
389 
390  template<typename T, json_details::json_options_t Options = bool_opts_def,
391  typename Constructor = nullable_constructor<T>>
394  Constructor>;
395 
396  template<typename T,
398  typename Constructor = default_constructor<T>>
399  struct json_number;
400 
401  template<typename T,
403  typename Constructor = nullable_constructor<T>>
406  Constructor>;
407 
408  template<typename Container, typename JsonValueType, typename JsonKeyType,
409  typename Constructor = default_constructor<Container>,
411  struct json_key_value;
412 
413  template<typename Container, typename JsonValueType, typename JsonKeyType,
414  typename Constructor = nullable_constructor<Container>>
416  json_key_value<Container, JsonValueType, JsonKeyType, Constructor,
418 
419  template<typename Tuple,
420  typename Constructor = default_constructor<Tuple>,
422  struct json_tuple;
423 
424  template<typename Tuple,
425  typename Constructor = nullable_constructor<Tuple>,
428  json_tuple<Tuple, Constructor,
429  json_details::tuple_opts_set<Options, JsonNullDefault>>;
430 
431  /***
432  * json_raw allows for raw JSON access to the member data. It requires a
433  * type that is constructable from (char const *, std::size_t) arguments
434  * and for serialization requires that it can be passed to
435  * std::begin/std::end and the iterator returned has a value_type of char
436  * @tparam T type to hold raw JSON data, defaults to json_value
437  * @tparam Constructor A callable used to construct T.
438  * @tparam Nullable Does the value have to exist in the document or can it
439  * have a null value
440  */
441  template<typename T, typename Constructor = default_constructor<T>,
442  JsonNullable Nullable = JsonNullable::MustExist>
443  struct json_raw;
444 
445  /***
446  * json_raw_null allows for raw JSON access to the nullable member data.
447  * It requires a type that is constructable from (char const *,
448  * std::size_t) arguments and for serialization requires that it can be
449  * passed to std::begin/std::end and the iterator returned has a
450  * value_type of char
451  * @tparam T type to hold raw JSON data, defaults to json_value
452  * @tparam Constructor A callable used to construct T.
453  */
454  template<typename T, typename Constructor = nullable_constructor<T>>
456  } // namespace json_base
457 
458  namespace json_details {
459  template<typename T>
460  using can_deref =
461  typename std::bool_constant<daw::is_detected_v<dereffed_type_impl, T>>;
462 
463  template<typename T>
464  using cant_deref = daw::not_trait<can_deref<T>>;
465 
466  template<typename T>
467  inline constexpr bool can_deref_v = can_deref<T>::value;
468 
469  template<typename T>
470  inline constexpr JsonParseTypes number_parse_type_impl_v = [] {
471  static_assert( daw::is_arithmetic<T>::value, "Unexpected non-number" );
472  if constexpr( daw::is_floating_point<T>::value ) {
473  return JsonParseTypes::Real;
474  } else if constexpr( daw::is_signed<T>::value ) {
475  return JsonParseTypes::Signed;
476  } else if constexpr( daw::is_unsigned<T>::value ) {
478  }
479  }( );
480 
481  template<typename T>
482  constexpr auto number_parse_type_test( )
483  -> std::enable_if_t<std::is_enum<T>::value, JsonParseTypes> {
484 
485  return number_parse_type_impl_v<std::underlying_type_t<T>>;
486  }
487  template<typename T>
488  constexpr auto number_parse_type_test( )
489  -> std::enable_if_t<not std::is_enum<T>::value, JsonParseTypes> {
490 
491  return number_parse_type_impl_v<T>;
492  }
493 
494  template<typename T>
495  inline constexpr JsonParseTypes
496  number_parse_type_v = number_parse_type_test<T>( );
497 
498  template<typename, typename = void>
500  static constexpr bool is_null = false;
502 
503  static constexpr bool type_map_found = false;
504  };
505 
506  template<typename JsonType>
507  struct json_deduced_type_map<
508  JsonType, std::enable_if_t<json_details::is_a_json_type_v<JsonType>>> {
509  static constexpr bool is_null = false;
511 
512  using type = JsonType;
513  static constexpr bool type_map_found = true;
514  };
515 
516  template<typename T>
517  struct json_deduced_type_map<
518  T, std::enable_if_t<json_details::has_json_data_contract_trait_v<T>>> {
519  static constexpr bool is_null = false;
520  using type = typename json_data_contract<T>::type;
522 
523  static constexpr bool type_map_found = true;
524  };
525 
526  template<>
527  struct json_deduced_type_map<daw::string_view> {
528  static constexpr bool is_null = false;
530 
531  static constexpr bool type_map_found = true;
532  };
533 
534  template<>
535  struct json_deduced_type_map<std::string_view> {
536  static constexpr bool is_null = false;
538 
539  static constexpr bool type_map_found = true;
540  };
541 
542  template<>
543  struct json_deduced_type_map<std::string> {
544  static constexpr bool is_null = false;
545  static constexpr JsonParseTypes parse_type =
547 
548  static constexpr bool type_map_found = true;
549  };
550 
551  template<>
552  struct json_deduced_type_map<bool> {
553  static constexpr bool is_null = false;
555 
556  static constexpr bool type_map_found = true;
557  };
558 
559  // libc++ has a non-conforming vector<bool>::const_reference as it isn't
560  // bool https://bugs.llvm.org/show_bug.cgi?id=16077
561 #if defined( _LIBCPP_VERSION )
562  template<>
563  struct json_deduced_type_map<
564  typename std::vector<bool>::const_reference> {
565  static constexpr bool is_null = false;
567 
568  static constexpr bool type_map_found = true;
569  };
570 #endif
571 
572  template<typename Integer>
573  struct json_deduced_type_map<
574  Integer,
575  std::enable_if_t<std::conjunction_v<
576  not_trait<json_details::has_json_data_contract_trait<Integer>>,
577  daw::is_integral<Integer>>>> {
578  static constexpr bool is_null = false;
579  static constexpr JsonParseTypes parse_type =
580  daw::is_signed_v<Integer> ? JsonParseTypes::Signed
582 
583  static constexpr bool type_map_found = true;
584  };
585 
586  template<typename Enum>
587  struct json_deduced_type_map<
588  Enum, std::enable_if_t<std::conjunction_v<
589  not_trait<json_details::has_json_data_contract_trait<Enum>>,
590  std::is_enum<Enum>>>> {
591  static constexpr bool is_null = false;
592  static constexpr JsonParseTypes parse_type =
593  daw::is_signed_v<std::underlying_type<Enum>>
596 
597  static constexpr bool type_map_found = true;
598  };
599 
600  template<typename FloatingPoint>
601  struct json_deduced_type_map<
602  FloatingPoint,
603  std::enable_if_t<std::conjunction_v<
604  not_trait<json_details::has_json_data_contract_trait<FloatingPoint>>,
605  daw::is_floating_point<FloatingPoint>>>> {
606  static constexpr bool is_null = false;
608 
609  static constexpr bool type_map_found = true;
610  };
611 
612  template<typename Tuple>
613  struct json_deduced_type_map<
614  Tuple, std::enable_if_t<std::conjunction_v<
615  not_trait<json_details::has_json_data_contract_trait<Tuple>>,
616  is_tuple<Tuple>>>> {
617  static constexpr bool is_null = false;
619 
620  static constexpr bool type_map_found = true;
621  };
622 
623  namespace container_detect {
624  template<typename T>
625  using container_value_type = typename T::value_type;
626 
627  template<typename Container>
629  decltype( std::begin( std::declval<Container const &>( ) ) );
630 
631  template<typename Container>
633  decltype( std::end( std::declval<Container const &>( ) ) );
634 
635  template<typename T>
636  inline constexpr bool container_detect_v =
637  std::conjunction_v<daw::is_detected<container_value_type, T>,
638  daw::is_detected<container_begin_type, T>,
639  daw::is_detected<container_end_type, T>>;
640 
641  template<typename AssociativeContainer>
642  using container_key_type = typename AssociativeContainer::key_type;
643 
644  template<typename AssociativeContainer>
646  typename AssociativeContainer::mapped_type;
647 
648  template<typename T>
649  using is_value_type_char = std::is_same<char, container_value_type<T>>;
650 
651  } // namespace container_detect
652  template<typename T>
653  using is_container = std::conjunction<
654  daw::is_detected<container_detect::container_value_type, T>,
655  daw::is_detected<container_detect::container_begin_type, T>,
656  daw::is_detected<container_detect::container_end_type, T>>;
657 
658  template<typename Container>
660 
661  template<typename String>
662  using is_string =
663  std::conjunction<is_container<String>,
665 
666  template<typename String>
667  inline constexpr bool is_string_v = is_string<String>::value;
668 
669  template<typename AssociativeContainer>
670  using is_associative_container = std::conjunction<
672  daw::is_detected<container_detect::container_key_type,
673  AssociativeContainer>,
675  AssociativeContainer>>;
676 
677  template<typename AssociativeContainer>
678  inline constexpr bool is_associative_container_v =
680 
681  template<typename AssociativeContainer>
682  struct json_deduced_type_map<
683  AssociativeContainer,
684  std::enable_if_t<std::conjunction_v<
685  not_trait<has_json_data_contract_trait<AssociativeContainer>>,
686  is_associative_container<AssociativeContainer>>>> {
687 
688  static constexpr bool is_null = false;
689  using key = typename AssociativeContainer::key_type;
690  using value = typename AssociativeContainer::mapped_type;
692 
693  static constexpr bool type_map_found = true;
694  };
695 
696  template<typename Container>
697  struct json_deduced_type_map<
698  Container, std::enable_if_t<std::conjunction_v<
699  not_trait<has_json_data_contract_trait<Container>>,
700  not_trait<is_associative_container<Container>>,
701  json_details::is_container<Container>,
702  not_trait<is_string<Container>>>>> {
703 
704  static constexpr bool is_null = false;
705  using value = typename Container::value_type;
707 
708  static constexpr bool type_map_found = true;
709  };
710 
711  template<typename T>
712  struct json_deduced_type_map<
713  std::optional<T>,
714  std::enable_if_t<std::conjunction_v<
715  not_trait<has_json_data_contract_trait<std::optional<T>>>,
716  daw::is_detected<json_deduced_type_map, T>>>> {
717 
718  static constexpr bool is_null = true;
719  using type = json_deduced_type_map<T>;
720  static constexpr JsonParseTypes parse_type = type::parse_type;
721 
722  static constexpr bool type_map_found = true;
723  };
724 
725  template<typename T>
726  inline constexpr bool has_deduced_type_mapping_v =
728 
729  template<typename Mapped, bool Found = true>
730  struct json_link_quick_map_type : std::bool_constant<Found> {
731  using mapped_type = Mapped;
732  };
733 
734  template<typename T>
735  inline constexpr auto json_link_quick_map( ) {
736  if constexpr( is_a_json_type_v<T> ) {
737  return json_link_quick_map_type<T>{ };
738  } else if constexpr( has_deduced_type_mapping_v<T> ) {
739  using mapped_type_t = json_deduced_type_map<T>;
740  constexpr auto mapped_type = mapped_type_t::parse_type;
741  constexpr bool is_null = mapped_type_t::is_null;
742  if constexpr( mapped_type == JsonParseTypes::Unknown ) {
743  if constexpr( is_null ) {
745  } else {
747  }
748  } else if constexpr( mapped_type == JsonParseTypes::StringRaw ) {
749  if constexpr( is_null ) {
752  } else {
754  }
755  } else if constexpr( mapped_type == JsonParseTypes::StringEscaped ) {
756  if constexpr( is_null ) {
759  } else {
761  }
762  } else if constexpr( mapped_type == JsonParseTypes::Bool ) {
763  if constexpr( is_null ) {
765  } else {
767  }
768  } else if constexpr( ( mapped_type == JsonParseTypes::Signed ) |
769  ( mapped_type == JsonParseTypes::Unsigned ) |
770  ( mapped_type == JsonParseTypes::Real ) ) {
771  if constexpr( is_null ) {
774  } else {
776  }
777  } else if constexpr( mapped_type == JsonParseTypes::Tuple ) {
778  if constexpr( is_null ) {
780  } else {
782  }
783  } else if constexpr( mapped_type == JsonParseTypes::KeyValue ) {
784  if constexpr( is_null ) {
785  using b_t = typename mapped_type_t::base_type;
786  using k_t = typename b_t::key;
787  using v_t = typename b_t::value;
790  } else {
791  using k_t = typename mapped_type_t::key;
792  using v_t = typename mapped_type_t::value;
795  }
796  } else if constexpr( mapped_type == JsonParseTypes::Array ) {
797  if constexpr( is_null ) {
798  using b_t = typename mapped_type_t::base_type;
799  using v_t = typename b_t::value;
802  } else {
803  using v_t = typename mapped_type_t::value;
805  }
806  } else {
808  }
809  } else {
811  }
812  }
813 
814  /***
815  * Check if the current type has a quick map specialized for it
816  */
817  template<typename T>
818  using has_json_link_quick_map = decltype( json_link_quick_map<T>( ) );
819 
820  template<typename T>
821  inline constexpr bool has_json_link_quick_map_v =
823 
824  /***
825  * Get the quick mapped json type for type T
826  */
827  template<typename T>
829  typename decltype( json_link_quick_map<T>( ) )::mapped_type;
830 
831  namespace vector_detect {
832  template<typename T>
833  struct vector_test {
834  struct not_vector {};
835  static constexpr bool value = false;
836  using type = not_vector;
837  };
838 
839  template<typename T, typename Alloc>
840  struct vector_test<std::vector<T, Alloc>> {
841  static constexpr bool value = true;
842  using type = T;
843  };
844 
845  template<typename T>
847  } // namespace vector_detect
848 
849  template<typename T>
850  using is_vector =
851  std::bool_constant<vector_detect::vector_test<T>::value>;
852 
853  template<typename JsonType>
854  using is_json_class_map_test = typename JsonType::json_member;
855 
856  template<typename JsonType>
858  using type = typename JsonType::json_member;
859  };
860 
861  template<typename JsonType>
862  inline constexpr bool is_json_class_map_v =
863  daw::is_detected_v<is_json_class_map_test, JsonType>;
864 
865  template<typename T, bool Contract, bool JsonType, bool QuickMap,
866  bool Container>
869  };
870 
871  template<typename T, /*typename Contract,*/ bool JsonType, bool QuickMap,
872  bool Container>
873  struct json_type_deducer<T, true, JsonType, QuickMap, Container> {
874 
875  static_assert( not std::is_same_v<T, void> );
878  static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
879  "Detection failure" );
880  static_assert(
881  not std::is_same_v<daw::remove_cvref_t<type>, daw::nonesuch>,
882  "Detection failure" );
883  };
884 
885  template<typename T,
886  /*bool Contract, bool JsonType,*/ bool QuickMap, bool Container>
887  struct json_type_deducer<T, false, true, QuickMap, Container> {
888  static_assert( not std::is_same_v<T, void> );
889  using type =
890  typename std::conditional_t<is_json_class_map_v<T>,
892  daw::traits::identity<T>>::type;
893  static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
894  "Detection failure" );
895  static_assert(
896  not std::is_same_v<daw::remove_cvref_t<type>, daw::nonesuch>,
897  "Detection failure" );
898  };
899 
900  template<typename T /*bool Contract, bool JsonType, bool QuickMap*/,
901  bool Container>
902  struct json_type_deducer<T, false, false, true, Container> {
903  static_assert( not std::is_same_v<T, void> );
905  static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
906  "Detection failure" );
907  static_assert(
908  not std::is_same_v<daw::remove_cvref_t<type>, daw::nonesuch>,
909  "Detection failure" );
910  static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
911  "Detection failure" );
912  };
913 
914  template<typename T
915  /*bool Contract, bool JsonType, bool QuickMap,bool Container*/>
916  struct json_type_deducer<T, false, false, false, true> {
917  static_assert( not std::is_same_v<T, void> );
919  static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
920  "Detection failure" );
921  static_assert(
922  not std::is_same_v<daw::remove_cvref_t<type>, daw::nonesuch>,
923  "Detection failure" );
924  static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
925  "Detection failure" );
926  };
927 
928  template<typename T>
930  T, has_json_data_contract_trait_v<T>, json_details::is_a_json_type_v<T>,
931  has_json_link_quick_map_v<T>, is_container_v<T>>::type;
932 
933  template<typename T>
934  using has_json_deduced_type = daw::not_trait<
935  std::is_same<json_deduced_type<T>, missing_json_data_contract_for<T>>>;
936 
937  template<typename T>
938  inline constexpr bool has_unnamed_default_type_mapping_v =
940 
941  template<typename JsonMember>
943 
944  template<typename Constructor, typename... Members>
946  Constructor{ }( std::declval<typename Members::parse_to_t &&>( )... ) );
947 
948  template<typename Constructor, typename... Members>
950  daw::detected_t<json_class_parse_result_impl2, Constructor, Members...>;
951 
952  template<typename Constructor, typename... Members>
953  using json_class_parse_result_t = daw::remove_cvref_t<
954  json_class_parse_result_impl<Constructor, Members...>>;
955 
956  template<typename Constructor, typename... Members>
957  inline constexpr bool can_defer_construction_v =
958  std::is_invocable_v<Constructor, typename Members::parse_to_t...>;
959 
960  template<typename JsonMember>
961  using dependent_member_t = typename JsonMember::dependent_member;
962 
963  template<typename JsonMember>
964  inline constexpr bool has_dependent_member_v =
965  daw::is_detected_v<dependent_member_t, JsonMember>;
966  } // namespace json_details
967  } // namespace DAW_JSON_VER
968 } // namespace daw::json
ParseState & parse_state
Definition: daw_json_parse_class.h:201
typename AssociativeContainer::key_type container_key_type
Definition: daw_json_parse_common.h:642
typename AssociativeContainer::mapped_type container_mapped_type
Definition: daw_json_parse_common.h:646
typename T::value_type container_value_type
Definition: daw_json_parse_common.h:625
decltype(std::begin(std::declval< Container const & >())) container_begin_type
Definition: daw_json_parse_common.h:629
std::is_same< char, container_value_type< T > > is_value_type_char
Definition: daw_json_parse_common.h:649
constexpr bool container_detect_v
Definition: daw_json_parse_common.h:636
decltype(std::end(std::declval< Container const & >())) container_end_type
Definition: daw_json_parse_common.h:633
typename vector_test< T >::type vector_test_t
Definition: daw_json_parse_common.h:846
decltype(std::declval< Container & >().push_back(std::declval< Value >())) detect_push_back
Definition: daw_json_parse_common.h:190
typename daw::detected_or< T, dereffed_type_impl, T >::type dereffed_type
Definition: daw_json_parse_common.h:301
std::bool_constant< JsonType::expected_type==JsonParseTypes::Null > is_json_nullable
Definition: daw_json_parse_common.h:289
typename T::json_member ordered_member_subtype_test
Definition: daw_json_parse_common.h:50
constexpr bool has_json_to_json_data_v
Definition: daw_json_parse_common.h:270
constexpr bool has_json_data_contract_trait_v
Definition: daw_json_parse_common.h:185
decltype(std::declval< Allocator & >().allocate(size_t{ 1 })) has_allocate_test
Definition: daw_json_parse_common.h:168
decltype(Constructor{ }(std::declval< typename Members::parse_to_t && >()...)) json_class_parse_result_impl2
Definition: daw_json_parse_common.h:946
std::conjunction< is_container< AssociativeContainer >, daw::is_detected< container_detect::container_key_type, AssociativeContainer >, daw::is_detected< container_detect::container_mapped_type, AssociativeContainer > > is_associative_container
Definition: daw_json_parse_common.h:675
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
decltype(json_link_quick_map< T >()) has_json_link_quick_map
Definition: daw_json_parse_common.h:818
constexpr json_options_t string_opts_set
Definition: daw_json_parse_common.h:325
daw::not_trait< std::is_same< json_deduced_type< T >, missing_json_data_contract_for< T > >> has_json_deduced_type
Definition: daw_json_parse_common.h:935
constexpr JsonParseTypes number_parse_type_v
Definition: daw_json_parse_common.h:496
constexpr json_options_t tuple_opts_set
Definition: daw_json_parse_common.h:337
constexpr json_options_t bool_opts_set
Definition: daw_json_parse_common.h:321
typename std::bool_constant< daw::is_detected_v< dereffed_type_impl, T > > can_deref
Definition: daw_json_parse_common.h:461
constexpr bool has_push_back_v
Definition: daw_json_parse_common.h:197
constexpr bool has_unnamed_default_type_mapping_v
Definition: daw_json_parse_common.h:938
constexpr bool has_dependent_member_v
Definition: daw_json_parse_common.h:964
constexpr auto json_link_quick_map()
Definition: daw_json_parse_common.h:735
constexpr json_options_t set_bits(JsonOptionList< OptionList... >, json_options_t value, Option pol, Options... pols)
Definition: daw_json_option_bits.h:138
typename daw::detected_or_t< T, ordered_member_subtype_test, T > ordered_member_subtype_t
Definition: daw_json_parse_common.h:54
typename std::conditional_t< daw::is_detected< json_data_contract_constructor_t, T >::value, json_data_contract_constructor< T >, daw::traits::identity< Default > >::type json_class_constructor_t
Definition: daw_json_traits.h:484
typename JsonType::json_member is_json_class_map_test
Definition: daw_json_parse_common.h:854
daw::detected_t< json_class_parse_result_impl2, Constructor, Members... > json_class_parse_result_impl
Definition: daw_json_parse_common.h:950
std::conjunction< is_container< String >, container_detect::is_value_type_char< String > > is_string
Definition: daw_json_parse_common.h:664
constexpr auto number_parse_type_test() -> std::enable_if_t< std::is_enum< T >::value, JsonParseTypes >
Definition: daw_json_parse_common.h:482
typename decltype(json_link_quick_map< T >())::mapped_type json_link_quick_map_t
Definition: daw_json_parse_common.h:829
std::conjunction< daw::is_detected< container_detect::container_value_type, T >, daw::is_detected< container_detect::container_begin_type, T >, daw::is_detected< container_detect::container_end_type, T > > is_container
Definition: daw_json_parse_common.h:656
daw::remove_cvref_t< decltype(*(std::declval< T & >()))> dereffed_type_impl
Definition: daw_json_parse_common.h:297
static constexpr DAW_ATTRIB_FLATINLINE auto construct_value_tp(ParseState &parse_state, fwd_pack< Args... > &&tp_args)
Definition: daw_json_parse_common.h:131
constexpr bool is_allocator_v
Definition: daw_json_parse_common.h:176
constexpr auto json_class_constructor
Definition: daw_json_parse_common.h:57
constexpr bool is_string_v
Definition: daw_json_parse_common.h:667
typename JsonMember::dependent_member dependent_member_t
Definition: daw_json_parse_common.h:961
std::uint32_t json_options_t
Definition: daw_json_option_bits.h:23
constexpr bool has_deduced_type_mapping_v
Definition: daw_json_parse_common.h:726
decltype(json_data_contract< T >::to_json_data(std::declval< T & >())) json_parser_to_json_data_t
Definition: daw_json_parse_common.h:267
json_result< json_deduced_type< JsonMember > > from_json_result_t
Definition: daw_json_parse_common.h:942
constexpr bool is_submember_tagged_variant_v
Definition: daw_json_parse_common.h:278
typename json_data_contract< T >::type::i_am_a_submember_tagged_variant is_submember_tagged_variant_t
Definition: daw_json_parse_common.h:275
decltype(std::declval< Container & >().insert(std::end(std::declval< Container & >()), std::declval< Value >())) detect_insert_end
Definition: daw_json_parse_common.h:194
std::bool_constant< vector_detect::vector_test< T >::value > is_vector
Definition: daw_json_parse_common.h:851
constexpr bool has_insert_end_v
Definition: daw_json_parse_common.h:201
constexpr json_options_t string_raw_opts_set
Definition: daw_json_parse_common.h:329
constexpr std::size_t parse_space_needed_v< simd_exec_tag >
Definition: daw_json_parse_common.h:285
constexpr JsonParseTypes number_parse_type_impl_v
Definition: daw_json_parse_common.h:470
constexpr bool is_container_v
Definition: daw_json_parse_common.h:659
constexpr auto construct_value_tp_invoke
Definition: daw_json_parse_common.h:125
decltype(std::declval< Allocator & >().deallocate(static_cast< void * >(nullptr), size_t{ 1 })) has_deallocate_test
Definition: daw_json_parse_common.h:173
constexpr json_options_t number_opts_set
Definition: daw_json_parse_common.h:317
constexpr bool is_associative_container_v
Definition: daw_json_parse_common.h:678
static constexpr DAW_ATTRIB_FLATINLINE auto construct_value(template_params< Value, Constructor >, ParseState &parse_state, Args &&...args)
Definition: daw_json_parse_common.h:63
constexpr std::size_t parse_space_needed_v
Definition: daw_json_parse_common.h:282
constexpr bool is_null(std::optional< T > const &v)
Definition: to_daw_json_string.h:942
typename JsonMember::parse_to_t json_result
Definition: daw_json_parse_common.h:205
not_trait< std::is_same< missing_json_data_contract_for< T >, json_data_contract_trait_t< T > >> has_json_data_contract_trait
Definition: daw_json_parse_common.h:183
static constexpr bool is_json_nullable_v
Definition: daw_json_parse_common.h:292
constexpr bool can_deref_v
Definition: daw_json_parse_common.h:467
constexpr bool can_defer_construction_v
Definition: daw_json_parse_common.h:957
constexpr bool is_json_class_map_v
Definition: daw_json_parse_common.h:862
daw::remove_cvref_t< json_class_parse_result_impl< Constructor, Members... > > json_class_parse_result_t
Definition: daw_json_parse_common.h:954
daw::not_trait< can_deref< T > > cant_deref
Definition: daw_json_parse_common.h:464
typename std::conditional_t< is_nullable_json_value_v< Nullable >, dereffed_type< T >, T > unwrap_type
Definition: daw_json_parse_common.h:306
constexpr bool has_json_link_quick_map_v
Definition: daw_json_parse_common.h:821
constexpr json_options_t json_custom_opts_set
Definition: daw_json_parse_common.h:333
typename JsonMember::base_type json_base_type
Definition: daw_json_parse_common.h:208
constexpr json_options_t class_opts_set
Definition: daw_json_parse_common.h:313
constexpr json_details::json_options_t string_opts_def
Definition: daw_json_type_options.h:124
JsonParseTypes
Definition: daw_json_enums.h:19
constexpr auto bool_opts
Definition: daw_json_type_options.h:81
typename json_data_contract< T >::type json_data_contract_trait_t
Definition: daw_json_traits.h:133
constexpr auto string_raw_opts
Definition: daw_json_type_options.h:155
constexpr json_details::json_options_t tuple_opts_def
Definition: daw_json_type_options.h:179
JsonNullable
Definition: daw_json_enums.h:77
constexpr json_details::json_options_t class_opts_def
Definition: daw_json_type_options.h:168
constexpr json_details::json_options_t bool_opts_def
Definition: daw_json_type_options.h:82
constexpr auto tuple_opts
Definition: daw_json_type_options.h:178
constexpr json_details::json_options_t string_raw_opts_def
Definition: daw_json_type_options.h:156
constexpr JsonNullable JsonNullDefault
Definition: daw_json_enums.h:83
constexpr auto json_custom_opts
Definition: daw_json_type_options.h:212
constexpr auto class_opts
Definition: daw_json_type_options.h:167
constexpr auto string_opts
Definition: daw_json_type_options.h:123
constexpr json_details::json_options_t number_opts_def
Definition: daw_json_type_options.h:69
constexpr auto number_opts
Definition: daw_json_type_options.h:68
Definition: daw_from_json.h:22
Definition: daw_from_json.h:22
Definition: daw_json_traits.h:190
Definition: daw_json_link_types.h:1182
Definition: daw_json_link_types.h:475
Definition: daw_json_link_types.h:775
Definition: daw_json_link_types.h:1378
Definition: daw_json_link_types.h:353
Definition: daw_json_link_types.h:1696
Definition: daw_json_link_types.h:546
Definition: daw_json_link_types.h:635
Definition: daw_json_link_types.h:1605
Definition: daw_json_link_types.h:822
Definition: daw_json_traits.h:125
Definition: daw_json_parse_common.h:211
Container * m_container
Definition: daw_json_parse_common.h:217
value_type reference
Definition: daw_json_parse_common.h:213
constexpr basic_appender & operator*()
Definition: daw_json_parse_common.h:260
constexpr basic_appender(Container &container)
Definition: daw_json_parse_common.h:219
typename Container::value_type value_type
Definition: daw_json_parse_common.h:212
std::output_iterator_tag iterator_category
Definition: daw_json_parse_common.h:216
constexpr basic_appender & operator=(Value &&v)
Definition: daw_json_parse_common.h:247
constexpr basic_appender operator++(int)
Definition: daw_json_parse_common.h:256
constexpr basic_appender & operator++()
Definition: daw_json_parse_common.h:252
value_type const * pointer
Definition: daw_json_parse_common.h:214
std::ptrdiff_t difference_type
Definition: daw_json_parse_common.h:215
Definition: daw_json_parse_common.h:857
typename JsonType::json_member type
Definition: daw_json_parse_common.h:858
static constexpr JsonParseTypes parse_type
Definition: daw_json_parse_common.h:501
static constexpr bool is_null
Definition: daw_json_parse_common.h:500
static constexpr bool type_map_found
Definition: daw_json_parse_common.h:503
typename std::conditional_t< is_json_class_map_v< T >, json_class_map_type< T >, daw::traits::identity< T > >::type type
Definition: daw_json_parse_common.h:892
json_link_quick_map_t< T > type
Definition: daw_json_parse_common.h:904
Definition: daw_json_parse_common.h:867
missing_json_data_contract_for< T > type
Definition: daw_json_parse_common.h:868
static constexpr bool value
Definition: daw_json_parse_common.h:835
not_vector type
Definition: daw_json_parse_common.h:836
Definition: daw_json_traits.h:331
#define DAW_JSON_VER
Definition: version.h:11