Skip to content

Commit f1ff789

Browse files
[libc++] LWG3187: P0591R4 reverted DR 2586 fixes to scoped_allocator_adaptor::construct()
Applying it (adding missing `const``) to pre-C++20 dispatching mechanisms. Also - make dispatch mechanisms in pre-C++20 `construct` more consistent, - add fallback dispatching and overloads to emit better error messages, and - partially implement LWG4312.
1 parent aa2a7f4 commit f1ff789

File tree

14 files changed

+252
-296
lines changed

14 files changed

+252
-296
lines changed

libcxx/docs/Status/Cxx20Issues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
"`LWG3184 <https://wg21.link/LWG3184>`__","Inconsistencies in ``bind_front``\ wording","2019-07 (Cologne)","|Complete|","13","`#103850 <https://github.com/llvm/llvm-project/issues/103850>`__",""
152152
"`LWG3185 <https://wg21.link/LWG3185>`__","Uses-allocator construction functions missing ``constexpr``\ and ``noexcept``\ ","2019-07 (Cologne)","|Complete|","16","`#103851 <https://github.com/llvm/llvm-project/issues/103851>`__",""
153153
"`LWG3186 <https://wg21.link/LWG3186>`__","``ranges``\ removal, partition, and ``partial_sort_copy``\ algorithms discard useful information","2019-07 (Cologne)","|Complete|","15","`#103852 <https://github.com/llvm/llvm-project/issues/103852>`__",""
154-
"`LWG3187 <https://wg21.link/LWG3187>`__","`P0591R4 <https://wg21.link/p0591r4>`__ reverted DR 2586 fixes to ``scoped_allocator_adaptor::construct()``\ ","2019-07 (Cologne)","","","`#100256 <https://github.com/llvm/llvm-project/issues/100256>`__",""
154+
"`LWG3187 <https://wg21.link/LWG3187>`__","`P0591R4 <https://wg21.link/p0591r4>`__ reverted DR 2586 fixes to ``scoped_allocator_adaptor::construct()``\ ","2019-07 (Cologne)","|Complete|","22","`#100256 <https://github.com/llvm/llvm-project/issues/100256>`__",""
155155
"`LWG3191 <https://wg21.link/LWG3191>`__","``std::ranges::shuffle``\ synopsis does not match algorithm definition","2019-07 (Cologne)","|Complete|","15","`#103853 <https://github.com/llvm/llvm-project/issues/103853>`__",""
156156
"`LWG3196 <https://wg21.link/LWG3196>`__","``std::optional<T>``\ is ill-formed is ``T``\ is an array","2019-07 (Cologne)","|Complete|","","`#103854 <https://github.com/llvm/llvm-project/issues/103854>`__",""
157157
"`LWG3198 <https://wg21.link/LWG3198>`__","Bad constraint on ``std::span::span()``\ ","2019-07 (Cologne)","|Complete|","","`#103856 <https://github.com/llvm/llvm-project/issues/103856>`__",""

libcxx/include/__memory/allocator_arg_t.h

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <__memory/uses_allocator.h>
1515
#include <__type_traits/integral_constant.h>
1616
#include <__type_traits/is_constructible.h>
17+
#include <__type_traits/remove_cv.h>
1718
#include <__type_traits/remove_cvref.h>
1819
#include <__utility/forward.h>
1920

@@ -40,34 +41,15 @@ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
4041
template <class _Tp, class _Alloc, class... _Args>
4142
struct __uses_alloc_ctor_imp {
4243
using _RawAlloc _LIBCPP_NODEBUG = __remove_cvref_t<_Alloc>;
43-
static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
44-
static const bool __ic = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
45-
static const int value = __ua ? 2 - __ic : 0;
44+
static constexpr bool __ua = uses_allocator<__remove_cv_t<_Tp>, _RawAlloc>::value;
45+
static constexpr bool __ic_head = is_constructible<_Tp, allocator_arg_t, const _RawAlloc&, _Args...>::value;
46+
static constexpr bool __ic_tail = is_constructible<_Tp, _Args..., const _RawAlloc&>::value;
47+
static constexpr int value = __ua ? (__ic_head ? 1 : __ic_tail ? 2 : -1) : 0;
4648
};
4749

4850
template <class _Tp, class _Alloc, class... _Args>
4951
struct __uses_alloc_ctor : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value> {};
5052

51-
template <class _Tp, class _Allocator, class... _Args>
52-
inline _LIBCPP_HIDE_FROM_ABI void
53-
__user_alloc_construct_impl(integral_constant<int, 0>, _Tp* __storage, const _Allocator&, _Args&&... __args) {
54-
new (__storage) _Tp(std::forward<_Args>(__args)...);
55-
}
56-
57-
// FIXME: This should have a version which takes a non-const alloc.
58-
template <class _Tp, class _Allocator, class... _Args>
59-
inline _LIBCPP_HIDE_FROM_ABI void
60-
__user_alloc_construct_impl(integral_constant<int, 1>, _Tp* __storage, const _Allocator& __a, _Args&&... __args) {
61-
new (__storage) _Tp(allocator_arg, __a, std::forward<_Args>(__args)...);
62-
}
63-
64-
// FIXME: This should have a version which takes a non-const alloc.
65-
template <class _Tp, class _Allocator, class... _Args>
66-
inline _LIBCPP_HIDE_FROM_ABI void
67-
__user_alloc_construct_impl(integral_constant<int, 2>, _Tp* __storage, const _Allocator& __a, _Args&&... __args) {
68-
new (__storage) _Tp(std::forward<_Args>(__args)..., __a);
69-
}
70-
7153
#endif // _LIBCPP_CXX03_LANG
7254

7355
_LIBCPP_END_NAMESPACE_STD

libcxx/include/__memory/uses_allocator_construction.h

Lines changed: 143 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@
1010
#define _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H
1111

1212
#include <__config>
13+
#include <__cstddef/size_t.h>
14+
#include <__functional/reference_wrapper.h>
1315
#include <__memory/construct_at.h>
1416
#include <__memory/uses_allocator.h>
1517
#include <__tuple/tuple_like_no_subrange.h>
1618
#include <__type_traits/enable_if.h>
19+
#include <__type_traits/invoke.h>
20+
#include <__type_traits/is_constructible.h>
1721
#include <__type_traits/remove_cv.h>
22+
#include <__type_traits/remove_cvref.h>
1823
#include <__utility/declval.h>
24+
#include <__utility/integer_sequence.h>
1925
#include <__utility/pair.h>
2026
#include <__utility/piecewise_construct.h>
2127
#include <tuple>
@@ -29,7 +35,43 @@ _LIBCPP_PUSH_MACROS
2935

3036
_LIBCPP_BEGIN_NAMESPACE_STD
3137

32-
#if _LIBCPP_STD_VER >= 17
38+
#if !defined(_LIBCPP_CXX03_LANG) && _LIBCPP_STD_VER < 14
39+
40+
template <class _Alloc, class... _Args, size_t... _Is>
41+
_LIBCPP_HIDE_FROM_ABI void __transform_tuple_using_allocator_impl(
42+
integral_constant<int, -1>, const _Alloc&, tuple<_Args...>&&, __index_sequence<_Is...>) {
43+
static_assert(false, "If uses_allocator_v<T, A> is true, T has to be allocator-constructible");
44+
}
45+
46+
template <class _Alloc, class... _Args, size_t... _Is>
47+
_LIBCPP_HIDE_FROM_ABI tuple<_Args&&...> __transform_tuple_using_allocator_impl(
48+
integral_constant<int, 0>, const _Alloc&, tuple<_Args...>&& __t, __index_sequence<_Is...>) {
49+
return tuple<_Args&&...>(std::move(__t));
50+
}
51+
52+
template <class _Alloc, class... _Args, size_t... _Is>
53+
_LIBCPP_HIDE_FROM_ABI tuple<allocator_arg_t, const _Alloc&, _Args&&...> __transform_tuple_using_allocator_impl(
54+
integral_constant<int, 1>, const _Alloc& __a, tuple<_Args...>&& __t, __index_sequence<_Is...>) {
55+
return tuple<allocator_arg_t, const _Alloc&, _Args&&...>(allocator_arg, __a, std::get<_Is>(std::move(__t))...);
56+
}
57+
58+
template <class _Alloc, class... _Args, size_t... _Is>
59+
_LIBCPP_HIDE_FROM_ABI tuple<_Args&&..., const _Alloc&> __transform_tuple_using_allocator_impl(
60+
integral_constant<int, 2>, const _Alloc& __a, tuple<_Args...>&& __t, __index_sequence<_Is...>) {
61+
return tuple<_Args&&..., const _Alloc&>(std::get<_Is>(std::move(__t))..., __a);
62+
}
63+
64+
template <class _Tp, class _Alloc, class... _Args>
65+
_LIBCPP_HIDE_FROM_ABI auto __transform_tuple_using_allocator(const _Alloc& __a, tuple<_Args...>&& __t)
66+
-> decltype(std::__transform_tuple_using_allocator_impl(
67+
__uses_alloc_ctor<_Tp, _Alloc, _Args...>{}, __a, std::move(__t), __make_index_sequence<sizeof...(_Args)>{})) {
68+
return std::__transform_tuple_using_allocator_impl(
69+
__uses_alloc_ctor<_Tp, _Alloc, _Args...>{}, __a, std::move(__t), __make_index_sequence<sizeof...(_Args)>{});
70+
}
71+
72+
#endif // !defined(_LIBCPP_CXX03_LANG) && _LIBCPP_STD_VER < 14
73+
74+
#if _LIBCPP_STD_VER >= 14
3375

3476
template <class _Tp>
3577
inline constexpr bool __is_cv_std_pair = __is_pair_v<remove_cv_t<_Tp>>;
@@ -40,17 +82,13 @@ struct __uses_allocator_construction_args;
4082
namespace __uses_allocator_detail {
4183

4284
template <class _Ap, class _Bp>
43-
void __fun(const pair<_Ap, _Bp>&);
44-
45-
template <class _Tp>
46-
decltype(__uses_allocator_detail::__fun(std::declval<_Tp>()), true_type()) __convertible_to_const_pair_ref_impl(int);
47-
48-
template <class>
49-
false_type __convertible_to_const_pair_ref_impl(...);
85+
void __pair_taker(const pair<_Ap, _Bp>&);
5086

87+
template <class, class = void>
88+
inline constexpr bool __convertible_to_const_pair_ref = false;
5189
template <class _Tp>
52-
inline constexpr bool __convertible_to_const_pair_ref =
53-
decltype(__uses_allocator_detail::__convertible_to_const_pair_ref_impl<_Tp>(0))::value;
90+
inline constexpr bool
91+
__convertible_to_const_pair_ref<_Tp, decltype(__uses_allocator_detail::__pair_taker(std::declval<_Tp>()))> = true;
5492

5593
# if _LIBCPP_STD_VER >= 23
5694
template <class _Tp, class _Up>
@@ -61,25 +99,75 @@ template <class _Tp, class _Up>
6199
inline constexpr bool __uses_allocator_constraints = __is_cv_std_pair<_Tp> && !__convertible_to_const_pair_ref<_Up>;
62100
# endif
63101

102+
# if _LIBCPP_STD_VER < 17
103+
template <class _Tp>
104+
struct __construction_fn {
105+
template <class... _Args>
106+
static _LIBCPP_HIDE_FROM_ABI constexpr _Tp operator()(_Args&&... __args) {
107+
static_assert(is_constructible<_Tp, _Args...>::value, "undesired C-style cast used");
108+
return _Tp(std::forward<_Args&&>(__args)...);
109+
}
110+
};
111+
112+
template <class _Fn, class _Tuple, size_t... _Ip>
113+
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) __apply_impl(_Fn&& __fn, _Tuple&& __t, index_sequence<_Ip...>) {
114+
return std::__invoke(std::forward<_Fn>(__fn), std::get<_Ip>(std::forward<_Tuple>(__t))...);
115+
}
116+
# endif // _LIBCPP_STD_VER < 17
117+
118+
template <class _Fn, class _Tuple>
119+
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) __apply(_Fn&& __fn, _Tuple&& __t) {
120+
# if _LIBCPP_STD_VER >= 17
121+
return std::apply(std::forward<_Fn>(__fn), std::forward<_Tuple>(__t));
122+
# else
123+
return __uses_allocator_detail::__apply_impl(
124+
std::forward<_Fn>(__fn),
125+
std::forward<_Tuple>(__t),
126+
std::make_index_sequence<tuple_size<__remove_cvref_t<_Tuple>>::value>{});
127+
# endif
128+
}
129+
130+
template <class _Tp, class _Tuple>
131+
_LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple(_Tuple&& __t) {
132+
# if _LIBCPP_STD_VER >= 17
133+
return std::make_from_tuple<_Tp>(std::forward<_Tuple>(__t));
134+
# else
135+
return __uses_allocator_detail::__apply_impl(
136+
__construction_fn<_Tp>{},
137+
std::forward<_Tuple>(__t),
138+
std::make_index_sequence<tuple_size<__remove_cvref_t<_Tuple>>::value>{});
139+
# endif
140+
}
141+
142+
template <class _Tp, class... _Args, class = decltype(::new (std::declval<void*>()) _Tp(std::declval<_Args>()...))>
143+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* __construct_at_nocv(_Tp* __location, _Args&&... __args) {
144+
return std::__construct_at(const_cast<remove_cv_t<_Tp>*>(__location), std::forward<_Args>(__args)...);
145+
}
146+
64147
} // namespace __uses_allocator_detail
65148

66149
template <class _Type, class _Alloc, class... _Args>
67-
_LIBCPP_HIDE_FROM_ABI constexpr _Type __make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args);
150+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Type
151+
__make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args);
68152

69153
template <class _Pair>
70154
struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<_Pair>>> {
71155
template <class _Alloc, class _Tuple1, class _Tuple2>
72-
static _LIBCPP_HIDE_FROM_ABI constexpr auto
156+
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
73157
__apply(const _Alloc& __alloc, piecewise_construct_t, _Tuple1&& __x, _Tuple2&& __y) noexcept {
74158
return std::make_tuple(
159+
# if _LIBCPP_STD_VER >= 20
75160
piecewise_construct,
76-
std::apply(
161+
# else // _LIBCPP_STD_VER >= 20
162+
std::ref(piecewise_construct),
163+
# endif // _LIBCPP_STD_VER >= 20
164+
__uses_allocator_detail::__apply(
77165
[&__alloc](auto&&... __args1) {
78166
return __uses_allocator_construction_args<typename _Pair::first_type>::__apply(
79167
__alloc, std::forward<decltype(__args1)>(__args1)...);
80168
},
81169
std::forward<_Tuple1>(__x)),
82-
std::apply(
170+
__uses_allocator_detail::__apply(
83171
[&__alloc](auto&&... __args2) {
84172
return __uses_allocator_construction_args<typename _Pair::second_type>::__apply(
85173
__alloc, std::forward<decltype(__args2)>(__args2)...);
@@ -88,12 +176,13 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
88176
}
89177

90178
template <class _Alloc>
91-
static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc) noexcept {
179+
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto __apply(const _Alloc& __alloc) noexcept {
92180
return __uses_allocator_construction_args<_Pair>::__apply(__alloc, piecewise_construct, tuple<>{}, tuple<>{});
93181
}
94182

95183
template <class _Alloc, class _Up, class _Vp>
96-
static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, _Up&& __u, _Vp&& __v) noexcept {
184+
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
185+
__apply(const _Alloc& __alloc, _Up&& __u, _Vp&& __v) noexcept {
97186
return __uses_allocator_construction_args<_Pair>::__apply(
98187
__alloc,
99188
piecewise_construct,
@@ -110,13 +199,15 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
110199
# endif
111200

112201
template <class _Alloc, class _Up, class _Vp>
113-
static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, const pair<_Up, _Vp>& __pair) noexcept {
202+
static _LIBCPP_HIDE_FROM_ABI
203+
_LIBCPP_CONSTEXPR_SINCE_CXX17 auto __apply(const _Alloc& __alloc, const pair<_Up, _Vp>& __pair) noexcept {
114204
return __uses_allocator_construction_args<_Pair>::__apply(
115205
__alloc, piecewise_construct, std::forward_as_tuple(__pair.first), std::forward_as_tuple(__pair.second));
116206
}
117207

118208
template <class _Alloc, class _Up, class _Vp>
119-
static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, pair<_Up, _Vp>&& __pair) noexcept {
209+
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
210+
__apply(const _Alloc& __alloc, pair<_Up, _Vp>&& __pair) noexcept {
120211
return __uses_allocator_construction_args<_Pair>::__apply(
121212
__alloc,
122213
piecewise_construct,
@@ -135,7 +226,8 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
135226
}
136227

137228
template < class _Alloc, __pair_like_no_subrange _PairLike>
138-
static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, _PairLike&& __p) noexcept {
229+
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
230+
__apply(const _Alloc& __alloc, _PairLike&& __p) noexcept {
139231
return __uses_allocator_construction_args<_Pair>::__apply(
140232
__alloc,
141233
piecewise_construct,
@@ -147,22 +239,25 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
147239
template <class _Alloc,
148240
class _Type,
149241
__enable_if_t<__uses_allocator_detail::__uses_allocator_constraints<_Pair, _Type>, int> = 0>
150-
static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, _Type&& __value) noexcept {
242+
static _LIBCPP_HIDE_FROM_ABI
243+
_LIBCPP_CONSTEXPR_SINCE_CXX17 auto __apply(const _Alloc& __alloc, _Type&& __value) noexcept {
151244
struct __pair_constructor {
152245
using _PairMutable = remove_cv_t<_Pair>;
153246

154-
_LIBCPP_HIDDEN constexpr auto __do_construct(const _PairMutable& __pair) const {
247+
_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX17 auto __do_construct(const _PairMutable& __pair) const {
155248
return std::__make_obj_using_allocator<_PairMutable>(__alloc_, __pair);
156249
}
157250

158-
_LIBCPP_HIDDEN constexpr auto __do_construct(_PairMutable&& __pair) const {
251+
_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX17 auto __do_construct(_PairMutable&& __pair) const {
159252
return std::__make_obj_using_allocator<_PairMutable>(__alloc_, std::move(__pair));
160253
}
161254

162255
const _Alloc& __alloc_;
163256
_Type& __value_;
164257

165-
_LIBCPP_HIDDEN constexpr operator _PairMutable() const { return __do_construct(std::forward<_Type>(__value_)); }
258+
_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX17 operator _PairMutable() const {
259+
return __do_construct(std::forward<_Type>(__value_));
260+
}
166261
};
167262

168263
return std::make_tuple(__pair_constructor{__alloc, __value});
@@ -172,14 +267,15 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
172267
template <class _Type>
173268
struct __uses_allocator_construction_args<_Type, __enable_if_t<!__is_cv_std_pair<_Type>>> {
174269
template <class _Alloc, class... _Args>
175-
static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, _Args&&... __args) noexcept {
176-
if constexpr (!uses_allocator_v<remove_cv_t<_Type>, _Alloc> && is_constructible_v<_Type, _Args...>) {
270+
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
271+
__apply(const _Alloc& __alloc, _Args&&... __args) noexcept {
272+
if constexpr (!uses_allocator<remove_cv_t<_Type>, _Alloc>::value && is_constructible<_Type, _Args...>::value) {
177273
return std::forward_as_tuple(std::forward<_Args>(__args)...);
178-
} else if constexpr (uses_allocator_v<remove_cv_t<_Type>, _Alloc> &&
179-
is_constructible_v<_Type, allocator_arg_t, const _Alloc&, _Args...>) {
274+
} else if constexpr (uses_allocator<remove_cv_t<_Type>, _Alloc>::value &&
275+
is_constructible<_Type, allocator_arg_t, const _Alloc&, _Args...>::value) {
180276
return tuple<allocator_arg_t, const _Alloc&, _Args&&...>(allocator_arg, __alloc, std::forward<_Args>(__args)...);
181-
} else if constexpr (uses_allocator_v<remove_cv_t<_Type>, _Alloc> &&
182-
is_constructible_v<_Type, _Args..., const _Alloc&>) {
277+
} else if constexpr (uses_allocator<remove_cv_t<_Type>, _Alloc>::value &&
278+
is_constructible<_Type, _Args..., const _Alloc&>::value) {
183279
return std::forward_as_tuple(std::forward<_Args>(__args)..., __alloc);
184280
} else {
185281
static_assert(
@@ -189,19 +285,34 @@ struct __uses_allocator_construction_args<_Type, __enable_if_t<!__is_cv_std_pair
189285
};
190286

191287
template <class _Type, class _Alloc, class... _Args>
192-
_LIBCPP_HIDE_FROM_ABI constexpr _Type __make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args) {
193-
return std::make_from_tuple<_Type>(
288+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Type
289+
__make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args) {
290+
return __uses_allocator_detail::__make_from_tuple<_Type>(
194291
__uses_allocator_construction_args<_Type>::__apply(__alloc, std::forward<_Args>(__args)...));
195292
}
196293

294+
#endif // _LIBCPP_STD_VER >= 14
295+
296+
#if _LIBCPP_STD_VER >= 17
297+
197298
template <class _Type, class _Alloc, class... _Args>
198-
_LIBCPP_HIDE_FROM_ABI constexpr _Type*
299+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
199300
__uninitialized_construct_using_allocator(_Type* __ptr, const _Alloc& __alloc, _Args&&... __args) {
200301
return std::apply(
201302
[&__ptr](auto&&... __xs) { return std::__construct_at(__ptr, std::forward<decltype(__xs)>(__xs)...); },
202303
__uses_allocator_construction_args<_Type>::__apply(__alloc, std::forward<_Args>(__args)...));
203304
}
204305

306+
template <class _Type, class _Alloc, class... _Args>
307+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
308+
__uninitialized_construct_using_allocator_nocv(_Type* __ptr, const _Alloc& __alloc, _Args&&... __args) {
309+
return std::apply(
310+
[&__ptr](auto&&... __xs) {
311+
return __uses_allocator_detail::__construct_at_nocv(__ptr, std::forward<decltype(__xs)>(__xs)...);
312+
},
313+
__uses_allocator_construction_args<_Type>::__apply(__alloc, std::forward<_Args>(__args)...));
314+
}
315+
205316
#endif // _LIBCPP_STD_VER >= 17
206317

207318
#if _LIBCPP_STD_VER >= 20

0 commit comments

Comments
 (0)