@@ -2067,6 +2067,30 @@ typename _Container::size_type _Erase_nodes_if(_Container& _Cont, _Pr _Pred) {
2067
2067
return _Old_size - _Cont.size();
2068
2068
}
2069
2069
2070
+ template <class _Ty1, class _Ty2>
2071
+ void _Deduce_as_pair(const pair<_Ty1, _Ty2>&); // not defined
2072
+
2073
+ template <class _Ty, class = void>
2074
+ _INLINE_VAR constexpr bool _Is_deducible_as_pair = false;
2075
+
2076
+ template <class _Ty>
2077
+ _INLINE_VAR constexpr bool _Is_deducible_as_pair<_Ty, decltype(_Deduce_as_pair(_STD declval<_Ty>()))> = true;
2078
+
2079
+ template <class _Ty>
2080
+ const _Ty& _Normally_bind(_Identity_t<const _Ty&>); // not defined
2081
+
2082
+ template <class _Ty>
2083
+ _Ty&& _Normally_bind(_Identity_t<_Ty&&>); // not defined
2084
+
2085
+ template <class _Ty, class _Uty>
2086
+ using _Normally_bound_ref = decltype(_Normally_bind<_Ty>(_STD declval<_Uty>()));
2087
+
2088
+ template <class _Ty, class _Uty, class = void>
2089
+ _INLINE_VAR constexpr bool _Is_normally_bindable = false;
2090
+
2091
+ template <class _Ty, class _Uty>
2092
+ _INLINE_VAR constexpr bool _Is_normally_bindable<_Ty, _Uty, void_t<_Normally_bound_ref<_Ty, _Uty>>> = true;
2093
+
2070
2094
#if _HAS_CXX20
2071
2095
template <class _Ty, class _Alloc, class... _Types, enable_if_t<!_Is_specialization_v<_Ty, pair>, int> = 0>
2072
2096
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Types&&... _Args) noexcept {
@@ -2099,6 +2123,10 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, co
2099
2123
template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_specialization_v<_Ty, pair>, int> = 0>
2100
2124
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pair<_Uty1, _Uty2>&& _Pair) noexcept;
2101
2125
2126
+ template <class _Ty, class _Alloc, class _Uty,
2127
+ enable_if_t<_Is_specialization_v<_Ty, pair> && !_Is_deducible_as_pair<_Uty&>, int> = 0>
2128
+ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept;
2129
+
2102
2130
template <class _Ty, class _Alloc, class _Tuple1, class _Tuple2, enable_if_t<_Is_specialization_v<_Ty, pair>, int> = 0>
2103
2131
_NODISCARD constexpr auto uses_allocator_construction_args(
2104
2132
const _Alloc& _Al, piecewise_construct_t, _Tuple1&& _Tup1, _Tuple2&& _Tup2) noexcept {
@@ -2156,6 +2184,43 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pa
2156
2184
_STD uses_allocator_construction_args<typename _Ty::second_type>(_Al, _STD get<1>(_STD move(_Pair))));
2157
2185
}
2158
2186
2187
+ template <class _Ty, class _Alloc, class _Uty,
2188
+ enable_if_t<_Is_specialization_v<_Ty, pair> && !_Is_deducible_as_pair<_Uty&>, int>>
2189
+ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept {
2190
+ struct _Pair_remaker {
2191
+ const _Alloc& _Al;
2192
+ _Uty& _Ux;
2193
+
2194
+ constexpr operator remove_cv_t<_Ty>() const {
2195
+ using _Pair_t = remove_cv_t<_Ty>;
2196
+ static_assert(_Is_normally_bindable<_Pair_t, _Uty>,
2197
+ "The argument must be bindable to a reference to the std::pair type.");
2198
+
2199
+ using _Pair_first_t = typename _Pair_t::first_type;
2200
+ using _Pair_second_t = typename _Pair_t::second_type;
2201
+ using _Pair_ref_t = _Normally_bound_ref<_Pair_t, _Uty>;
2202
+ _Pair_ref_t _Pair_ref = _STD forward<_Uty>(_Ux);
2203
+ if constexpr (is_same_v<_Pair_ref_t, const _Pair_t&>) {
2204
+ // equivalent to
2205
+ // return _STD make_obj_using_allocator<_Pair_t>(_Al, _Pair_ref);
2206
+ return _Pair_t{piecewise_construct,
2207
+ _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _Pair_ref.first),
2208
+ _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _Pair_ref.second)};
2209
+ } else {
2210
+ // equivalent to
2211
+ // return _STD make_obj_using_allocator<_Pair_t>(_Al, _STD move(_Pair_ref));
2212
+ return _Pair_t{piecewise_construct,
2213
+ _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _STD get<0>(_STD move(_Pair_ref))),
2214
+ _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _STD get<1>(_STD move(_Pair_ref)))};
2215
+ }
2216
+ }
2217
+ };
2218
+
2219
+ // equivalent to
2220
+ // return _STD make_tuple(_Pair_remaker{_Al, _Ux});
2221
+ return tuple<_Pair_remaker>({_Al, _Ux});
2222
+ }
2223
+
2159
2224
template <class _Ty, class _Alloc, class... _Types>
2160
2225
_NODISCARD constexpr _Ty make_obj_using_allocator(const _Alloc& _Al, _Types&&... _Args) {
2161
2226
return _STD make_from_tuple<_Ty>(_STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...));
0 commit comments