32 namespace json_details {
34 inline constexpr bool is_std_allocator_v =
false;
37 inline constexpr bool is_std_allocator_v<std::allocator<T>> =
true;
42 template<
typename T, std::
size_t Sz>
44 template<
typename Iterator, std::size_t... Is>
45 DAW_ATTRIB_INLINE
static constexpr std::array<T, Sz>
47 std::index_sequence<Is...> ) {
48 auto const get_result = [&]( std::size_t ) {
50 if constexpr( std::is_move_constructible_v<T> or
51 std::is_copy_constructible_v<T> ) {
57 auto const run_after_parse = on_exit_success( [&] {
60 (void)run_after_parse;
66 return std::array<T, Sz>{ get_result( Is )... };
71 operator( )( std::array<T, Sz> &&v )
73 return std::move( v );
76 template<
typename Iterator,
typename Last>
79 operator( )( Iterator first,
81 return construct_array( std::move( first ), std::move( last ),
82 std::make_index_sequence<Sz>{ } );
87#if defined( DAW_JSON_HAS_CPP23_RANGE_CTOR )
88 namespace json_details {
89 template<
typename F,
typename L>
94 explicit iter_range_t( ) =
default;
95 explicit constexpr iter_range_t( F f, L l ) noexcept
99 [[nodiscard]]
constexpr F begin( ) const noexcept {
103 [[nodiscard]]
constexpr L end( ) const noexcept {
107 template<
typename F,
typename L>
108 iter_range_t( F, L ) -> iter_range_t<F, L>;
113 template<
typename T,
typename Alloc>
114 struct default_constructor<
std::vector<T, Alloc>> {
118 operator( )( std::vector<T, Alloc> &&v )
120 noexcept(
noexcept( std::vector<T, Alloc>( v ) ) ) {
121 return std::move( v );
124 template<
typename Iterator,
typename Last>
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>(
133 json_details::iter_range_t{ std::move( first ), std::move( last ) },
136 constexpr auto reserve_amount = 4096U / (
sizeof( T ) * 8U );
137 auto result = std::vector<T, Alloc>( alloc );
139 result.reserve( reserve_amount );
140 result.assign_range( json_details::iter_range_t{
141 std::move( first ), std::move( last ) } );
151 template<
typename T,
typename Alloc>
156 operator( )( std::vector<T, Alloc> &&v )
158 noexcept(
noexcept( std::vector<T, Alloc>( v ) ) ) {
159 return std::move( v );
162 template<
typename Iterator,
typename Last>
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 ),
174 constexpr auto reserve_amount = 4096U / (
sizeof( T ) * 8U );
175 auto result = std::vector<T, Alloc>( alloc );
177 result.reserve( reserve_amount );
178 result.assign( std::move( first ), std::move( last ) );
191 template<
typename Key,
typename T,
typename Hash,
typename CompareEqual,
194 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>> {
198 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
199 operator( )( std::unordered_map<Key, T, Hash, CompareEqual, Alloc> &&v )
201 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>( v ) ) ) {
202 return std::move( v );
205 static constexpr std::size_t count = 1;
206 template<
typename Iterator>
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 );
227 [[nodiscard]] DAW_ATTRIB_INLINE
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 );
237 concepts::is_nullable_value_constructible_v<T, Args...> )>
239 concepts::is_nullable_value_constructible_v<T, Args...> )
244 concepts::is_nullable_value_nothrow_constructible_v<T, Args...> ) {
245 return rtraits_t{ }( concepts::construct_nullable_with_value,
246 DAW_FWD( args )... );
250 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )>
252 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )
255 operator( )( concepts::construct_nullable_with_pointer_t,
258 concepts::is_nullable_value_nothrow_constructible_v<T, Pointer> ) {
259 return rtraits_t{ }( concepts::construct_nullable_with_pointer, ptr );