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
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
30namespace 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> );
233 return rtraits_t{ }( concepts::construct_nullable_with_empty );
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...> ) {
245 return rtraits_t{ }( concepts::construct_nullable_with_value,
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> ) {
259 return rtraits_t{ }( concepts::construct_nullable_with_pointer, ptr );
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
#define DAW_JSON_REQUIRES(...)
Customization point traits.
static DAW_ATTRIB_INLINE constexpr 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:20