DAW JSON Link
daw_json_link_types_fwd.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_link_impl.h"
12 #include "daw_json_parse_name.h"
14 
15 #include <daw/cpp_17.h>
16 #include <daw/daw_arith_traits.h>
17 #include <daw/daw_traits.h>
18 #include <daw/daw_utility.h>
19 
20 #include <chrono>
21 #include <ciso646>
22 #include <optional>
23 #include <string>
24 
25 namespace daw::json {
26 
37  template<JSONNAMETYPE Name, typename T = double,
38  LiteralAsStringOpt LiteralAsString = LiteralAsStringOpt::Never,
39  typename Constructor = default_constructor<T>,
40  JsonRangeCheck RangeCheck = JsonRangeCheck::Never,
41  JsonNullable Nullable = JsonNullable::Never>
42  struct json_number;
43 
53  template<JSONNAMETYPE Name, typename T = std::optional<double>,
54  LiteralAsStringOpt LiteralAsString = LiteralAsStringOpt::Never,
55  typename Constructor = nullable_constructor<T>,
56  JsonRangeCheck RangeCheck = JsonRangeCheck::Never>
57  using json_number_null = json_number<Name, T, LiteralAsString, Constructor,
58  RangeCheck, JsonNullable::Nullable>;
59 
69  template<JSONNAMETYPE Name, typename T = double,
70  LiteralAsStringOpt LiteralAsString = LiteralAsStringOpt::Never,
71  typename Constructor = default_constructor<T>,
72  JsonNullable Nullable = JsonNullable::Never>
74  json_number<Name, T, LiteralAsString, Constructor,
76 
85  template<JSONNAMETYPE Name, typename T = std::optional<double>,
86  LiteralAsStringOpt LiteralAsString = LiteralAsStringOpt::Never,
87  typename Constructor = nullable_constructor<T>>
89  json_number<Name, T, LiteralAsString, Constructor,
91 
100  template<JSONNAMETYPE Name, typename T = bool,
101  LiteralAsStringOpt LiteralAsString = LiteralAsStringOpt::Never,
102  typename Constructor = default_constructor<T>,
103  JsonNullable Nullable = JsonNullable::Never>
104  struct json_bool;
105 
113  template<JSONNAMETYPE Name, typename T = std::optional<bool>,
114  LiteralAsStringOpt LiteralAsString = LiteralAsStringOpt::Never,
115  typename Constructor = nullable_constructor<T>>
118 
134  template<JSONNAMETYPE Name, typename String = std::string,
135  typename Constructor = default_constructor<String>,
136  JsonNullable EmptyStringNull = JsonNullable::Never,
138  JsonNullable Nullable = JsonNullable::Never,
139  AllowEscapeCharacter AllowEscape = AllowEscapeCharacter::Allow>
140  struct json_string_raw;
141 
156  template<JSONNAMETYPE Name, typename String = std::optional<std::string>,
157  typename Constructor = nullable_constructor<String>,
158  JsonNullable EmptyStringNull = JsonNullable::Nullable,
159  EightBitModes EightBitMode = EightBitModes::AllowFull,
160  AllowEscapeCharacter AllowEscape = AllowEscapeCharacter::Allow>
162  json_string_raw<Name, String, Constructor, EmptyStringNull, EightBitMode,
163  JsonNullable::Nullable, AllowEscape>;
164 
177  template<JSONNAMETYPE Name, typename String = std::string,
178  typename Constructor = default_constructor<String>,
179  JsonNullable EmptyStringNull = JsonNullable::Never,
181  JsonNullable Nullable = JsonNullable::Never>
182  struct json_string;
183 
195  template<JSONNAMETYPE Name, typename String = std::optional<std::string>,
196  typename Constructor = nullable_constructor<String>,
197  JsonNullable EmptyStringNull = JsonNullable::Never,
198  EightBitModes EightBitMode = EightBitModes::AllowFull>
200  json_string<Name, String, Constructor, EmptyStringNull, EightBitMode,
202 
212  template<JSONNAMETYPE Name,
213  typename T = std::chrono::time_point<std::chrono::system_clock,
214  std::chrono::milliseconds>,
215  typename Constructor =
217  JsonNullable Nullable = JsonNullable::Never>
218  struct json_date;
219 
227  template<JSONNAMETYPE Name,
228  typename T = std::optional<std::chrono::time_point<
229  std::chrono::system_clock, std::chrono::milliseconds>>,
230  typename Constructor =
234 
244  template<JSONNAMETYPE Name, typename T,
245  typename Constructor = default_constructor<T>,
246  JsonNullable Nullable = JsonNullable::Never>
247  struct json_class;
248 
257  template<JSONNAMETYPE Name, typename T,
258  typename Constructor = nullable_constructor<T>>
261 
262  namespace json_details {
274  template<JSONNAMETYPE Name, typename JsonElement, typename Container,
275  typename Constructor = default_constructor<Container>,
276  JsonNullable Nullable = JsonNullable::Never>
277  struct json_array_detect;
278 
279  namespace vector_detect {
280  struct not_vector {};
281  template<typename T, typename... Alloc>
282  [[maybe_unused]] auto vector_test( daw::tag_t<std::vector<T, Alloc...>> )
283  -> T;
284 
285  template<typename T>
286  [[maybe_unused]] not_vector vector_test( daw::tag_t<T> );
287 
288  template<typename T>
289  using detector =
290  std::remove_reference_t<decltype( vector_test( daw::tag<T> ) )>;
291  } // namespace vector_detect
292 
293  template<typename T>
294  using is_vector = daw::not_trait<
295  std::is_same<vector_detect::detector<T>, vector_detect::not_vector>>;
296  } // namespace json_details
297 
298  template<typename Mapped, bool Found = true>
299  struct json_link_quick_map_type : std::bool_constant<Found> {
300  using mapped_type = Mapped;
301  };
302 
303  template<JSONNAMETYPE Name, typename T>
304  DAW_ATTRIBUTE_HIDDEN inline constexpr auto json_link_quick_map( ) {
305  if constexpr( std::is_same_v<T, std::string_view> ) {
308  } else if constexpr( std::is_same_v<T, daw::string_view> ) {
311  } else if constexpr( std::is_same_v<T, std::string> ) {
313  } else if constexpr( std::is_same_v<T, bool> ) {
315  } else {
317  }
318  }
319  /***
320  * Check if the current type has a quick map specialized for it
321  */
322  template<typename T>
323  inline constexpr bool has_json_link_quick_map_v =
324  decltype( json_link_quick_map<no_name, T>( ) )::value;
325 
326  /***
327  * Get the quick mapped json type for type T
328  */
329  template<JSONNAMETYPE Name, typename T>
331  typename decltype( json_link_quick_map<Name, T>( ) )::mapped_type;
332 
333  namespace json_details {
334  template<typename T, JSONNAMETYPE Name = no_name>
335  using unnamed_default_type_mapping = daw::if_t<
336  json_details::is_a_json_type_v<T>, T,
337  daw::if_t<
338  has_json_data_contract_trait_v<T>, json_class<Name, T>,
339  daw::if_t<
340  has_json_link_quick_map_v<T>, json_link_quick_map_t<Name, T>,
341  daw::if_t<
342  std::disjunction_v<daw::is_arithmetic<T>, std::is_enum<T>>,
344  daw::if_t<std::conjunction_v<cant_deref<T>, is_vector<T>>,
345  json_array_detect<Name, vector_detect::detector<T>, T>,
347 
348  template<typename T>
349  using has_unnamed_default_type_mapping = daw::not_trait<
350  std::is_same<unnamed_default_type_mapping<T>,
352  } // namespace json_details
353 
354  /***
355  * A type to hold the types for parsing tagged variants.
356  * @tparam JsonElements a list of types that can be parsed,
357  */
358  template<typename... JsonElements>
362  std::tuple<json_details::unnamed_default_type_mapping<JsonElements>...>;
363  };
364 
376  template<JSONNAMETYPE Name, typename JsonElement,
377  typename Container =
378  std::vector<typename json_details::unnamed_default_type_mapping<
379  JsonElement>::parse_to_t>,
380  typename Constructor = default_constructor<Container>,
381  JsonNullable Nullable = JsonNullable::Never>
382  struct json_array;
383 
394  template<JSONNAMETYPE Name, typename JsonElement,
395  typename Container =
396  std::vector<typename json_details::unnamed_default_type_mapping<
397  JsonElement>::parse_to_t>,
398  typename Constructor = nullable_constructor<Container>>
399  using json_array_null = json_array<Name, JsonElement, Container, Constructor,
401 
416  template<JSONNAMETYPE Name, typename Container, typename JsonValueType,
417  typename JsonKeyType = json_string<no_name>,
418  typename Constructor = default_constructor<Container>,
419  JsonNullable Nullable = JsonNullable::Never>
420  struct json_key_value;
421 
435  template<JSONNAMETYPE Name, typename Container, typename JsonValueType,
436  typename JsonKeyType = json_string<no_name>,
437  typename Constructor = nullable_constructor<Container>>
439  json_key_value<Name, Container, JsonValueType, JsonKeyType, Constructor,
441 
457  template<JSONNAMETYPE Name, typename Container, typename JsonValueType,
458  typename JsonKeyType,
459  typename Constructor = default_constructor<Container>,
460  JsonNullable Nullable = JsonNullable::Never>
461  struct json_key_value_array;
462 
477  template<JSONNAMETYPE Name, typename Container, typename JsonValueType,
478  typename JsonKeyType,
479  typename Constructor = nullable_constructor<Container>>
481  json_key_value_array<Name, Container, JsonValueType, JsonKeyType,
482  Constructor, JsonNullable::Nullable>;
483 
496  template<JSONNAMETYPE Name, typename T,
497  typename FromJsonConverter = custom_from_converter_t<T>,
498  typename ToJsonConverter = custom_to_converter_t<T>,
499  CustomJsonTypes CustomJsonType = CustomJsonTypes::Either,
500  JsonNullable Nullable = JsonNullable::Never>
501  struct json_custom;
502 
512  template<JSONNAMETYPE Name, typename T,
513  typename FromConverter = custom_from_converter_t<T>,
514  typename ToConverter = custom_to_converter_t<T>,
515  CustomJsonTypes CustomJsonType = CustomJsonTypes::Either>
516  using json_custom_null = json_custom<Name, T, FromConverter, ToConverter,
517  CustomJsonType, JsonNullable::Nullable>;
518 
519  namespace json_details {
520 
521  template<JsonBaseParseTypes PT>
522  constexpr std::size_t
523  find_json_element( std::initializer_list<JsonBaseParseTypes> pts ) {
524  std::size_t idx = 0;
525  for( auto const &pt : pts ) {
526  if( pt == PT ) {
527  return idx;
528  }
529  ++idx;
530  }
531  return daw::numeric_limits<std::size_t>::max( );
532  }
533 
534  } // namespace json_details
535 
536  /***
537  * Link to a variant like data type. The JSON member can be any one of the
538  * json types. This precludes having more than one class type or array
539  * type(including their specialized keyvalue mappings) or
540  * string-enum/int-enum.
541  * @tparam Name name of JSON member to link to
542  * @tparam T type of value to construct
543  * @tparam JsonElements a json_variant_type_list
544  * @tparam Constructor A callable used to construct T. The
545  * default supports normal and aggregate construction
546  * @tparam Nullable Can the member be missing or have a null value *
547  */
548  template<JSONNAMETYPE Name, typename T, typename JsonElements,
549  typename Constructor = default_constructor<T>,
550  JsonNullable Nullable = JsonNullable::Never>
551  struct json_variant;
552 
553  /***
554  * Link to a nullable JSON variant
555  * @tparam Name name of JSON member to link to
556  * @tparam T type that has specialization of
557  * daw::json::json_data_contract
558  * @tparam JsonElements a json_variant_type_list
559  * @tparam Constructor A callable used to construct T. The
560  * default supports normal and aggregate construction
561  */
562  template<JSONNAMETYPE Name, typename T, typename JsonElements,
563  typename Constructor = nullable_constructor<T>>
566 
567  namespace json_details {
568  template<typename T>
569  struct unknown_variant_type {
570  using i_am_tagged_variant_type_list = void;
571  };
572 
573  template<typename... Ts>
574  struct missing_default_type_mapping {
575  using i_am_tagged_variant_type_list = void;
576  };
577 
578  template<typename... Ts>
579  [[maybe_unused]] constexpr std::conditional_t<
580  std::conjunction_v<has_unnamed_default_type_mapping<Ts>...>,
582  missing_default_type_mapping<unnamed_default_type_mapping<Ts>...>>
583  get_variant_type_list( std::variant<Ts...> const * );
584 
585  template<typename T>
586  using underlying_nullable_type = decltype( *std::declval<T>( ) );
587 
588  template<typename T>
589  using detected_underlying_nullable_type =
590  std::remove_reference_t<daw::detected_t<underlying_nullable_type, T>>;
591 
592  template<typename T>
593  inline constexpr bool is_nullable_type =
594  daw::is_detected_v<underlying_nullable_type, T>;
595 
596  template<typename T>
597  [[maybe_unused]] constexpr unknown_variant_type<T>
598  get_variant_type_list( T const * );
599 
600  struct cannot_deduce_variant_element_types {};
601 
602  template<JsonNullable Nullable, typename Variant>
603  using determine_variant_element_types = std::conditional_t<
604  Nullable == JsonNullable::Never or not is_nullable_type<Variant>,
605  std::remove_reference_t<decltype( get_variant_type_list(
606  std::declval<Variant const *>( ) ) )>,
607  std::conditional_t<
608  is_nullable_type<Variant>,
609  std::remove_reference_t<decltype( get_variant_type_list(
610  std::declval<
611  detected_underlying_nullable_type<Variant> const *>( ) ) )>,
612  cannot_deduce_variant_element_types>>;
613  } // namespace json_details
614 
615  /***
616  * Link to a variant like data type that is discriminated via another member.
617  * @tparam Name name of JSON member to link to
618  * @tparam T type of value to construct
619  * @tparam TagMember JSON element to pass to Switcher. Does not have to be
620  * declared in member list
621  * @tparam Switcher A callable that returns an index into JsonElements when
622  * passed the TagMember object in parent member list
623  * @tparam JsonElements a json_tagged_variant_type_list, defaults to type
624  * elements of T when T is a std::variant and they are all auto mappable
625  * @tparam Constructor A callable used to construct T. The
626  * default supports normal and aggregate construction
627  * @tparam Nullable Can the member be missing or have a null value *
628  */
629  template<
630  JSONNAMETYPE Name, typename T, typename TagMember, typename Switcher,
631  typename JsonElements =
632  json_details::determine_variant_element_types<JsonNullable::Never, T>,
633  typename Constructor = default_constructor<T>,
634  JsonNullable Nullable = JsonNullable::Never>
635  struct json_tagged_variant;
636 
637  /***
638  * Link to a nullable variant like data type that is discriminated via another
639  * member.
640  * @tparam Name name of JSON member to link to
641  * @tparam T type of value to construct
642  * @tparam TagMember JSON element to pass to Switcher. Does not have to be
643  * declared in member list
644  * @tparam Switcher A callable that returns an index into JsonElements when
645  * passed the TagMember object in parent member list
646  * @tparam JsonElements a json_tagged_variant_type_list, defaults to type
647  * elements of T when T is a std::variant and they are all auto mappable
648  * @tparam Constructor A callable used to construct T. The
649  * default supports normal and aggregate construction
650  */
651  template<
652  JSONNAMETYPE Name, typename T, typename TagMember, typename Switcher,
653  typename JsonElements =
654  json_details::determine_variant_element_types<JsonNullable::Nullable, T>,
655  typename Constructor = nullable_constructor<T>>
657  json_tagged_variant<Name, T, TagMember, Switcher, JsonElements, Constructor,
659 } // namespace daw::json
daw::json::json_tagged_variant_type_list
Definition: daw_json_link_types_fwd.h:359
daw::json::json_tagged_variant
Definition: daw_json_link.h:529
daw::json
Definition: daw_json_event_parser.h:17
daw::json::json_date
Definition: daw_json_link.h:401
daw_json_parse_value_fwd.h
daw::json::json_string_raw
Definition: daw_json_link.h:334
daw::json::EightBitModes
EightBitModes
Definition: daw_json_parse_common.h:411
daw::json::json_tagged_variant_type_list::element_map_t
std::tuple< json_details::unnamed_default_type_mapping< JsonElements >... > element_map_t
Definition: daw_json_link_types_fwd.h:362
daw::json::json_tagged_variant_type_list::i_am_tagged_variant_type_list
void i_am_tagged_variant_type_list
Definition: daw_json_link_types_fwd.h:360
daw::json::json_string
Definition: daw_json_link.h:371
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::json_custom
Definition: daw_json_link.h:571
daw::json::nullable_constructor
Definition: daw_json_traits.h:103
daw::json::json_key_value
Definition: daw_json_link.h:685
daw::json::custom_from_converter_t
Definition: daw_json_link_impl.h:75
daw::json::LiteralAsStringOpt
LiteralAsStringOpt
Definition: daw_json_parse_common.h:503
JSONNAMETYPE
#define JSONNAMETYPE
Definition: daw_json_parse_common.h:346
daw::json::JsonRangeCheck::Never
@ Never
daw::json::EightBitModes::DisallowHigh
@ DisallowHigh
daw::json::json_number
Definition: daw_json_link.h:257
daw::json::JsonNullable::Never
@ Never
daw::json::JsonNullable
JsonNullable
Definition: daw_json_parse_common.h:409
daw::json::JsonRangeCheck
JsonRangeCheck
Definition: daw_json_parse_common.h:410
daw::json::json_key_value_array
Definition: daw_json_link.h:732
daw::json::json_bool
Definition: daw_json_link.h:296
daw::json::has_json_link_quick_map_v
constexpr bool has_json_link_quick_map_v
Definition: daw_json_link_types_fwd.h:323
daw_json_parse_name.h
daw::json::json_array
Definition: daw_json_link.h:643
daw::json::construct_from_iso8601_timestamp< JsonNullable::Never >
Definition: daw_json_link_impl.h:47
daw::json::CustomJsonTypes
CustomJsonTypes
Definition: daw_json_parse_common.h:412
daw::json::json_link_quick_map_t
typename decltype(json_link_quick_map< Name, T >())::mapped_type json_link_quick_map_t
Definition: daw_json_link_types_fwd.h:331
daw::json::json_variant
Definition: daw_json_link.h:490
daw::json::default_constructor
Definition: daw_json_traits.h:58
daw::json::json_class
Definition: daw_json_link.h:431
daw::json::json_link_quick_map
constexpr DAW_ATTRIBUTE_HIDDEN auto json_link_quick_map()
Definition: daw_json_link_types_fwd.h:304
daw::json::CustomJsonTypes::Literal
@ Literal
daw::json::custom_to_converter_t
Definition: daw_json_to_string.h:87
daw::json::construct_from_iso8601_timestamp< JsonNullable::Nullable >
Definition: daw_json_link_impl.h:58