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
3476template <class _Tp >
3577inline constexpr bool __is_cv_std_pair = __is_pair_v<remove_cv_t <_Tp>>;
@@ -40,17 +82,13 @@ struct __uses_allocator_construction_args;
4082namespace __uses_allocator_detail {
4183
4284template <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 ;
5189template <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
5694template <class _Tp , class _Up >
@@ -61,25 +99,71 @@ template <class _Tp, class _Up>
6199inline 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_v<_Tp, _Args...>, " 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), std::forward<_Tuple>(__t ), std::make_index_sequence<__remove_cvref_t <_Tuple>>{});
125+ # endif
126+ }
127+
128+ template <class _Tp , class _Tuple >
129+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple (_Tp&& __t ) {
130+ # if _LIBCPP_STD_VER >= 17
131+ return std::make_from_tuple<_Tp>(std::forward<_Tuple>(__t ));
132+ # else
133+ return __uses_allocator_detail::__apply_impl (
134+ __construction_fn<_Tp>{}, std::forward<_Tuple>(__t ), std::make_index_sequence<__remove_cvref_t <_Tuple>>{});
135+ # endif
136+ }
137+
138+ template <class _Tp , class ... _Args, class = decltype (::new (std::declval<void *>()) _Tp(std::declval<_Args>()...))>
139+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* __construct_nocv_at (_Tp* __location, _Args&&... __args) {
140+ return std::__construct_at (const_cast <remove_cv_t <_Tp>*>(__location), std::forward<_Args>(__args)...);
141+ }
142+
64143} // namespace __uses_allocator_detail
65144
66145template <class _Type , class _Alloc , class ... _Args>
67- _LIBCPP_HIDE_FROM_ABI constexpr _Type __make_obj_using_allocator (const _Alloc& __alloc, _Args&&... __args);
146+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Type
147+ __make_obj_using_allocator (const _Alloc& __alloc, _Args&&... __args);
68148
69149template <class _Pair >
70150struct __uses_allocator_construction_args <_Pair, __enable_if_t <__is_cv_std_pair<_Pair>>> {
71151 template <class _Alloc , class _Tuple1 , class _Tuple2 >
72- static _LIBCPP_HIDE_FROM_ABI constexpr auto
152+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
73153 __apply (const _Alloc& __alloc, piecewise_construct_t , _Tuple1&& __x, _Tuple2&& __y) noexcept {
74154 return std::make_tuple (
155+ # if _LIBCPP_STD_VER >= 20
75156 piecewise_construct,
76- std::apply (
157+ # else // _LIBCPP_STD_VER >= 20
158+ std::ref (piecewise_construct),
159+ # endif // _LIBCPP_STD_VER >= 20
160+ __uses_allocator_detail::__apply (
77161 [&__alloc](auto &&... __args1) {
78162 return __uses_allocator_construction_args<typename _Pair::first_type>::__apply (
79163 __alloc, std::forward<decltype (__args1)>(__args1)...);
80164 },
81165 std::forward<_Tuple1>(__x)),
82- std::apply (
166+ __uses_allocator_detail::__apply (
83167 [&__alloc](auto &&... __args2) {
84168 return __uses_allocator_construction_args<typename _Pair::second_type>::__apply (
85169 __alloc, std::forward<decltype (__args2)>(__args2)...);
@@ -88,12 +172,13 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
88172 }
89173
90174 template <class _Alloc >
91- static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply (const _Alloc& __alloc) noexcept {
175+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto __apply (const _Alloc& __alloc) noexcept {
92176 return __uses_allocator_construction_args<_Pair>::__apply (__alloc, piecewise_construct, tuple<>{}, tuple<>{});
93177 }
94178
95179 template <class _Alloc , class _Up , class _Vp >
96- static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply (const _Alloc& __alloc, _Up&& __u, _Vp&& __v) noexcept {
180+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
181+ __apply (const _Alloc& __alloc, _Up&& __u, _Vp&& __v) noexcept {
97182 return __uses_allocator_construction_args<_Pair>::__apply (
98183 __alloc,
99184 piecewise_construct,
@@ -110,13 +195,15 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
110195# endif
111196
112197 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 {
198+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
199+ __apply (const _Alloc& __alloc, const pair<_Up, _Vp>& __pair) noexcept {
114200 return __uses_allocator_construction_args<_Pair>::__apply (
115201 __alloc, piecewise_construct, std::forward_as_tuple (__pair.first ), std::forward_as_tuple (__pair.second ));
116202 }
117203
118204 template <class _Alloc , class _Up , class _Vp >
119- static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply (const _Alloc& __alloc, pair<_Up, _Vp>&& __pair) noexcept {
205+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
206+ __apply (const _Alloc& __alloc, pair<_Up, _Vp>&& __pair) noexcept {
120207 return __uses_allocator_construction_args<_Pair>::__apply (
121208 __alloc,
122209 piecewise_construct,
@@ -135,7 +222,8 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
135222 }
136223
137224 template < class _Alloc , __pair_like_no_subrange _PairLike>
138- static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply (const _Alloc& __alloc, _PairLike&& __p) noexcept {
225+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
226+ __apply (const _Alloc& __alloc, _PairLike&& __p) noexcept {
139227 return __uses_allocator_construction_args<_Pair>::__apply (
140228 __alloc,
141229 piecewise_construct,
@@ -147,22 +235,25 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
147235 template <class _Alloc ,
148236 class _Type ,
149237 __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 {
238+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
239+ __apply (const _Alloc& __alloc, _Type&& __value) noexcept {
151240 struct __pair_constructor {
152241 using _PairMutable = remove_cv_t <_Pair>;
153242
154- _LIBCPP_HIDDEN constexpr auto __do_construct (const _PairMutable& __pair) const {
243+ _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX17 auto __do_construct (const _PairMutable& __pair) const {
155244 return std::__make_obj_using_allocator<_PairMutable>(__alloc_, __pair);
156245 }
157246
158- _LIBCPP_HIDDEN constexpr auto __do_construct (_PairMutable&& __pair) const {
247+ _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX17 auto __do_construct (_PairMutable&& __pair) const {
159248 return std::__make_obj_using_allocator<_PairMutable>(__alloc_, std::move (__pair));
160249 }
161250
162251 const _Alloc& __alloc_;
163252 _Type& __value_;
164253
165- _LIBCPP_HIDDEN constexpr operator _PairMutable () const { return __do_construct (std::forward<_Type>(__value_)); }
254+ _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX17 operator _PairMutable () const {
255+ return __do_construct (std::forward<_Type>(__value_));
256+ }
166257 };
167258
168259 return std::make_tuple (__pair_constructor{__alloc, __value});
@@ -172,7 +263,8 @@ struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<
172263template <class _Type >
173264struct __uses_allocator_construction_args <_Type, __enable_if_t <!__is_cv_std_pair<_Type>>> {
174265 template <class _Alloc , class ... _Args>
175- static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply (const _Alloc& __alloc, _Args&&... __args) noexcept {
266+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
267+ __apply (const _Alloc& __alloc, _Args&&... __args) noexcept {
176268 if constexpr (!uses_allocator_v<remove_cv_t <_Type>, _Alloc> && is_constructible_v<_Type, _Args...>) {
177269 return std::forward_as_tuple (std::forward<_Args>(__args)...);
178270 } else if constexpr (uses_allocator_v<remove_cv_t <_Type>, _Alloc> &&
@@ -189,20 +281,31 @@ struct __uses_allocator_construction_args<_Type, __enable_if_t<!__is_cv_std_pair
189281};
190282
191283template <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>(
284+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Type
285+ __make_obj_using_allocator (const _Alloc& __alloc, _Args&&... __args) {
286+ return __uses_allocator_detail::__make_from_tuple<_Type>(
194287 __uses_allocator_construction_args<_Type>::__apply (__alloc, std::forward<_Args>(__args)...));
195288}
196289
197290template <class _Type , class _Alloc , class ... _Args>
198- _LIBCPP_HIDE_FROM_ABI constexpr _Type*
291+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
199292__uninitialized_construct_using_allocator (_Type* __ptr, const _Alloc& __alloc, _Args&&... __args) {
200293 return std::apply (
201294 [&__ptr](auto &&... __xs) { return std::__construct_at (__ptr, std::forward<decltype (__xs)>(__xs)...); },
202295 __uses_allocator_construction_args<_Type>::__apply (__alloc, std::forward<_Args>(__args)...));
203296}
204297
205- #endif // _LIBCPP_STD_VER >= 17
298+ template <class _Type , class _Alloc , class ... _Args>
299+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type*
300+ __uninitialized_construct_using_allocator_nocv (_Type* __ptr, const _Alloc& __alloc, _Args&&... __args) {
301+ return std::apply (
302+ [&__ptr](auto &&... __xs) {
303+ return __uses_allocator_detail::__construct_nocv_at (__ptr, std::forward<decltype (__xs)>(__xs)...);
304+ },
305+ __uses_allocator_construction_args<_Type>::__apply (__alloc, std::forward<_Args>(__args)...));
306+ }
307+
308+ #endif // _LIBCPP_STD_VER >= 14
206309
207310#if _LIBCPP_STD_VER >= 20
208311
0 commit comments