@@ -260,6 +260,8 @@ __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
260
260
__a.deallocate (_PTraits::pointer_to (*this ), 1 );
261
261
}
262
262
263
+ struct __default_initialize_tag {};
264
+
263
265
template <class _Tp , class _Alloc >
264
266
struct __shared_ptr_emplace
265
267
: __shared_weak_count
@@ -278,6 +280,16 @@ struct __shared_ptr_emplace
278
280
#endif
279
281
}
280
282
283
+
284
+ #if _LIBCPP_STD_VER >= 20
285
+ _LIBCPP_HIDE_FROM_ABI
286
+ explicit __shared_ptr_emplace (__default_initialize_tag, _Alloc __a)
287
+ : __storage_(std::move(__a))
288
+ {
289
+ ::new ((void *)__get_elem ()) _Tp;
290
+ }
291
+ #endif
292
+
281
293
_LIBCPP_HIDE_FROM_ABI
282
294
_Alloc* __get_alloc () _NOEXCEPT { return __storage_.__get_alloc (); }
283
295
@@ -945,6 +957,29 @@ shared_ptr<_Tp> make_shared(_Args&& ...__args)
945
957
return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
946
958
}
947
959
960
+ #if _LIBCPP_STD_VER >= 20
961
+
962
+ template <class _Tp , class _Alloc , __enable_if_t <!is_array<_Tp>::value, int > = 0 >
963
+ _LIBCPP_HIDE_FROM_ABI
964
+ shared_ptr<_Tp> allocate_shared_for_overwrite (const _Alloc& __a)
965
+ {
966
+ using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
967
+ using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
968
+ __allocation_guard<_ControlBlockAllocator> __guard (__a, 1 );
969
+ ::new ((void *)_VSTD::addressof (*__guard.__get ())) _ControlBlock (__default_initialize_tag{}, __a);
970
+ auto __control_block = __guard.__release_ptr ();
971
+ return shared_ptr<_Tp>::__create_with_control_block ((*__control_block).__get_elem (), _VSTD::addressof (*__control_block));
972
+ }
973
+
974
+ template <class _Tp , __enable_if_t <!is_array<_Tp>::value, int > = 0 >
975
+ _LIBCPP_HIDE_FROM_ABI
976
+ shared_ptr<_Tp> make_shared_for_overwrite ()
977
+ {
978
+ return std::allocate_shared_for_overwrite<_Tp>(allocator<_Tp>());
979
+ }
980
+
981
+ #endif // _LIBCPP_STD_VER >= 20
982
+
948
983
#if _LIBCPP_STD_VER > 14
949
984
950
985
template <size_t _Alignment>
@@ -975,6 +1010,17 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
975
1010
std::__uninitialized_allocator_value_construct_n (__alloc_, std::begin (__data_), __count_);
976
1011
}
977
1012
1013
+ #if _LIBCPP_STD_VER >= 20
1014
+ _LIBCPP_HIDE_FROM_ABI
1015
+ explicit __unbounded_array_control_block (_Alloc const & __alloc, size_t __count, __default_initialize_tag)
1016
+ : __alloc_(__alloc), __count_(__count)
1017
+ {
1018
+ // We are purposefully not using an allocator-aware default construction because the spec says so.
1019
+ // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
1020
+ std::uninitialized_default_construct_n (std::begin (__data_), __count_);
1021
+ }
1022
+ #endif
1023
+
978
1024
// Returns the number of bytes required to store a control block followed by the given number
979
1025
// of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
980
1026
_LIBCPP_HIDE_FROM_ABI
@@ -1058,6 +1104,15 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc>
1058
1104
std::__uninitialized_allocator_value_construct_n (__alloc_, std::addressof (__data_[0 ]), _Count);
1059
1105
}
1060
1106
1107
+ #if _LIBCPP_STD_VER >= 20
1108
+ _LIBCPP_HIDE_FROM_ABI
1109
+ explicit __bounded_array_control_block (_Alloc const & __alloc, __default_initialize_tag) : __alloc_(__alloc) {
1110
+ // We are purposefully not using an allocator-aware default construction because the spec says so.
1111
+ // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
1112
+ std::uninitialized_default_construct_n (std::addressof (__data_[0 ]), _Count);
1113
+ }
1114
+ #endif
1115
+
1061
1116
_LIBCPP_HIDE_FROM_ABI_VIRTUAL
1062
1117
~__bounded_array_control_block () override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
1063
1118
@@ -1101,6 +1156,7 @@ shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ...
1101
1156
1102
1157
#if _LIBCPP_STD_VER > 17
1103
1158
1159
+ // bounded array variants
1104
1160
template <class _Tp , class _Alloc , class = __enable_if_t <is_bounded_array<_Tp>::value>>
1105
1161
_LIBCPP_HIDE_FROM_ABI
1106
1162
shared_ptr<_Tp> allocate_shared (const _Alloc& __a)
@@ -1115,18 +1171,11 @@ shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& _
1115
1171
return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
1116
1172
}
1117
1173
1118
- template <class _Tp , class _Alloc , class = __enable_if_t <is_unbounded_array<_Tp>::value>>
1119
- _LIBCPP_HIDE_FROM_ABI
1120
- shared_ptr<_Tp> allocate_shared (const _Alloc& __a, size_t __n)
1121
- {
1122
- return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
1123
- }
1124
-
1125
- template <class _Tp , class _Alloc , class = __enable_if_t <is_unbounded_array<_Tp>::value>>
1174
+ template <class _Tp , class _Alloc , __enable_if_t <is_bounded_array<_Tp>::value, int > = 0 >
1126
1175
_LIBCPP_HIDE_FROM_ABI
1127
- shared_ptr<_Tp> allocate_shared (const _Alloc& __a, size_t __n, const remove_extent_t <_Tp>& __u )
1176
+ shared_ptr<_Tp> allocate_shared_for_overwrite (const _Alloc& __a)
1128
1177
{
1129
- return std::__allocate_shared_unbounded_array <_Tp>(__a, __n, __u );
1178
+ return std::__allocate_shared_bounded_array <_Tp>(__a, __default_initialize_tag{} );
1130
1179
}
1131
1180
1132
1181
template <class _Tp , class = __enable_if_t <is_bounded_array<_Tp>::value>>
@@ -1143,6 +1192,35 @@ shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u)
1143
1192
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
1144
1193
}
1145
1194
1195
+ template <class _Tp , __enable_if_t <is_bounded_array<_Tp>::value, int > = 0 >
1196
+ _LIBCPP_HIDE_FROM_ABI
1197
+ shared_ptr<_Tp> make_shared_for_overwrite ()
1198
+ {
1199
+ return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __default_initialize_tag{});
1200
+ }
1201
+
1202
+ // unbounded array variants
1203
+ template <class _Tp , class _Alloc , class = __enable_if_t <is_unbounded_array<_Tp>::value>>
1204
+ _LIBCPP_HIDE_FROM_ABI
1205
+ shared_ptr<_Tp> allocate_shared (const _Alloc& __a, size_t __n)
1206
+ {
1207
+ return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
1208
+ }
1209
+
1210
+ template <class _Tp , class _Alloc , class = __enable_if_t <is_unbounded_array<_Tp>::value>>
1211
+ _LIBCPP_HIDE_FROM_ABI
1212
+ shared_ptr<_Tp> allocate_shared (const _Alloc& __a, size_t __n, const remove_extent_t <_Tp>& __u)
1213
+ {
1214
+ return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
1215
+ }
1216
+
1217
+ template <class _Tp , class _Alloc , __enable_if_t <is_unbounded_array<_Tp>::value, int > = 0 >
1218
+ _LIBCPP_HIDE_FROM_ABI
1219
+ shared_ptr<_Tp> allocate_shared_for_overwrite (const _Alloc& __a, size_t __n)
1220
+ {
1221
+ return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __default_initialize_tag{});
1222
+ }
1223
+
1146
1224
template <class _Tp , class = __enable_if_t <is_unbounded_array<_Tp>::value>>
1147
1225
_LIBCPP_HIDE_FROM_ABI
1148
1226
shared_ptr<_Tp> make_shared (size_t __n)
@@ -1157,6 +1235,13 @@ shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u)
1157
1235
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
1158
1236
}
1159
1237
1238
+ template <class _Tp , __enable_if_t <is_unbounded_array<_Tp>::value, int > = 0 >
1239
+ _LIBCPP_HIDE_FROM_ABI
1240
+ shared_ptr<_Tp> make_shared_for_overwrite (size_t __n)
1241
+ {
1242
+ return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __default_initialize_tag{});
1243
+ }
1244
+
1160
1245
#endif // _LIBCPP_STD_VER > 17
1161
1246
1162
1247
template <class _Tp , class _Up >
0 commit comments