Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and
is_constructible_v<T, allocator_arg_t, const Alloc&, Args..>
is true,
return
tuple<allocator_arg_t, const Alloc&, Args&&.>(
allocator_arg, alloc, std::forward<Args>(args).)
Otherwise, if
uses_allocator_v<remove_cv_t<T>, Alloc> is
true and
is_constructible_v<T, Args.., const Alloc&> is
true,
return
forward_as_tuple(std::forward<Args>(args)., alloc).Otherwise, the program is ill-formed
. [
Note 2:
This definition prevents a silent failure
to pass the allocator to a constructor of a type for which
uses_allocator_v<T, Alloc> is
true. —
end note]
template<class T, class Alloc, class Tuple1, class Tuple2>
constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
Tuple1&& x, Tuple2&& y) noexcept;
Effects: Equivalent to:
return make_tuple(
piecewise_construct,
apply([&alloc](auto&. args1) {
return uses_allocator_construction_args<T1>(
alloc, std::forward<decltype(args1)>(args1).);
}, std::forward<Tuple1>(x)),
apply([&alloc](auto&. args2) {
return uses_allocator_construction_args<T2>(
alloc, std::forward<decltype(args2)>(args2).);
}, std::forward<Tuple2>(y));
template<class T, class Alloc>
constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept;
Effects: Equivalent to:
return uses_allocator_construction_args<T>(alloc, piecewise_construct,
tuple<>{}, tuple<>{});
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
U&& u, V&& v) noexcept;
Effects: Equivalent to:
return uses_allocator_construction_args<T>(alloc, piecewise_construct,
forward_as_tuple(std::forward<U>(u)),
forward_as_tuple(std::forward<V>(v));
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
pair<U, V>& pr) noexcept;
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
const pair<U, V>& pr) noexcept;
Effects: Equivalent to:
return uses_allocator_construction_args<T>(alloc, piecewise_construct,
forward_as_tuple(pr.first),
forward_as_tuple(pr.second));
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
pair<U, V>& pr) noexcept;
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
const pair<U, V>& pr) noexcept;
Effects: Equivalent to:
return uses_allocator_construction_args<T>(alloc, piecewise_construct,
forward_as_tuple(get<0>(std::move(pr)),
forward_as_tuple(get<1>(std::move(pr));
template<class T, class Alloc, pair-like P>
constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;
Constraints:
remove_cv_t<T> is a specialization of
pair and
remove_cvref_t<P> is not a specialization of
ranges::subrange. Effects: Equivalent to:
return uses_allocator_construction_args<T>(alloc, piecewise_construct,
forward_as_tuple(get<0>(std::forward<P>(p)),
forward_as_tuple(get<1>(std::forward<P>(p));
template<class T, class Alloc, class U>
constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
Let FUN be the function template:
template<class A, class B>
void FUN(const pair<A, B>&);
Constraints:
remove_cv_t<T> is a specialization of
pair, and either:
- remove_cvref_t<U> is a specialization of ranges::subrange, or
- U does not satisfy pair-like and
the expression FUN(u) is not well-formed
when considered as an unevaluated operand.
Let pair-constructor be an exposition-only class defined as follows:
class pair-constructor {
using pair-type = remove_cv_t<T>;
constexpr auto do-construct(const pair-type& p) const {
return make_obj_using_allocator<pair-type>(alloc_, p);
}
constexpr auto do-construct(pair-type&& p) const {
return make_obj_using_allocator<pair-type>(alloc_, std::move(p));
}
const Alloc& alloc_;
U& u_;
public:
constexpr operator pair-type() const {
return do-construct(std::forward<U>(u_));
}
};
Returns:
make_tuple(pc),
where
pc is a
pair-constructor object
whose
alloc_ member is initialized with
alloc and
whose
u_ member is initialized with
u. template<class T, class Alloc, class. Args>
constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&. args);
Effects: Equivalent to:
return make_from_tuple<T>(uses_allocator_construction_args<T>(
alloc, std::forward<Args>(args).);
template<class T, class Alloc, class. Args>
constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&. args);
Effects: Equivalent to:
return apply([&]<class. U>(U&&. xs) {
return construct_at(p, std::forward<U>(xs).);
}, uses_allocator_construction_args<T>(alloc, std::forward<Args>(args).);