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"
18#include "daw_json_traits.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
37namespace daw::json {
38 inline namespace DAW_JSON_VER {
39
40 struct json_deduce_type;
41
42 template<typename ParseState>
43 class basic_json_value;
44
45 namespace json_details {
46 template<typename T>
47 using ordered_member_subtype_test = typename T::json_member;
48
49 template<typename T>
51 typename daw::detected_or_t<T, ordered_member_subtype_test, T>;
52
53 template<typename T, typename Default>
54 inline constexpr auto json_class_constructor =
56
57 template<typename Value, typename Constructor, typename ParseState,
58 typename... Args>
59 [[maybe_unused]] DAW_ATTRIB_FLATINLINE static inline constexpr auto
60 construct_value( template_params<Value, Constructor>,
61 ParseState &parse_state, Args &&...args ) {
62 // Silence MSVC warning, used in other if constexpr case
63 (void)parse_state;
64 if constexpr( ParseState::has_allocator ) {
65 using alloc_t =
66 typename ParseState::template allocator_type_as<Value>;
67 auto alloc = parse_state.get_allocator_for( template_arg<Value> );
68 if constexpr( std::is_invocable<Constructor, Args...,
69 alloc_t>::value ) {
70 return Constructor{ }( DAW_FWD2( Args, args )...,
71 DAW_MOVE( alloc ) );
72 } else if constexpr( daw::traits::is_callable_v<Constructor,
73 std::allocator_arg_t,
74 alloc_t, Args...> ) {
75 return Constructor{ }( std::allocator_arg, DAW_MOVE( alloc ),
76 DAW_FWD2( Args, args )... );
77 } else {
78 static_assert(
79 std::is_invocable<Constructor, Args...>::value,
80 "Unable to construct value with the supplied arguments" );
81 return Constructor{ }( DAW_FWD2( Args, args )... );
82 }
83 } else {
84 static_assert(
85 std::is_invocable<Constructor, Args...>::value,
86 "Unable to construct value with the supplied arguments" );
87 return Constructor{ }( DAW_FWD2( Args, args )... );
88 }
89 }
90
91 template<typename Constructor>
93 template<typename... TArgs, std::size_t... Is>
94 DAW_ATTRIB_FLATINLINE inline constexpr decltype( auto )
95 operator( )( fwd_pack<TArgs...> &&tp,
96 std::index_sequence<Is...> ) const {
97 return Constructor{ }( get<Is>( DAW_MOVE( tp ) )... );
98 }
99
100 template<typename... TArgs, typename Allocator, std::size_t... Is>
101 DAW_ATTRIB_FLATINLINE inline constexpr decltype( auto )
102 operator( )( fwd_pack<TArgs...> &&tp, Allocator &alloc,
103 std::index_sequence<Is...> ) const {
104 return Constructor{ }( get<Is>( DAW_MOVE( tp ) )...,
105 DAW_FWD2( Allocator, alloc ) );
106 }
107
108 template<typename Alloc, typename... TArgs, std::size_t... Is>
109 DAW_ATTRIB_FLATINLINE inline constexpr decltype( auto )
110 operator( )( std::allocator_arg_t, Alloc &&alloc,
111 fwd_pack<TArgs...> &&tp,
112 std::index_sequence<Is...> ) const {
113
114 return Constructor{ }( std::allocator_arg, DAW_FWD2( Alloc, alloc ),
115 get<Is>( DAW_MOVE( tp ) )... );
116 }
117 };
118
119 template<typename Constructor>
120 inline constexpr auto construct_value_tp_invoke =
122
123 template<typename Value, typename Constructor, typename ParseState,
124 typename... Args>
125 [[maybe_unused]] DAW_ATTRIB_FLATINLINE static inline constexpr auto
127 fwd_pack<Args...> &&tp_args ) {
128 if constexpr( ParseState::has_allocator ) {
129 using alloc_t =
130 typename ParseState::template allocator_type_as<Value>;
131 auto alloc = parse_state.get_allocator_for( template_arg<Value> );
132 if constexpr( std::is_invocable<Constructor, Args...,
133 alloc_t>::value ) {
134 return construct_value_tp_invoke<Constructor>(
135 DAW_MOVE( tp_args ), DAW_MOVE( alloc ),
136 std::index_sequence_for<Args...>{ } );
137 } else if constexpr( daw::traits::is_callable_v<Constructor,
138 std::allocator_arg_t,
139 alloc_t, Args...> ) {
140 return construct_value_tp_invoke<Constructor>(
141 std::allocator_arg, DAW_MOVE( alloc ), DAW_MOVE( tp_args ),
142 std::index_sequence_for<Args...>{ } );
143 } else {
144 static_assert(
145 std::is_invocable<Constructor, Args...>::value,
146 "Unable to construct value with the supplied arguments" );
147 return construct_value_tp_invoke<Constructor>(
148 DAW_MOVE( tp_args ), std::index_sequence_for<Args...>{ } );
149 }
150 } else {
151 // Silence MSVC warning, used in other if constexpr case
152 (void)parse_state;
153 static_assert(
154 std::is_invocable<Constructor, Args...>::value,
155 "Unable to construct value with the supplied arguments" );
156 return construct_value_tp_invoke<Constructor>(
157 DAW_MOVE( tp_args ), std::index_sequence_for<Args...>{ } );
158 }
159 }
160
161 template<typename Allocator>
163 decltype( std::declval<Allocator &>( ).allocate( size_t{ 1 } ) );
164
165 template<typename Allocator>
167 decltype( std::declval<Allocator &>( ).deallocate(
168 static_cast<void *>( nullptr ), size_t{ 1 } ) );
169
170 template<typename Allocator>
171 inline constexpr bool is_allocator_v = std::conjunction<
172 daw::is_detected<has_allocate_test, Allocator>,
173 daw::is_detected<has_deallocate_test, Allocator>>::value;
174
175 template<typename T>
177 not_trait<std::is_same<missing_json_data_contract_for<T>,
179 template<typename T>
180 inline constexpr bool has_json_data_contract_trait_v =
182
183 template<typename Container, typename Value>
184 using detect_push_back = decltype( std::declval<Container &>( ).push_back(
185 std::declval<Value>( ) ) );
186
187 template<typename Container, typename Value>
188 using detect_insert_end = decltype( std::declval<Container &>( ).insert(
189 std::end( std::declval<Container &>( ) ), std::declval<Value>( ) ) );
190
191 template<typename Container, typename Value>
192 inline constexpr bool has_push_back_v =
193 daw::is_detected<detect_push_back, Container, Value>::value;
194
195 template<typename Container, typename Value>
196 inline constexpr bool has_insert_end_v =
197 daw::is_detected<detect_insert_end, Container, Value>::value;
198
199 template<typename JsonMember>
200 using json_result = typename JsonMember::parse_to_t;
201
202 template<typename JsonMember>
203 using json_base_type = typename JsonMember::base_type;
204
205 template<typename Container>
207 using value_type = typename Container::value_type;
209 using pointer = value_type const *;
210 using difference_type = std::ptrdiff_t;
211 using iterator_category = std::output_iterator_tag;
212 Container *m_container;
213
214 explicit inline constexpr basic_appender( Container &container )
215 : m_container( &container ) {}
216
217 template<typename Value>
218 DAW_ATTRIB_FLATINLINE inline constexpr void
219 operator( )( Value &&value ) const {
220 if constexpr( has_push_back_v<Container,
221 daw::remove_cvref_t<Value>> ) {
222 m_container->push_back( DAW_FWD2( Value, value ) );
223 } else if constexpr( has_insert_end_v<Container,
224 daw::remove_cvref_t<Value>> ) {
225 m_container->insert( std::end( *m_container ),
226 DAW_FWD2( Value, value ) );
227 } else {
228 static_assert(
229 has_push_back_v<Container, daw::remove_cvref_t<Value>> or
230 has_insert_end_v<Container, daw::remove_cvref_t<Value>>,
231 "basic_appender requires a Container that either has push_back "
232 "or "
233 "insert with the end iterator as first argument" );
234 }
235 }
236
237 template<
238 typename Value,
239 std::enable_if_t<
240 not std::is_same<basic_appender, daw::remove_cvref_t<Value>>::value,
241 std::nullptr_t> = nullptr>
242 inline constexpr basic_appender &operator=( Value &&v ) {
243 operator( )( DAW_FWD2( Value, v ) );
244 return *this;
245 }
246
247 inline constexpr basic_appender &operator++( ) {
248 return *this;
249 }
250
251 inline constexpr basic_appender operator++( int ) {
252 return *this;
253 }
254
255 inline constexpr basic_appender &operator*( ) {
256 return *this;
257 }
258 };
259
260 template<typename T>
262 decltype( json_data_contract<T>::to_json_data( std::declval<T &>( ) ) );
263
264 template<typename T>
265 inline constexpr bool has_json_to_json_data_v =
266 daw::is_detected<json_parser_to_json_data_t, T>::value;
267
268 template<typename T>
271
272 template<typename T>
273 inline constexpr bool is_submember_tagged_variant_v =
274 daw::is_detected<is_submember_tagged_variant_t, T>::value;
275
276 template<typename>
277 inline constexpr std::size_t parse_space_needed_v = 1U;
278
279 template<>
280 inline constexpr std::size_t parse_space_needed_v<simd_exec_tag> = 16U;
281
282 template<typename JsonType>
284 std::bool_constant<JsonType::expected_type == JsonParseTypes::Null>;
285
286 template<typename JsonType>
287 static inline constexpr bool is_json_nullable_v =
289 /***
290 * Helpers to set options on json_ types
291 */
292
293 template<json_options_t CurrentOptions, auto option, auto... options>
295 set_bits( class_opts, CurrentOptions, option, options... );
296
297 template<json_options_t CurrentOptions, auto option, auto... options>
299 set_bits( number_opts, CurrentOptions, option, options... );
300
301 template<json_options_t CurrentOptions, auto option, auto... options>
302 inline constexpr json_options_t bool_opts_set =
303 set_bits( bool_opts, CurrentOptions, option, options... );
304
305 template<json_options_t CurrentOptions, auto option, auto... options>
307 set_bits( string_opts, CurrentOptions, option, options... );
308
309 template<json_options_t CurrentOptions, auto option, auto... options>
311 set_bits( string_raw_opts, CurrentOptions, option, options... );
312
313 template<json_options_t CurrentOptions, auto option, auto... options>
315 set_bits( json_custom_opts, CurrentOptions, option, options... );
316
317 template<json_options_t CurrentOptions, auto option, auto... options>
319 set_bits( tuple_opts, CurrentOptions, option, options... );
320 } // namespace json_details
321
322 namespace json_base {
323 template<typename T, typename Constructor = default_constructor<T>,
324 json_details::json_options_t Options = class_opts_def>
325 struct json_class;
326
327 template<typename T, typename Constructor = nullable_constructor<T>,
328 json_details::json_options_t Options = class_opts_def>
330 json_class<T, Constructor,
331 json_details::class_opts_set<Options, JsonNullDefault>>;
332
333 template<typename JsonElement, typename Container,
334 typename Constructor = default_constructor<Container>,
336 struct json_array;
337
338 template<typename JsonElement, typename Container,
339 typename Constructor = nullable_constructor<Container>>
342
343 template<typename T,
345 typename Constructor = default_constructor<T>>
346 struct json_string_raw;
347
348 template<typename T,
350 typename Constructor = nullable_constructor<T>>
352 T, json_details::string_raw_opts_set<Options, JsonNullDefault>,
353 Constructor>;
354
355 template<typename T,
357 typename Constructor = default_constructor<T>>
358 struct json_string;
359
360 template<typename T,
362 typename Constructor = nullable_constructor<T>>
365 Constructor>;
366
367 template<typename T, json_details::json_options_t Options = bool_opts_def,
368 typename Constructor = default_constructor<T>>
369 struct json_bool;
370
371 template<typename T, json_details::json_options_t Options = bool_opts_def,
372 typename Constructor = nullable_constructor<T>>
375 Constructor>;
376
377 template<typename T,
379 typename Constructor = default_constructor<T>>
380 struct json_number;
381
382 template<typename T,
384 typename Constructor = nullable_constructor<T>>
387 Constructor>;
388
389 template<typename Container, typename JsonValueType, typename JsonKeyType,
390 typename Constructor = default_constructor<Container>,
392 struct json_key_value;
393
394 template<typename Container, typename JsonValueType, typename JsonKeyType,
395 typename Constructor = nullable_constructor<Container>>
397 json_key_value<Container, JsonValueType, JsonKeyType, Constructor,
399
400 template<typename Tuple,
401 typename Constructor = default_constructor<Tuple>,
403 typename JsonTupleTypesList = json_deduce_type>
404 struct json_tuple;
405
406 template<typename Tuple,
407 typename Constructor = nullable_constructor<Tuple>,
409 typename JsonTupleTypesList = json_deduce_type>
411 json_tuple<Tuple, Constructor,
412 json_details::tuple_opts_set<Options, JsonNullDefault>,
413 JsonTupleTypesList>;
414
415 /***
416 * json_raw allows for raw JSON access to the member data. It requires a
417 * type that is constructable from (char const *, std::size_t) arguments
418 * and for serialization requires that it can be passed to
419 * std::begin/std::end and the iterator returned has a value_type of char
420 * @tparam T type to hold raw JSON data, defaults to json_value
421 * @tparam Constructor A callable used to construct T.
422 * @tparam Nullable Does the value have to exist in the document or can it
423 * have a null value
424 */
425 template<typename T, typename Constructor = default_constructor<T>,
426 JsonNullable Nullable = JsonNullable::MustExist>
427 struct json_raw;
428
429 /***
430 * json_raw_null allows for raw JSON access to the nullable member data.
431 * It requires a type that is constructable from (char const *,
432 * std::size_t) arguments and for serialization requires that it can be
433 * passed to std::begin/std::end and the iterator returned has a
434 * value_type of char
435 * @tparam T type to hold raw JSON data, defaults to json_value
436 * @tparam Constructor A callable used to construct T.
437 */
438 template<typename T, typename Constructor = nullable_constructor<T>>
440 } // namespace json_base
441
442 namespace json_details {
443 template<typename T>
445 static_assert( daw::is_arithmetic<T>::value, "Unexpected non-number" );
446 if constexpr( daw::is_floating_point<T>::value ) {
448 } else if constexpr( daw::is_signed<T>::value ) {
450 } else if constexpr( daw::is_unsigned<T>::value ) {
452 }
453 }( );
454
455 template<typename T>
456 constexpr auto number_parse_type_test( )
457 -> std::enable_if_t<std::is_enum<T>::value, JsonParseTypes> {
458
459 return number_parse_type_impl_v<std::underlying_type_t<T>>;
460 }
461 template<typename T>
462 constexpr auto number_parse_type_test( )
463 -> std::enable_if_t<not std::is_enum<T>::value, JsonParseTypes> {
464
465 return number_parse_type_impl_v<T>;
466 }
467
468 template<typename T>
469 inline constexpr JsonParseTypes
470 number_parse_type_v = number_parse_type_test<T>( );
471
472 template<typename, typename = void>
474 static constexpr bool is_null = false;
476
477 static constexpr bool type_map_found = false;
478 };
479
480 template<typename JsonType>
482 JsonType, std::enable_if_t<json_details::is_a_json_type_v<JsonType>>> {
483 static constexpr bool is_null = false;
485
486 using type = JsonType;
487 static constexpr bool type_map_found = true;
488 };
489
490 template<typename T>
491 struct json_deduced_type_map<
492 T, std::enable_if_t<json_details::has_json_data_contract_trait_v<T>>> {
493 static constexpr bool is_null = false;
494 using type = typename json_data_contract<T>::type;
496
497 static constexpr bool type_map_found = true;
498 };
499
500 template<>
501 struct json_deduced_type_map<daw::string_view> {
502 static constexpr bool is_null = false;
504
505 static constexpr bool type_map_found = true;
506 };
507
508 template<>
509 struct json_deduced_type_map<std::string_view> {
510 static constexpr bool is_null = false;
512
513 static constexpr bool type_map_found = true;
514 };
515
516 template<>
517 struct json_deduced_type_map<std::string> {
518 static constexpr bool is_null = false;
519 static constexpr JsonParseTypes parse_type =
521
522 static constexpr bool type_map_found = true;
523 };
524
525 template<>
527 static constexpr bool is_null = false;
529
530 static constexpr bool type_map_found = true;
531 };
532
533 // libc++ has a non-conforming vector<bool>::const_reference as it isn't
534 // bool https://bugs.llvm.org/show_bug.cgi?id=16077
535#if defined( _LIBCPP_VERSION )
536 template<>
538 typename std::vector<bool>::const_reference> {
539
540 static constexpr bool is_null = false;
542
543 static constexpr bool type_map_found = true;
544 };
545#endif
546
547 template<typename Integer>
548 struct json_deduced_type_map<
549 Integer,
550 std::enable_if_t<std::conjunction_v<
551 not_trait<json_details::has_json_data_contract_trait<Integer>>,
552 daw::is_integral<Integer>>>> {
553 static constexpr bool is_null = false;
554 static constexpr JsonParseTypes parse_type =
555 daw::is_signed_v<Integer> ? JsonParseTypes::Signed
557
558 static constexpr bool type_map_found = true;
559 };
560
561 template<typename Enum>
562 struct json_deduced_type_map<
563 Enum, std::enable_if_t<std::conjunction_v<
564 not_trait<json_details::has_json_data_contract_trait<Enum>>,
565 std::is_enum<Enum>>>> {
566 static constexpr bool is_null = false;
567 static constexpr JsonParseTypes parse_type =
568 daw::is_signed_v<std::underlying_type<Enum>>
571
572 static constexpr bool type_map_found = true;
573 };
574
575 template<typename FloatingPoint>
576 struct json_deduced_type_map<
577 FloatingPoint,
578 std::enable_if_t<std::conjunction_v<
579 not_trait<json_details::has_json_data_contract_trait<FloatingPoint>>,
580 daw::is_floating_point<FloatingPoint>>>> {
581 static constexpr bool is_null = false;
583
584 static constexpr bool type_map_found = true;
585 };
586
587 template<typename Tuple>
588 struct json_deduced_type_map<
589 Tuple, std::enable_if_t<std::conjunction_v<
590 not_trait<json_details::has_json_data_contract_trait<Tuple>>,
591 is_tuple<Tuple>>>> {
592 static constexpr bool is_null = false;
594
595 static constexpr bool type_map_found = true;
596 };
597
598 namespace container_detect {
599 template<typename T>
600 using container_value_type = typename T::value_type;
601
602 template<typename Container>
604 decltype( std::begin( std::declval<Container const &>( ) ) );
605
606 template<typename Container>
608 decltype( std::end( std::declval<Container const &>( ) ) );
609
610 template<typename T>
611 inline constexpr bool container_detect_v =
612 std::conjunction_v<daw::is_detected<container_value_type, T>,
613 daw::is_detected<container_begin_type, T>,
614 daw::is_detected<container_end_type, T>>;
615
616 template<typename AssociativeContainer>
617 using container_key_type = typename AssociativeContainer::key_type;
618
619 template<typename AssociativeContainer>
621 typename AssociativeContainer::mapped_type;
622
623 template<typename T>
624 using is_value_type_char = std::is_same<char, container_value_type<T>>;
625
626 } // namespace container_detect
627 template<typename T>
628 using is_container = std::conjunction<
629 daw::is_detected<container_detect::container_value_type, T>,
630 daw::is_detected<container_detect::container_begin_type, T>,
631 daw::is_detected<container_detect::container_end_type, T>>;
632
633 template<typename Container>
635
636 template<typename String>
637 using is_string =
638 std::conjunction<is_container<String>,
640
641 template<typename String>
642 inline constexpr bool is_string_v = is_string<String>::value;
643
644 template<typename AssociativeContainer>
645 using is_associative_container = std::conjunction<
648 AssociativeContainer>,
650 AssociativeContainer>>;
651
652 template<typename AssociativeContainer>
653 inline constexpr bool is_associative_container_v =
655
656 template<typename AssociativeContainer>
658 AssociativeContainer,
659 std::enable_if_t<std::conjunction_v<
660 not_trait<has_json_data_contract_trait<AssociativeContainer>>,
661 is_associative_container<AssociativeContainer>>>> {
662
663 static constexpr bool is_null = false;
664 using key = typename AssociativeContainer::key_type;
665 using value = typename AssociativeContainer::mapped_type;
667
668 static constexpr bool type_map_found = true;
669 };
670
671 template<typename Container>
672 struct json_deduced_type_map<
673 Container, std::enable_if_t<std::conjunction_v<
674 not_trait<has_json_data_contract_trait<Container>>,
675 not_trait<is_associative_container<Container>>,
676 json_details::is_container<Container>,
677 not_trait<is_string<Container>>>>> {
678
679 static constexpr bool is_null = false;
680 using value = typename Container::value_type;
682
683 static constexpr bool type_map_found = true;
684 };
685
686 template<typename T>
687 struct json_deduced_type_map<
688 std::optional<T>,
689 std::enable_if_t<std::conjunction_v<
690 not_trait<has_json_data_contract_trait<std::optional<T>>>,
691 daw::is_detected<json_deduced_type_map, T>>>> {
692
693 static constexpr bool is_null = true;
694 using type = json_deduced_type_map<T>;
695 static constexpr JsonParseTypes parse_type = type::parse_type;
696
697 static constexpr bool type_map_found = true;
698 };
699
700 template<typename T>
702 std::bool_constant<json_deduced_type_map<T>::type_map_found>;
703
704 template<typename T>
705 inline constexpr bool has_deduced_type_mapping_v =
707
708 template<typename Mapped, bool Found = true>
709 struct json_link_quick_map_type : std::bool_constant<Found> {
710 using mapped_type = Mapped;
711 };
712
713 template<auto Value, auto... Values>
715 std::bool_constant<( ( Value == Values ) or ... )>;
716
717 template<auto Value, auto... Values>
718 inline constexpr bool equal_to_one_of_v =
719 equal_to_one_of<Value, Values...>::value;
720
721 template<typename T>
722 inline constexpr auto json_link_quick_map( ) {
723 if constexpr( is_a_json_type_v<T> ) {
725 } else if constexpr( has_deduced_type_mapping_v<T> ) {
726 using mapped_type_t = json_deduced_type_map<T>;
727 using parse_type = daw::constant<mapped_type_t::parse_type>;
728 using is_null = daw::constant<mapped_type_t::is_null>;
729 if constexpr( parse_type::value == JsonParseTypes::Unknown ) {
730 if constexpr( is_null::value ) {
732 } else {
734 }
735 } else if constexpr( parse_type::value ==
737 if constexpr( is_null::value ) {
740 } else {
742 }
743 } else if constexpr( parse_type::value ==
745 if constexpr( is_null::value ) {
748 } else {
750 }
751 } else if constexpr( parse_type::value == JsonParseTypes::Bool ) {
752 if constexpr( is_null::value ) {
754 } else {
756 }
757 } else if constexpr( equal_to_one_of_v<parse_type::value,
761 if constexpr( is_null::value ) {
764 } else {
766 }
767 } else if constexpr( parse_type::value == JsonParseTypes::Tuple ) {
768 if constexpr( is_null::value ) {
770 } else {
772 }
773 } else if constexpr( parse_type::value == JsonParseTypes::KeyValue ) {
774 if constexpr( is_null::value ) {
775 using b_t = typename mapped_type_t::base_type;
776 using k_t = typename b_t::key;
777 using v_t = typename b_t::value;
780 } else {
781 using k_t = typename mapped_type_t::key;
782 using v_t = typename mapped_type_t::value;
785 }
786 } else if constexpr( parse_type::value == JsonParseTypes::Array ) {
787 if constexpr( is_null::value ) {
788 using b_t = typename mapped_type_t::base_type;
789 using v_t = typename b_t::value;
792 } else {
793 using v_t = typename mapped_type_t::value;
795 }
796 } else {
798 }
799 } else {
801 }
802 }
803
804 /***
805 * Check if the current type has a quick map specialized for it
806 */
807 template<typename T>
808 using has_json_link_quick_map = decltype( json_link_quick_map<T>( ) );
809
810 template<typename T>
811 inline constexpr bool has_json_link_quick_map_v =
813
814 /***
815 * Get the quick mapped json type for type T
816 */
817 template<typename T>
819 typename decltype( json_link_quick_map<T>( ) )::mapped_type;
820
821 namespace vector_detect {
822 template<typename T>
823 struct vector_test {
824 struct not_vector {};
825 static constexpr bool value = false;
827 };
828
829 template<typename T, typename Alloc>
830 struct vector_test<std::vector<T, Alloc>> {
831 static constexpr bool value = true;
832 using type = T;
833 };
834
835 template<typename T>
837 } // namespace vector_detect
838
839 template<typename T>
840 using is_vector =
841 std::bool_constant<vector_detect::vector_test<T>::value>;
842
843 template<typename JsonType>
846 };
847
848 template<typename JsonType>
851
852 template<typename JsonType>
853 using json_class_map_type_test = typename JsonType::json_member;
854
855 template<typename>
856 struct is_json_class_map : std::false_type {};
857
858 template<typename T>
859 inline constexpr bool is_json_class_map_v =
860 std::conjunction_v<has_json_data_contract_trait<T>,
862
863 template<typename T, bool Ordered, bool Contract, bool JsonType,
864 bool QuickMap, bool Container>
867 };
868
869 template<typename T, /* typename Ordered, */ bool Contract, bool JsonType,
870 bool QuickMap, bool Container>
871 struct json_type_deducer<T, true, Contract, JsonType, QuickMap,
872 Container> {
873
874 using type = T;
875 };
876
877 template<typename T>
878 using parse_to_t_test = typename T::parse_to_t;
879
880 template<typename T>
884 };
885
886 template<typename T, /*typename Contract,*/ bool JsonType, bool QuickMap,
887 bool Container>
888 struct json_type_deducer<T, false, true, JsonType, QuickMap, Container> {
889
890 static_assert( not std::is_same_v<T, void> );
891 /*
892 using type = typename std::conditional_t<is_json_class_map_v<T>,
893 json_class_map_type<T>,
894 as_json_class<T>>::type;
895 */
898
899 static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
900 "Detection failure" );
901 static_assert(
902 not std::is_same_v<daw::remove_cvref_t<type>, daw::nonesuch>,
903 "Detection failure" );
904 };
905
906 template<typename T,
907 /*bool Contract, bool JsonType,*/ bool QuickMap, bool Container>
908 struct json_type_deducer<T, false, false, true, QuickMap, Container> {
909 static_assert( not std::is_same_v<T, void> );
910 using type =
911 typename std::conditional_t<is_json_class_map_v<T>,
913 daw::traits::identity<T>>::type;
914 static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
915 "Detection failure" );
916 static_assert(
917 not std::is_same_v<daw::remove_cvref_t<type>, daw::nonesuch>,
918 "Detection failure" );
919 };
920
921 template<typename T /*bool Contract, bool JsonType, bool QuickMap*/,
922 bool Container>
923 struct json_type_deducer<T, false, false, false, true, Container> {
924 static_assert( not std::is_same_v<T, void> );
926 static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
927 "Detection failure" );
928 static_assert(
929 not std::is_same_v<daw::remove_cvref_t<type>, daw::nonesuch>,
930 "Detection failure" );
931 static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
932 "Detection failure" );
933 };
934
935 template<typename T
936 /*bool Contract, bool JsonType, bool QuickMap,bool Container*/>
937 struct json_type_deducer<T, false, false, false, false, true> {
938 static_assert( not std::is_same_v<T, void> );
940 static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
941 "Detection failure" );
942 static_assert(
943 not std::is_same_v<daw::remove_cvref_t<type>, daw::nonesuch>,
944 "Detection failure" );
945 static_assert( not std::is_same_v<daw::remove_cvref_t<type>, void>,
946 "Detection failure" );
947 };
948
949 template<typename T>
951 T, is_an_ordered_member_v<T>, has_json_data_contract_trait_v<T>,
952 json_details::is_a_json_type_v<T>, has_json_link_quick_map_v<T>,
953 is_container_v<T>>::type;
954
955 /***
956 * Some types cannot use construct_value or dont needed it.
957 */
958 template<typename ParsePolicy, typename JsonMember>
959 inline constexpr bool use_direct_construction_v =
960 ParsePolicy::exec_tag_t::always_rvo;
961 // TODO DAW implement this so that it work
962 /* or
963 ( not ParsePolicy::has_allocator and
964 is_default_constructor_v<
965 typename json_deduced_type<JsonMember>::constructor_t> );*/
966
967 template<typename T>
968 using has_json_deduced_type = daw::not_trait<
969 std::is_same<json_deduced_type<T>, missing_json_data_contract_for<T>>>;
970
971 template<typename T>
974
975 template<typename JsonMember>
977
978 template<typename Constructor, typename... Members>
980 Constructor{ }( std::declval<typename Members::parse_to_t &&>( )... ) );
981
982 template<typename Constructor, typename... Members>
984 daw::detected_t<json_class_parse_result_impl2, Constructor, Members...>;
985
986 template<typename Constructor, typename... Members>
987 using json_class_parse_result_t = daw::remove_cvref_t<
988 json_class_parse_result_impl<Constructor, Members...>>;
989
990 template<typename Constructor, typename... Members>
991 inline constexpr bool can_defer_construction_v =
992 std::is_invocable_v<Constructor, typename Members::parse_to_t...>;
993
994 template<typename JsonMember>
995 using dependent_member_t = typename JsonMember::dependent_member;
996
997 template<typename JsonMember>
998 inline constexpr bool has_dependent_member_v =
999 daw::is_detected_v<dependent_member_t, JsonMember>;
1000 } // namespace json_details
1001 } // namespace DAW_JSON_VER
1002} // namespace daw::json
ParseState & parse_state
Definition: daw_json_parse_class.h:182
typename AssociativeContainer::key_type container_key_type
Definition: daw_json_parse_common.h:617
typename AssociativeContainer::mapped_type container_mapped_type
Definition: daw_json_parse_common.h:621
typename T::value_type container_value_type
Definition: daw_json_parse_common.h:600
decltype(std::begin(std::declval< Container const & >())) container_begin_type
Definition: daw_json_parse_common.h:604
std::is_same< char, container_value_type< T > > is_value_type_char
Definition: daw_json_parse_common.h:624
constexpr bool container_detect_v
Definition: daw_json_parse_common.h:611
decltype(std::end(std::declval< Container const & >())) container_end_type
Definition: daw_json_parse_common.h:608
typename vector_test< T >::type vector_test_t
Definition: daw_json_parse_common.h:836
decltype(std::declval< Container & >().push_back(std::declval< Value >())) detect_push_back
Definition: daw_json_parse_common.h:185
typename json_class_map_type< JsonType >::type json_class_map_type_t
Definition: daw_json_parse_common.h:850
std::bool_constant< JsonType::expected_type==JsonParseTypes::Null > is_json_nullable
Definition: daw_json_parse_common.h:284
typename T::json_member ordered_member_subtype_test
Definition: daw_json_parse_common.h:47
constexpr bool has_json_to_json_data_v
Definition: daw_json_parse_common.h:265
constexpr bool has_json_data_contract_trait_v
Definition: daw_json_parse_common.h:180
decltype(std::declval< Allocator & >().allocate(size_t{ 1 })) has_allocate_test
Definition: daw_json_parse_common.h:163
decltype(Constructor{ }(std::declval< typename Members::parse_to_t && >()...)) json_class_parse_result_impl2
Definition: daw_json_parse_common.h:980
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:650
decltype(json_link_quick_map< T >()) has_json_link_quick_map
Definition: daw_json_parse_common.h:808
constexpr json_options_t string_opts_set
Definition: daw_json_parse_common.h:306
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:969
constexpr JsonParseTypes number_parse_type_v
Definition: daw_json_parse_common.h:470
constexpr json_options_t tuple_opts_set
Definition: daw_json_parse_common.h:318
constexpr json_options_t bool_opts_set
Definition: daw_json_parse_common.h:302
constexpr bool equal_to_one_of_v
Definition: daw_json_parse_common.h:718
constexpr bool has_push_back_v
Definition: daw_json_parse_common.h:192
constexpr bool has_unnamed_default_type_mapping_v
Definition: daw_json_parse_common.h:972
constexpr bool has_dependent_member_v
Definition: daw_json_parse_common.h:998
constexpr auto json_link_quick_map()
Definition: daw_json_parse_common.h:722
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:51
daw::detected_t< json_class_parse_result_impl2, Constructor, Members... > json_class_parse_result_impl
Definition: daw_json_parse_common.h:984
std::conjunction< is_container< String >, container_detect::is_value_type_char< String > > is_string
Definition: daw_json_parse_common.h:639
constexpr auto number_parse_type_test() -> std::enable_if_t< std::is_enum< T >::value, JsonParseTypes >
Definition: daw_json_parse_common.h:456
typename decltype(json_link_quick_map< T >())::mapped_type json_link_quick_map_t
Definition: daw_json_parse_common.h:819
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:631
static constexpr DAW_ATTRIB_FLATINLINE auto construct_value_tp(ParseState &parse_state, fwd_pack< Args... > &&tp_args)
Definition: daw_json_parse_common.h:126
constexpr bool is_allocator_v
Definition: daw_json_parse_common.h:171
constexpr auto json_class_constructor
Definition: daw_json_parse_common.h:54
constexpr bool is_string_v
Definition: daw_json_parse_common.h:642
typename JsonMember::dependent_member dependent_member_t
Definition: daw_json_parse_common.h:995
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:705
typename T::parse_to_t parse_to_t_test
Definition: daw_json_parse_common.h:878
decltype(json_data_contract< T >::to_json_data(std::declval< T & >())) json_parser_to_json_data_t
Definition: daw_json_parse_common.h:262
json_result< json_deduced_type< JsonMember > > from_json_result_t
Definition: daw_json_parse_common.h:976
constexpr bool is_submember_tagged_variant_v
Definition: daw_json_parse_common.h:273
typename json_data_contract< T >::type::i_am_a_submember_tagged_variant is_submember_tagged_variant_t
Definition: daw_json_parse_common.h:270
typename JsonType::json_member json_class_map_type_test
Definition: daw_json_parse_common.h:853
decltype(std::declval< Container & >().insert(std::end(std::declval< Container & >()), std::declval< Value >())) detect_insert_end
Definition: daw_json_parse_common.h:189
std::bool_constant< vector_detect::vector_test< T >::value > is_vector
Definition: daw_json_parse_common.h:841
constexpr bool has_insert_end_v
Definition: daw_json_parse_common.h:196
constexpr json_options_t string_raw_opts_set
Definition: daw_json_parse_common.h:310
constexpr std::size_t parse_space_needed_v< simd_exec_tag >
Definition: daw_json_parse_common.h:280
constexpr JsonParseTypes number_parse_type_impl_v
Definition: daw_json_parse_common.h:444
constexpr bool is_container_v
Definition: daw_json_parse_common.h:634
std::bool_constant< json_deduced_type_map< T >::type_map_found > has_deduced_type_mapping
Definition: daw_json_parse_common.h:702
constexpr auto construct_value_tp_invoke
Definition: daw_json_parse_common.h:120
decltype(std::declval< Allocator & >().deallocate(static_cast< void * >(nullptr), size_t{ 1 })) has_deallocate_test
Definition: daw_json_parse_common.h:168
constexpr json_options_t number_opts_set
Definition: daw_json_parse_common.h:298
constexpr bool is_associative_container_v
Definition: daw_json_parse_common.h:653
static constexpr DAW_ATTRIB_FLATINLINE auto construct_value(template_params< Value, Constructor >, ParseState &parse_state, Args &&...args)
Definition: daw_json_parse_common.h:60
constexpr std::size_t parse_space_needed_v
Definition: daw_json_parse_common.h:277
constexpr bool is_null(std::optional< T > const &v)
Definition: to_daw_json_string.h:951
typename JsonMember::parse_to_t json_result
Definition: daw_json_parse_common.h:200
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:178
static constexpr bool is_json_nullable_v
Definition: daw_json_parse_common.h:287
constexpr bool can_defer_construction_v
Definition: daw_json_parse_common.h:991
constexpr bool is_json_class_map_v
Definition: daw_json_parse_common.h:859
typename json_type_deducer< T, is_an_ordered_member_v< 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:953
daw::remove_cvref_t< json_class_parse_result_impl< Constructor, Members... > > json_class_parse_result_t
Definition: daw_json_parse_common.h:988
constexpr bool has_json_link_quick_map_v
Definition: daw_json_parse_common.h:811
constexpr json_options_t json_custom_opts_set
Definition: daw_json_parse_common.h:314
constexpr bool use_direct_construction_v
Definition: daw_json_parse_common.h:959
typename JsonMember::base_type json_base_type
Definition: daw_json_parse_common.h:203
daw::detected_or_t< Default, json_class_constructor_t_impl, T > json_class_constructor_t
Definition: daw_json_traits.h:516
constexpr json_options_t class_opts_set
Definition: daw_json_parse_common.h:294
std::bool_constant<((Value==Values) or ...)> equal_to_one_of
Definition: daw_json_parse_common.h:715
constexpr json_details::json_options_t string_opts_def
Definition: daw_json_type_options.h:163
JsonParseTypes
The tags used by the parser to determine what parser to call.
Definition: daw_json_enums.h:22
@ Array
A class type with named members.
@ Signed
Number - Floating Point.
@ Unknown
Array - An array type where each element is mapped to the member of a C++ class.
@ Unsigned
Number - Signed Integer.
@ Tuple
A variant type where the Switcher is based on a submember of the class being parsed.
@ StringEscaped
String - A raw string as is. Escapes are left in.
@ Bool
Number - Unsigned Integer.
constexpr auto bool_opts
Definition: daw_json_type_options.h:120
typename json_data_contract< T >::type json_data_contract_trait_t
Definition: daw_json_traits.h:135
constexpr auto string_raw_opts
Definition: daw_json_type_options.h:195
constexpr json_details::json_options_t tuple_opts_def
Definition: daw_json_type_options.h:219
JsonNullable
Definition: daw_json_enums.h:90
constexpr json_details::json_options_t class_opts_def
Definition: daw_json_type_options.h:208
constexpr json_details::json_options_t bool_opts_def
Definition: daw_json_type_options.h:121
basic_json_value(ParseState) -> basic_json_value< ParseState >
constexpr auto tuple_opts
Definition: daw_json_type_options.h:218
constexpr json_details::json_options_t string_raw_opts_def
Definition: daw_json_type_options.h:196
constexpr JsonNullable JsonNullDefault
Definition: daw_json_enums.h:96
constexpr auto json_custom_opts
Definition: daw_json_type_options.h:252
constexpr auto class_opts
Definition: daw_json_type_options.h:207
constexpr auto string_opts
Definition: daw_json_type_options.h:162
constexpr json_details::json_options_t number_opts_def
Definition: daw_json_type_options.h:108
constexpr auto number_opts
Definition: daw_json_type_options.h:107
Definition: daw_from_json.h:22
Definition: daw_from_json.h:22
Definition: daw_json_traits.h:199
Definition: daw_json_link_types.h:1251
Definition: daw_json_link_types.h:510
Definition: daw_json_link_types.h:810
Definition: daw_json_link_types.h:1454
Definition: daw_json_link_types.h:377
Definition: daw_json_link_types.h:1944
String - A raw string as is. Escapes are left in.
Definition: daw_json_link_types.h:582
Definition: daw_json_link_types.h:670
Definition: daw_json_link_types.h:1684
Definition: daw_json_link_types.h:858
Definition: daw_json_traits.h:127
Definition: daw_json_parse_common.h:881
Definition: daw_json_parse_common.h:206
Container * m_container
Definition: daw_json_parse_common.h:212
constexpr basic_appender & operator=(Value &&v)
Definition: daw_json_parse_common.h:242
value_type reference
Definition: daw_json_parse_common.h:208
constexpr basic_appender(Container &container)
Definition: daw_json_parse_common.h:214
constexpr basic_appender & operator*()
Definition: daw_json_parse_common.h:255
typename Container::value_type value_type
Definition: daw_json_parse_common.h:207
std::output_iterator_tag iterator_category
Definition: daw_json_parse_common.h:211
constexpr basic_appender & operator++()
Definition: daw_json_parse_common.h:247
constexpr basic_appender operator++(int)
Definition: daw_json_parse_common.h:251
value_type const * pointer
Definition: daw_json_parse_common.h:209
std::ptrdiff_t difference_type
Definition: daw_json_parse_common.h:210
Definition: daw_json_parse_common.h:856
Definition: daw_json_parse_common.h:844
typename json_data_contract_trait_t< JsonType >::json_member type
Definition: daw_json_parse_common.h:845
static constexpr JsonParseTypes parse_type
Definition: daw_json_parse_common.h:475
static constexpr bool is_null
Definition: daw_json_parse_common.h:474
static constexpr bool type_map_found
Definition: daw_json_parse_common.h:477
json_link_quick_map_t< T > type
Definition: daw_json_parse_common.h:925
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:913
Definition: daw_json_parse_common.h:865
missing_json_data_contract_for< T > type
Definition: daw_json_parse_common.h:866
static constexpr bool value
Definition: daw_json_parse_common.h:825
not_vector type
Definition: daw_json_parse_common.h:826
Definition: daw_json_traits.h:351
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:16