DAW JSON Link
daw_json_traits.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/daw_traits.h>
12 
13 #include <memory>
14 #include <optional>
15 #include <string>
16 #include <type_traits>
17 #include <unordered_map>
18 #include <utility>
19 
20 /***
21  * Customization point traits
22  *
23  */
24 namespace daw::json {
25 
26  /***
27  * This class is used as a way to indicate that a json_data_contract
28  * specialization has not been done for a user class.
29  */
30  template<typename>
32 
33  /***
34  * Mapping class for JSON data structures to C++. It must be specialized in
35  * order to parse to a user class
36  * @tparam T Class to map
37  */
38  template<typename T>
41  };
42 
43  /***
44  * This trait can be specialized such that when class being returned has
45  * non-move/copyable members the construction can be done with { } instead of
46  * a callable. This is a blunt object and probably should not be used
47  * @tparam T type to specialize
48  */
49  template<typename T>
50  struct force_aggregate_construction : std::false_type {};
51 
52  /***
53  * Default Constructor for a type. It accounts for aggregate types and uses
54  * brace construction for them
55  * @tparam T type to construct
56  */
57  template<typename T>
59  template<typename... Args>
60  [[nodiscard]] inline constexpr auto operator( )( Args &&... args ) const
61  noexcept( std::is_nothrow_constructible_v<T, Args...> )
62  -> std::enable_if_t<std::is_constructible_v<T, Args...>, T> {
63 
64  return T( std::forward<Args>( args )... );
65  }
66 
67  template<typename... Args>
68  [[nodiscard]] inline constexpr auto operator( )( Args &&... args ) const
69  noexcept( daw::traits::is_nothrow_list_constructible_v<T, Args...> )
70  -> std::enable_if_t<(not std::is_constructible_v<T, Args...> and
71  daw::traits::is_list_constructible_v<T, Args...>),
72  T> {
73 
74  return T{ std::forward<Args>( args )... };
75  }
76  };
77 
78  template<typename K, typename V, typename H, typename E, typename Alloc>
79  struct default_constructor<std::unordered_map<K, V, H, E, Alloc>> {
80  inline std::unordered_map<K, V, H, E, Alloc> operator( )( ) const
81  noexcept( noexcept( std::unordered_map<K, V, H, E, Alloc>( ) ) ) {
82  return { };
83  }
84 
85  template<typename Iterator>
86  inline std::unordered_map<K, V, H, E, Alloc>
87  operator( )( Iterator first, Iterator last,
88  Alloc const &alloc = Alloc{ } ) const
89  noexcept( noexcept( std::unordered_map<K, V, H, E, Alloc>( first, last, 0,
90  H{ }, E{ },
91  alloc ) ) ) {
92  return std::unordered_map<K, V, H, E, Alloc>( first, last, 0, H{ }, E{ },
93  alloc );
94  }
95  };
96 
97  /***
98  * Auto generated constructor for nullable types.
99  * Specializations must accept accept an operator( )( ) that signifies a JSON
100  * null. Any other arguments only need to be valid to construct the type.
101  */
102  template<typename T>
104 
105  template<typename T>
106  struct nullable_constructor<std::optional<T>> {
107  using value_type = T;
108 
109  [[nodiscard]] DAW_ATTRIBUTE_FLATTEN constexpr std::optional<T>
110  operator( )( ) const noexcept {
111  return std::optional<T>( );
112  }
113 
114  template<typename... Args>
115  [[nodiscard]] DAW_ATTRIBUTE_FLATTEN inline constexpr auto
116  operator( )( Args &&... args ) const
117  noexcept( std::is_nothrow_constructible_v<std::optional<T>,
118  std::in_place_t, Args...> )
119  -> std::enable_if_t<
120  (( sizeof...( Args ) > 0 ) and
121  std::is_constructible_v<T, std::in_place_t, Args...>),
122  std::optional<T>> {
123 
124  return std::optional<T>( std::in_place, std::forward<Args>( args )... );
125  }
126 
127  template<typename... Args>
128  [[nodiscard]] DAW_ATTRIBUTE_FLATTEN inline constexpr auto
129  operator( )( Args &&... args ) const
130  noexcept( daw::traits::is_nothrow_list_constructible_v<T, Args...>
131  and std::is_nothrow_move_constructible_v<T> )
132  -> std::enable_if_t<
133  (( sizeof...( Args ) > 0 ) and
134  not std::is_constructible_v<T, std::in_place_t, Args...> and
135  daw::traits::is_list_constructible_v<T, Args...>),
136  std::optional<T>> {
137 
138  return std::optional<T>( T{ std::forward<Args>( args )... } );
139  }
140  };
141 
142  template<typename T, typename Deleter>
143  struct nullable_constructor<std::unique_ptr<T, Deleter>> {
144  using value_type = T;
145 
146  constexpr std::unique_ptr<T, Deleter> operator( )( ) const noexcept {
147  return std::unique_ptr<T, Deleter>{ };
148  }
149 
150  template<typename... Args>
151  [[nodiscard]] DAW_ATTRIBUTE_FLATTEN inline auto
152  operator( )( Args &&... args ) const
153  noexcept( std::is_nothrow_constructible_v<T, Args...> )
154  -> std::enable_if_t<(sizeof...( Args ) > 0 and
155  std::is_constructible_v<T, Args...>),
156  std::unique_ptr<T, Deleter>> {
157 
158  return std::unique_ptr<T, Deleter>(
159  new T( std::forward<Args>( args )... ) );
160  }
161 
162  template<typename... Args>
163  [[nodiscard]] DAW_ATTRIBUTE_FLATTEN inline auto
164  operator( )( Args &&... args ) const
165  noexcept( daw::traits::is_nothrow_list_constructible_v<T, Args...> )
166  -> std::enable_if_t<(( sizeof...( Args ) > 0 ) and
167  not std::is_constructible_v<T, Args...> and
168  daw::traits::is_list_constructible_v<T, Args...>),
169  std::unique_ptr<T, Deleter>> {
170 
171  return std::unique_ptr<T, Deleter>(
172  new T{ std::forward<Args>( args )... } );
173  }
174  };
175 
176  /***
177  * Can use the fast, pseudo random string iterators. They are InputIterators
178  * with an operator- that allows for O(1) distance calculations as we often
179  * know the length but cannot provide random access. For types that only use
180  * InputIterator operations and last - first for distance calc
181  */
182  template<typename>
183  struct can_single_allocation_string : std::false_type {};
184 
185  template<typename Char, typename CharTrait, typename Allocator>
187  std::basic_string<Char, CharTrait, Allocator>> : std::true_type {};
188 } // namespace daw::json
daw::json
Definition: daw_json_event_parser.h:17
daw::json::missing_json_data_contract_for
Definition: daw_json_traits.h:31
daw::json::nullable_constructor
Definition: daw_json_traits.h:103
daw
Definition: daw_json_event_parser.h:17
daw::json::force_aggregate_construction
Definition: daw_json_traits.h:50
daw::json::default_constructor
Definition: daw_json_traits.h:58
daw::json::json_data_contract
Definition: daw_json_traits.h:39
daw::json::can_single_allocation_string
Definition: daw_json_traits.h:183