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 } // namespace json_details
40
43 template<typename T, std::size_t Sz>
44 struct default_constructor<std::array<T, Sz>> {
45 template<typename Iterator, std::size_t... Is>
46 DAW_ATTRIB_INLINE static constexpr std::array<T, Sz>
47 construct_array( Iterator first, Iterator last,
48 std::index_sequence<Is...> ) {
49 auto const get_result = [&]( std::size_t ) {
50 if( first != last ) {
51 if constexpr( std::is_move_constructible_v<T> or
52 std::is_copy_constructible_v<T> ) {
53 auto result = *first;
54 ++first;
55 return result;
56 } else {
57 // Only use for non-movable/copyable types
58 auto const run_after_parse = on_exit_success( [&] {
59 ++first;
60 } );
61 (void)run_after_parse;
62 return *first;
63 }
64 }
65 return T{ };
66 };
67 return std::array<T, Sz>{ get_result( Is )... };
68 }
69
71 DAW_JSON_CPP23_STATIC_CALL_OP constexpr std::array<T, Sz>
72 operator( )( std::array<T, Sz> &&v )
74 return std::move( v );
75 }
76
77 template<typename Iterator, typename Last>
78 DAW_ATTRIB_INLINE
79 DAW_JSON_CPP23_STATIC_CALL_OP constexpr std::array<T, Sz>
80 operator( )( Iterator first,
82 return construct_array( std::move( first ),
83 std::move( last ),
84 std::make_index_sequence<Sz>{ } );
85 }
87 }; // namespace daw::json
88
89#if defined( DAW_JSON_HAS_CPP23_RANGE_CTOR )
90 namespace json_details {
91 template<typename F, typename L>
92 struct iter_range_t {
93 F first;
94 L last;
95
96 explicit iter_range_t( ) = default;
97 explicit constexpr iter_range_t( F f, L l ) noexcept
98 : first( f )
99 , last( l ) {}
100
101 [[nodiscard]] constexpr F begin( ) const noexcept {
102 return first;
103 }
104
105 [[nodiscard]] constexpr L end( ) const noexcept {
106 return last;
107 }
108 };
109 template<typename F, typename L>
110 iter_range_t( F, L ) -> iter_range_t<F, L>;
111 } // namespace json_details
112
115 template<typename T, typename Alloc>
116 struct default_constructor<std::vector<T, Alloc>> {
118 DAW_ATTRIB_INLINE
120 operator( )( std::vector<T, Alloc> &&v )
122 noexcept( noexcept( std::vector<T, Alloc>( v ) ) ) {
123 return std::move( v );
124 }
125
126 template<typename Iterator, typename Last>
127 DAW_ATTRIB_INLINE
129 operator( )( Iterator first, Last last, Alloc const &alloc = Alloc{ } )
131 if constexpr( requires { last - first; } or
132 not json_details::is_std_allocator_v<Alloc> ) {
133 return std::vector<T, Alloc>(
134 std::from_range,
135 json_details::iter_range_t{ std::move( first ), std::move( last ) },
136 alloc );
137 } else {
138 using reserve_amount = daw::constant<
139 ( 4096U / sizeof( T ) ) == 0 ? 1 : ( 4096U / sizeof( T ) )>;
140 auto result = std::vector<T, Alloc>( alloc );
141 // Lets use a WAG and go for a 4k page size
142 result.reserve( reserve_amount::value );
143 result.assign_range( json_details::iter_range_t{
144 std::move( first ), std::move( last ) } );
145 return result;
146 }
147 }
149 };
150
151#else
154 template<typename T, typename Alloc>
155 struct default_constructor<std::vector<T, Alloc>> {
157 DAW_ATTRIB_INLINE
159 operator( )( std::vector<T, Alloc> &&v )
161 noexcept( noexcept( std::vector<T, Alloc>( v ) ) ) {
162 return std::move( v );
163 }
164
165 template<typename Iterator, typename Last>
166 DAW_ATTRIB_INLINE
168 operator( )( Iterator first, Last last, Alloc const &alloc = Alloc{ } )
170 if constexpr( std::is_same_v<std::random_access_iterator_tag,
171 typename std::iterator_traits<
172 Iterator>::iterator_category> or
173 not json_details::is_std_allocator_v<Alloc> ) {
174 return std::vector<T, Alloc>(
175 std::move( first ), std::move( last ), alloc );
176 } else {
177 using reserve_amount = daw::constant<4096U / ( sizeof( T ) * 8U )>;
178 auto result = std::vector<T, Alloc>( alloc );
179 // Lets use a WAG and go for a 4k page size
180 result.reserve( reserve_amount::value );
181 result.assign( std::move( first ), std::move( last ) );
182 return result;
183 }
184 }
186 };
187#endif
188
194 template<typename Key, typename T, typename Hash, typename CompareEqual,
195 typename Alloc>
197 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>> {
198
200 DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
201 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
202 operator( )( std::unordered_map<Key, T, Hash, CompareEqual, Alloc> &&v )
203 DAW_JSON_CPP23_STATIC_CALL_OP_CONST noexcept( noexcept(
204 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>( v ) ) ) {
205 return std::move( v );
206 }
207
208 static constexpr std::size_t count = 1;
209 template<typename Iterator>
210 DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
211 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
212 operator( )( Iterator first, Iterator last,
213 Alloc const &alloc = Alloc{ } )
215 return std::unordered_map<Key, T, Hash, CompareEqual, Alloc>(
216 first, last, count, Hash{ }, CompareEqual{ }, alloc );
217 }
219 };
220
222 template<typename T>
223 DAW_REQUIRES( concepts::is_nullable_value_v<T> )
225 T DAW_ENABLEIF_S( concepts::is_nullable_value_v<T> )> {
226 using value_type = concepts::nullable_value_type_t<T>;
227 using rtraits_t = concepts::nullable_value_traits<T>;
228
230 [[nodiscard]] DAW_ATTRIB_INLINE
231 DAW_JSON_CPP23_STATIC_CALL_OP constexpr auto
232 operator( )( concepts::construct_nullable_with_empty_t )
234 noexcept( concepts::is_nullable_empty_nothrow_constructible_v<T> ) {
235 static_assert( concepts::is_nullable_empty_constructible_v<T> );
236 return rtraits_t{ }( concepts::construct_nullable_with_empty );
237 }
238
239 template<typename... Args DAW_ENABLEIF(
240 concepts::is_nullable_value_constructible_v<T, Args...> )>
241 DAW_REQUIRES( concepts::is_nullable_value_constructible_v<T, Args...> )
242 [[nodiscard]] DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
243 constexpr auto
244 operator( )( Args &&...args ) DAW_JSON_CPP23_STATIC_CALL_OP_CONST
245 noexcept(
246 concepts::is_nullable_value_nothrow_constructible_v<T, Args...> ) {
247 return rtraits_t{ }( concepts::construct_nullable_with_value,
248 DAW_FWD( args )... );
249 }
250
251 template<typename Pointer DAW_ENABLEIF(
252 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )>
254 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )
255 [[nodiscard]] DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
256 constexpr auto
257 operator( )( concepts::construct_nullable_with_pointer_t,
259 noexcept(
260 concepts::is_nullable_value_nothrow_constructible_v<T, Pointer> ) {
261 return rtraits_t{ }( concepts::construct_nullable_with_pointer, ptr );
262 }
264 };
265 } // namespace DAW_JSON_VER
266} // 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
Customization point traits.
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