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<4096U / ( sizeof( T ) * 8U )>;
139 auto result = std::vector<T, Alloc>( alloc );
140 // Lets use a WAG and go for a 4k page size
141 result.reserve( reserve_amount::value );
142 result.assign_range( json_details::iter_range_t{
143 std::move( first ), std::move( last ) } );
144 return result;
145 }
146 }
148 };
149
150#else
153 template<typename T, typename Alloc>
154 struct default_constructor<std::vector<T, Alloc>> {
156 DAW_ATTRIB_INLINE
158 operator( )( std::vector<T, Alloc> &&v )
160 noexcept( noexcept( std::vector<T, Alloc>( v ) ) ) {
161 return std::move( v );
162 }
163
164 template<typename Iterator, typename Last>
165 DAW_ATTRIB_INLINE
167 operator( )( Iterator first, Last last, Alloc const &alloc = Alloc{ } )
169 if constexpr( std::is_same_v<std::random_access_iterator_tag,
170 typename std::iterator_traits<
171 Iterator>::iterator_category> or
172 not json_details::is_std_allocator_v<Alloc> ) {
173 return std::vector<T, Alloc>(
174 std::move( first ), std::move( last ), alloc );
175 } else {
176 using reserve_amount = daw::constant<4096U / ( sizeof( T ) * 8U )>;
177 auto result = std::vector<T, Alloc>( alloc );
178 // Lets use a WAG and go for a 4k page size
179 result.reserve( reserve_amount::value );
180 result.assign( std::move( first ), std::move( last ) );
181 return result;
182 }
183 }
185 };
186#endif
187
193 template<typename Key, typename T, typename Hash, typename CompareEqual,
194 typename Alloc>
196 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>> {
197
199 DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
200 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
201 operator( )( std::unordered_map<Key, T, Hash, CompareEqual, Alloc> &&v )
202 DAW_JSON_CPP23_STATIC_CALL_OP_CONST noexcept( noexcept(
203 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>( v ) ) ) {
204 return std::move( v );
205 }
206
207 static constexpr std::size_t count = 1;
208 template<typename Iterator>
209 DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
210 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
211 operator( )( Iterator first, Iterator last,
212 Alloc const &alloc = Alloc{ } )
214 return std::unordered_map<Key, T, Hash, CompareEqual, Alloc>(
215 first, last, count, Hash{ }, CompareEqual{ }, alloc );
216 }
218 };
219
221 template<typename T>
222 DAW_REQUIRES( concepts::is_nullable_value_v<T> )
224 T DAW_ENABLEIF_S( concepts::is_nullable_value_v<T> )> {
225 using value_type = concepts::nullable_value_type_t<T>;
226 using rtraits_t = concepts::nullable_value_traits<T>;
227
229 [[nodiscard]] DAW_ATTRIB_INLINE
230 DAW_JSON_CPP23_STATIC_CALL_OP constexpr auto
231 operator( )( concepts::construct_nullable_with_empty_t )
233 noexcept( concepts::is_nullable_empty_nothrow_constructible_v<T> ) {
234 static_assert( concepts::is_nullable_empty_constructible_v<T> );
235 return rtraits_t{ }( concepts::construct_nullable_with_empty );
236 }
237
238 template<typename... Args DAW_ENABLEIF(
239 concepts::is_nullable_value_constructible_v<T, Args...> )>
240 DAW_REQUIRES( concepts::is_nullable_value_constructible_v<T, Args...> )
241 [[nodiscard]] DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
242 constexpr auto
243 operator( )( Args &&...args ) DAW_JSON_CPP23_STATIC_CALL_OP_CONST
244 noexcept(
245 concepts::is_nullable_value_nothrow_constructible_v<T, Args...> ) {
246 return rtraits_t{ }( concepts::construct_nullable_with_value,
247 DAW_FWD( args )... );
248 }
249
250 template<typename Pointer DAW_ENABLEIF(
251 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )>
253 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )
254 [[nodiscard]] DAW_ATTRIB_INLINE DAW_JSON_CPP23_STATIC_CALL_OP
255 constexpr auto
256 operator( )( concepts::construct_nullable_with_pointer_t,
258 noexcept(
259 concepts::is_nullable_value_nothrow_constructible_v<T, Pointer> ) {
260 return rtraits_t{ }( concepts::construct_nullable_with_pointer, ptr );
261 }
263 };
264 } // namespace DAW_JSON_VER
265} // 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