33 namespace json_details {
35 inline constexpr bool is_std_allocator_v =
false;
38 inline constexpr bool is_std_allocator_v<std::allocator<T>> =
true;
42 template<
typename Iterator>
43 DAW_ATTRIB_INLINE
constexpr auto array_size_hint( Iterator
const &it,
45 ->
decltype(
static_cast<std::size_t
>( it.size_hint( ) ) ) {
46 return static_cast<std::size_t
>( it.size_hint( ) );
49 template<
typename Iterator>
50 DAW_ATTRIB_INLINE
constexpr std::size_t
51 array_size_hint( Iterator
const &,
long ) {
58 template<
typename T, std::
size_t Sz>
60 template<
typename Iterator, std::size_t... Is>
61 DAW_ATTRIB_INLINE
static constexpr std::array<T, Sz>
63 std::index_sequence<Is...> ) {
64 auto const get_result = [&]( std::size_t ) {
66 if constexpr( std::is_move_constructible_v<T> or
67 std::is_copy_constructible_v<T> ) {
73 auto const run_after_parse = on_exit_success( [&] {
76 (void)run_after_parse;
82 return std::array<T, Sz>{ get_result( Is )... };
87 operator( )( std::array<T, Sz> &&v )
89 return std::move( v );
92 template<
typename Iterator,
typename Last>
95 operator( )( Iterator first,
97 return construct_array( std::move( first ),
99 std::make_index_sequence<Sz>{ } );
104#if defined( DAW_JSON_HAS_CPP23_RANGE_CTOR )
105 namespace json_details {
109 inline constexpr bool is_vector_default_constructor_v =
false;
111 template<
typename T,
typename Alloc>
112 inline constexpr bool is_vector_default_constructor_v<
115 template<
typename F,
typename L>
116 struct iter_range_t {
120 explicit iter_range_t( ) =
default;
121 explicit constexpr iter_range_t( F f, L l ) noexcept
125 [[nodiscard]]
constexpr F begin( ) const noexcept {
129 [[nodiscard]]
constexpr L end( ) const noexcept {
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 );
140 template<
typename F,
typename L>
141 iter_range_t( F, L ) -> iter_range_t<F, L>;
147 template<
typename T,
typename Alloc>
148 struct default_constructor<
std::vector<T, Alloc>> {
152 operator( )( std::vector<T, Alloc> &&v )
154 noexcept(
noexcept( std::vector<T, Alloc>( v ) ) ) {
155 return std::move( v );
158 template<
typename Iterator,
typename Last>
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>(
167 json_details::iter_range_t{ std::move( first ), std::move( last ) },
170 auto result = std::vector<T, Alloc>( alloc );
172 if(
auto const hint = json_details::array_size_hint( first, 0 );
174 result.reserve( hint );
176 result.assign_range( json_details::iter_range_t{
177 std::move( first ), std::move( last ) } );
188 template<
typename T,
typename Alloc>
193 operator( )( std::vector<T, Alloc> &&v )
195 noexcept(
noexcept( std::vector<T, Alloc>( v ) ) ) {
196 return std::move( v );
199 template<
typename Iterator,
typename Last>
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 );
211 auto result = std::vector<T, Alloc>( alloc );
213 if(
auto const hint = json_details::array_size_hint( first, 0 );
215 result.reserve( hint );
217 result.assign( std::move( first ), std::move( last ) );
230 template<
typename Key,
typename T,
typename Hash,
typename CompareEqual,
233 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>> {
237 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>
238 operator( )( std::unordered_map<Key, T, Hash, CompareEqual, Alloc> &&v )
240 std::unordered_map<Key, T, Hash, CompareEqual, Alloc>( v ) ) ) {
241 return std::move( v );
244 static constexpr std::size_t count = 1;
245 template<
typename Iterator>
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 );
261 T DAW_ENABLEIF_S( concepts::is_nullable_value_v<T> )> {
266 [[nodiscard]] DAW_ATTRIB_INLINE
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 );
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...> )
282 concepts::is_nullable_value_nothrow_constructible_v<T, Args...> ) {
283 return rtraits_t{ }( concepts::construct_nullable_with_value,
284 DAW_FWD( args )... );
287 template<
typename Pointer DAW_ENABLEIF(
288 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )>
290 concepts::is_nullable_pointer_constructible_v<T, Pointer *> )
293 operator( )( concepts::construct_nullable_with_pointer_t,
296 concepts::is_nullable_value_nothrow_constructible_v<T, Pointer> ) {
297 return rtraits_t{ }( concepts::construct_nullable_with_pointer, ptr );