DAW JSON Link
daw_json_default_constuctor.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"
16 
17 #include <daw/daw_attributes.h>
18 #include <daw/daw_move.h>
19 #include <daw/daw_scope_guard.h>
20 
21 #include <array>
22 #include <cstddef>
23 #include <iterator>
24 #include <type_traits>
25 #include <unordered_map>
26 #include <utility>
27 #include <vector>
28 
30 namespace daw::json {
31  inline namespace DAW_JSON_VER {
32  namespace json_details {
33  template<typename>
34  inline constexpr bool is_std_allocator_v = false;
35 
36  template<typename T>
37  inline constexpr bool is_std_allocator_v<std::allocator<T>> = true;
38  } // namespace json_details
39 
42  template<typename T, std::size_t Sz>
43  struct default_constructor<std::array<T, Sz>> {
44  template<typename Iterator, std::size_t... Is>
45  DAW_ATTRIB_INLINE static constexpr std::array<T, Sz>
46  construct_array( Iterator first, Iterator last,
47  std::index_sequence<Is...> ) {
48  auto const get_result = [&]( std::size_t ) {
49  if( first != last ) {
50  if constexpr( std::is_move_constructible_v<T> or
51  std::is_copy_constructible_v<T> ) {
52  auto result = *first;
53  ++first;
54  return result;
55  } else {
56  // Only use for non-movable/copyable types
57  auto const run_after_parse = on_exit_success( [&] {
58  ++first;
59  } );
60  (void)run_after_parse;
61  return *first;
62  }
63  }
64  return T{ };
65  };
66  return std::array<T, Sz>{ get_result( Is )... };
67  }
68 
70  DAW_JSON_CPP23_STATIC_CALL_OP constexpr std::array<T, Sz>
71  operator( )( std::array<T, Sz> &&v )
73  return std::move( v );
74  }
75 
76  template<typename Iterator, typename Last>
77  DAW_ATTRIB_INLINE
78  DAW_JSON_CPP23_STATIC_CALL_OP constexpr std::array<T, Sz>
79  operator( )( Iterator first,
81  return construct_array( std::move( first ), std::move( last ),
82  std::make_index_sequence<Sz>{ } );
83  }
85  }; // namespace daw::json
86 
87 #if defined( DAW_JSON_HAS_CPP23_RANGE_CTOR )
88  namespace json_details {
89  template<typename F, typename L>
90  struct iter_range_t {
91  F first;
92  L last;
93 
94  explicit iter_range_t( ) = default;
95  explicit constexpr iter_range_t( F f, L l ) noexcept
96  : first( f )
97  , last( l ) {}
98 
99  [[nodiscard]] constexpr F begin( ) const noexcept {
100  return first;
101  }
102 
103  [[nodiscard]] constexpr L end( ) const noexcept {
104  return last;
105  }
106  };
107  template<typename F, typename L>
108  iter_range_t( F, L ) -> iter_range_t<F, L>;
109  } // namespace json_details
110 
113  template<typename T, typename Alloc>
114  struct default_constructor<std::vector<T, Alloc>> {
116  DAW_ATTRIB_INLINE
118  operator( )( std::vector<T, Alloc> &&v )
120  noexcept( noexcept( std::vector<T, Alloc>( v ) ) ) {
121  return std::move( v );
122  }
123 
124  template<typename Iterator, typename Last>
125  DAW_ATTRIB_INLINE
127  operator( )( Iterator first, Last last, Alloc const &alloc = Alloc{ } )
129  if constexpr( requires { last - first; } or
130  not json_details::is_std_allocator_v<Alloc> ) {
131  return std::vector<T, Alloc>(
132  std::from_range,
133  json_details::iter_range_t{ std::move( first ), std::move( last ) },
134  alloc );
135  } else {
136  constexpr auto reserve_amount = 4096U / ( sizeof( T ) * 8U );
137  auto result = std::vector<T, Alloc>( alloc );
138  // Lets use a WAG and go for a 4k page size
139  result.reserve( reserve_amount );
140  result.assign_range( json_details::iter_range_t{
141  std::move( first ), std::move( last ) } );
142  return result;
143  }
144  }
146  };
147 
148 #else
151  template<typename T, typename Alloc>
152  struct default_constructor<std::vector<T, Alloc>> {
154  DAW_ATTRIB_INLINE
156  operator( )( std::vector<T, Alloc> &&v )
158  noexcept( noexcept( std::vector<T, Alloc>( v ) ) ) {
159  return std::move( v );
160  }
161 
162  template<typename Iterator, typename Last>
163  DAW_ATTRIB_INLINE
165  operator( )( Iterator first, Last last, Alloc const &alloc = Alloc{ } )
167  if constexpr( std::is_same_v<std::random_access_iterator_tag,
168  typename std::iterator_traits<
169  Iterator>::iterator_category> or
170  not json_details::is_std_allocator_v<Alloc> ) {
171  return std::vector<T, Alloc>( std::move( first ), std::move( last ),
172  alloc );
173  } else {
174  constexpr auto reserve_amount = 4096U / ( sizeof( T ) * 8U );
175  auto result = std::vector<T, Alloc>( alloc );
176  // Lets use a WAG and go for a 4k page size
177  result.reserve( reserve_amount );
178  result.assign( std::move( first ), std::move( last ) );
179  return result;
180  }
181  }
183  };
184 #endif
185 
191  template<typename Key, typename T, typename Hash, typename CompareEqual,
192  typename Alloc>
194  std::unordered_map<Key, T, Hash, CompareEqual, Alloc>> {
195 
197  DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
198  std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
199  operator( )( std::unordered_map<Key, T, Hash, CompareEqual, Alloc> &&v )
200  DAW_JSON_CPP23_STATIC_CALL_OP_CONST noexcept( noexcept(
201  std::unordered_map<Key, T, Hash, CompareEqual, Alloc>( v ) ) ) {
202  return std::move( v );
203  }
204 
205  static constexpr std::size_t count = 1;
206  template<typename Iterator>
207  DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
208  std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
209  operator( )( Iterator first, Iterator last,
210  Alloc const &alloc = Alloc{ } )
212  return std::unordered_map<Key, T, Hash, CompareEqual, Alloc>(
213  first, last, count, Hash{ }, CompareEqual{ }, alloc );
214  }
216  };
217 
219  template<typename T>
220  DAW_JSON_REQUIRES( concepts::is_nullable_value_v<T> )
222  T DAW_JSON_ENABLEIF_S( concepts::is_nullable_value_v<T> )> {
223  using value_type = concepts::nullable_value_type_t<T>;
224  using rtraits_t = concepts::nullable_value_traits<T>;
225 
227  [[nodiscard]] DAW_ATTRIB_INLINE
228  DAW_JSON_CPP23_STATIC_CALL_OP constexpr auto
229  operator( )( concepts::construct_nullable_with_empty_t )
231  noexcept( concepts::is_nullable_empty_nothrow_constructible_v<T> ) {
232  static_assert( concepts::is_nullable_empty_constructible_v<T> );
234  }
235 
236  template<typename... Args DAW_JSON_ENABLEIF(
237  concepts::is_nullable_value_constructible_v<T, Args...> )>
239  concepts::is_nullable_value_constructible_v<T, Args...> )
240  [[nodiscard]] DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
241  constexpr auto
242  operator( )( Args &&...args ) DAW_JSON_CPP23_STATIC_CALL_OP_CONST
243  noexcept(
244  concepts::is_nullable_value_nothrow_constructible_v<T, Args...> ) {
246  DAW_FWD( args )... );
247  }
248 
249  template<typename Pointer DAW_JSON_ENABLEIF(
250  concepts::is_nullable_pointer_constructible_v<T, Pointer *> )>
252  concepts::is_nullable_pointer_constructible_v<T, Pointer *> )
253  [[nodiscard]] DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
254  constexpr auto
255  operator( )( concepts::construct_nullable_with_pointer_t,
257  noexcept(
258  concepts::is_nullable_value_nothrow_constructible_v<T, Pointer> ) {
260  }
262  };
263  } // namespace DAW_JSON_VER
264 } // namespace daw::json
#define DAW_JSON_ENABLEIF_S(...)
#define DAW_JSON_CPP23_STATIC_CALL_OP_DISABLE_WARNING
#define DAW_JSON_CPP23_STATIC_CALL_OP_CONST
#define DAW_JSON_CX_VECTOR
#define DAW_JSON_ENABLEIF(...)
#define DAW_JSON_CPP23_STATIC_CALL_OP_ENABLE_WARNING
#define DAW_JSON_CPP23_STATIC_CALL_OP
This is in addition to the parse policy. Always do a full name match instead of sometimes relying on ...
Customization point traits.
DAW_JSON_REQUIRES(boost::describe::has_describe_members< T >::value and use_boost_describe_v< T >) struct json_data_contract< T >
requires(std::is_aggregate_v< T > and std::is_class_v< T > and not std::is_empty_v< T >) inline const expr bool use_boost_pfr
Enable Boost PFR mappings for a type.
static constexpr DAW_ATTRIB_INLINE std::array< T, Sz > construct_array(Iterator first, Iterator last, std::index_sequence< Is... >)
DAW_JSON_REQUIRES(concepts::is_nullable_value_constructible_v< T, Args... >) DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP const expr auto operator()(Args &&...args) DAW_JSON_CPP23_STATIC_CALL_OP_CONST noexcept(concepts::is_nullable_value_nothrow_constructible_v< T, Args... >)
DAW_JSON_REQUIRES(concepts::is_nullable_pointer_constructible_v< T, Pointer * >) DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP const expr auto operator()(concepts
Default Constructor for a type. It accounts for aggregate types and uses brace construction for them.
Default constructor for nullable types. Specializations must accept accept an operator( )( ) that sig...
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:25