DAW JSON Link
Loading...
Searching...
No Matches
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
12
16
17#include <daw/daw_attributes.h>
18#include <daw/daw_enable_requires.h>
19#include <daw/daw_move.h>
20#include <daw/daw_scope_guard.h>
21
22#include <array>
23#include <cstddef>
24#include <iterator>
25#include <type_traits>
26#include <unordered_map>
27#include <utility>
28#include <vector>
29
31namespace daw::json {
32 inline namespace DAW_JSON_VER {
33 namespace json_details {
34 template<typename>
35 inline constexpr bool is_std_allocator_v = false;
36
37 template<typename T>
38 inline constexpr bool is_std_allocator_v<std::allocator<T>> = true;
39
42 template<typename Iterator>
43 DAW_ATTRIB_INLINE constexpr auto array_size_hint( Iterator const &it,
44 int )
45 -> decltype( static_cast<std::size_t>( it.size_hint( ) ) ) {
46 return static_cast<std::size_t>( it.size_hint( ) );
47 }
48
49 template<typename Iterator>
50 DAW_ATTRIB_INLINE constexpr std::size_t
51 array_size_hint( Iterator const &, long ) {
52 return 0;
53 }
54 } // namespace json_details
55
58 template<typename T, std::size_t Sz>
59 struct default_constructor<std::array<T, Sz>> {
60 template<typename Iterator, std::size_t... Is>
61 DAW_ATTRIB_INLINE static constexpr std::array<T, Sz>
62 construct_array( Iterator first, Iterator last,
63 std::index_sequence<Is...> ) {
64 auto const get_result = [&]( std::size_t ) {
65 if( first != last ) {
66 if constexpr( std::is_move_constructible_v<T> or
67 std::is_copy_constructible_v<T> ) {
68 auto result = *first;
69 ++first;
70 return result;
71 } else {
72 // Only use for non-movable/copyable types
73 auto const run_after_parse = on_exit_success( [&] {
74 ++first;
75 } );
76 (void)run_after_parse;
77 return *first;
78 }
79 }
80 return T{ };
81 };
82 return std::array<T, Sz>{ get_result( Is )... };
83 }
84
86 DAW_JSON_CPP23_STATIC_CALL_OP constexpr std::array<T, Sz>
87 operator( )( std::array<T, Sz> &&v )
89 return std::move( v );
90 }
91
92 template<typename Iterator, typename Last>
93 DAW_ATTRIB_INLINE
94 DAW_JSON_CPP23_STATIC_CALL_OP constexpr std::array<T, Sz>
95 operator( )( Iterator first,
97 return construct_array( std::move( first ),
98 std::move( last ),
99 std::make_index_sequence<Sz>{ } );
100 }
102 }; // namespace daw::json
103
104#if defined( DAW_JSON_HAS_CPP23_RANGE_CTOR )
105 namespace json_details {
108 template<typename>
109 inline constexpr bool is_vector_default_constructor_v = false;
110
111 template<typename T, typename Alloc>
112 inline constexpr bool is_vector_default_constructor_v<
114
115 template<typename F, typename L>
116 struct iter_range_t {
117 F first;
118 L last;
119
120 explicit iter_range_t( ) = default;
121 explicit constexpr iter_range_t( F f, L l ) noexcept
122 : first( f )
123 , last( l ) {}
124
125 [[nodiscard]] constexpr F begin( ) const noexcept {
126 return first;
127 }
128
129 [[nodiscard]] constexpr L end( ) const noexcept {
130 return last;
131 }
132
135 [[nodiscard]] constexpr std::size_t size( ) const
136 requires( std::sized_sentinel_for<L, F> ) {
137 return static_cast<std::size_t>( last - first );
138 }
139 };
140 template<typename F, typename L>
141 iter_range_t( F, L ) -> iter_range_t<F, L>;
142 } // namespace json_details
143
147 template<typename T, typename Alloc>
148 struct default_constructor<std::vector<T, Alloc>> {
150 DAW_ATTRIB_INLINE
152 operator( )( std::vector<T, Alloc> &&v )
154 noexcept( noexcept( std::vector<T, Alloc>( v ) ) ) {
155 return std::move( v );
156 }
157
158 template<typename Iterator, typename Last>
159 DAW_ATTRIB_INLINE
161 operator( )( Iterator first, Last last, Alloc const &alloc = Alloc{ } )
163 if constexpr( requires { last - first; } or
164 not json_details::is_std_allocator_v<Alloc> ) {
165 return std::vector<T, Alloc>(
166 std::from_range,
167 json_details::iter_range_t{ std::move( first ), std::move( last ) },
168 alloc );
169 } else {
170 auto result = std::vector<T, Alloc>( alloc );
171 // The known element count, or the ArrayReserve parse option
172 if( auto const hint = json_details::array_size_hint( first, 0 );
173 hint != 0 ) {
174 result.reserve( hint );
175 }
176 result.assign_range( json_details::iter_range_t{
177 std::move( first ), std::move( last ) } );
178 return result;
179 }
180 }
182 };
183
184#else
188 template<typename T, typename Alloc>
189 struct default_constructor<std::vector<T, Alloc>> {
191 DAW_ATTRIB_INLINE
193 operator( )( std::vector<T, Alloc> &&v )
195 noexcept( noexcept( std::vector<T, Alloc>( v ) ) ) {
196 return std::move( v );
197 }
198
199 template<typename Iterator, typename Last>
200 DAW_ATTRIB_INLINE
202 operator( )( Iterator first, Last last, Alloc const &alloc = Alloc{ } )
204 if constexpr( std::is_same_v<std::random_access_iterator_tag,
205 typename std::iterator_traits<
206 Iterator>::iterator_category> or
207 not json_details::is_std_allocator_v<Alloc> ) {
208 return std::vector<T, Alloc>(
209 std::move( first ), std::move( last ), alloc );
210 } else {
211 auto result = std::vector<T, Alloc>( alloc );
212 // The known element count, or the ArrayReserve parse option
213 if( auto const hint = json_details::array_size_hint( first, 0 );
214 hint != 0 ) {
215 result.reserve( hint );
216 }
217 result.assign( std::move( first ), std::move( last ) );
218 return result;
219 }
220 }
222 };
223#endif
224
230 template<typename Key, typename T, typename Hash, typename CompareEqual,
231 typename Alloc>
233 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>> {
234
236 DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
237 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
238 operator( )( std::unordered_map<Key, T, Hash, CompareEqual, Alloc> &&v )
239 DAW_JSON_CPP23_STATIC_CALL_OP_CONST noexcept( noexcept(
240 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>( v ) ) ) {
241 return std::move( v );
242 }
243
244 static constexpr std::size_t count = 1;
245 template<typename Iterator>
246 DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
247 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
248 operator( )( Iterator first, Iterator last,
249 Alloc const &alloc = Alloc{ } )
251 return std::unordered_map<Key, T, Hash, CompareEqual, Alloc>(
252 first, last, count, Hash{ }, CompareEqual{ }, alloc );
253 }
255 };
256
258 template<typename T>
259 DAW_REQUIRES( concepts::is_nullable_value_v<T> )
261 T DAW_ENABLEIF_S( concepts::is_nullable_value_v<T> )> {
262 using value_type = concepts::nullable_value_type_t<T>;
263 using rtraits_t = concepts::nullable_value_traits<T>;
264
266 [[nodiscard]] DAW_ATTRIB_INLINE
267 DAW_JSON_CPP23_STATIC_CALL_OP constexpr auto
268 operator( )( concepts::construct_nullable_with_empty_t )
270 noexcept( concepts::is_nullable_empty_nothrow_constructible_v<T> ) {
271 static_assert( concepts::is_nullable_empty_constructible_v<T> );
272 return rtraits_t{ }( concepts::construct_nullable_with_empty );
273 }
274
275 template<typename... Args DAW_ENABLEIF(
276 concepts::is_nullable_value_constructible_v<T, Args...> )>
277 DAW_REQUIRES( concepts::is_nullable_value_constructible_v<T, Args...> )
278 [[nodiscard]] DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
279 constexpr auto
280 operator( )( Args &&...args ) DAW_JSON_CPP23_STATIC_CALL_OP_CONST
281 noexcept(
282 concepts::is_nullable_value_nothrow_constructible_v<T, Args...> ) {
283 return rtraits_t{ }( concepts::construct_nullable_with_value,
284 DAW_FWD( args )... );
285 }
286
287 template<typename Pointer DAW_ENABLEIF(
288 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )>
290 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )
291 [[nodiscard]] DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
292 constexpr auto
293 operator( )( concepts::construct_nullable_with_pointer_t,
295 noexcept(
296 concepts::is_nullable_value_nothrow_constructible_v<T, Pointer> ) {
297 return rtraits_t{ }( concepts::construct_nullable_with_pointer, ptr );
298 }
300 };
301 } // namespace DAW_JSON_VER
302} // namespace daw::json
DAW_REQUIRES(daw::json::json_details::is_container_opted_into_json_iostreams_v< Container >) std
An opt in ostream interface for containers of types that have JSON mappings.
#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_CPP23_STATIC_CALL_OP_ENABLE_WARNING
#define DAW_JSON_CPP23_STATIC_CALL_OP
string_writer grows its string with resize_and_overwrite, leaving the new bytes uninitialized,...
static DAW_ATTRIB_INLINE constexpr std::array< T, Sz > construct_array(Iterator first, Iterator last, std::index_sequence< Is... >)
DAW_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:20