[allocator.uses] (original) (raw)

20.2.8.1 uses_allocator trait [allocator.uses.trait]

template<class T, class Alloc> struct uses_allocator;

Remarks: Automatically detects whether T has a nested allocator_type that is convertible from Alloc.

The implementation shall provide a definition that is derived from true_type if the qualified-id T​::​allocator_typeis valid and denotes a type ([temp.deduct]) andis_convertible_v<Alloc, T​::​allocator_type> != false, otherwise it shall be derived from false_type.

A program may specialize this template to derive fromtrue_type for a program-defined type T that does not have a nestedallocator_type but nonetheless can be constructed with an allocator where either:

20.2.8.2 Uses-allocator construction [allocator.uses.construction]

Uses-allocator constructionwith allocator alloc and constructor arguments args...refers to the construction of an object of type Tsuch that alloc is passed to the constructor of Tif T uses an allocator type compatible with alloc.

When applied to the construction of an object of type T, it is equivalent to initializing it with the value of the expressionmake_obj_using_allocator<T>(alloc, args...), described below.

The following utility functions support three conventions for passing alloc to a constructor:

The uses_allocator_construction_args function template takes an allocator and argument list and produces (as a tuple) a new argument list matching one of the above conventions.

Additionally, overloads are provided that treat specializations of pairsuch that uses-allocator construction is applied individually to the first and second data members.

The make_obj_using_allocator anduninitialized_construct_using_allocator function templates apply the modified constructor arguments to construct an object of type Tas a return value or in-place, respectively.

[Note 1:

For uses_allocator_construction_args andmake_obj_using_allocator, type Tis not deduced and must therefore be specified explicitly by the caller.

— _end note_]

template<class T, class Alloc, class... Args> constexpr auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) noexcept;

Constraints: remove_cv_t<T> is not a specialization of pair.

Returns: A tuple value determined as follows:

[Note 2:

This definition prevents a silent failure to pass the allocator to a constructor of a type for whichuses_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;

Let T1 be T​::​first_type.

Let T2 be T​::​second_type.

Constraints: remove_cv_t<T> is a specialization of pair.

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;

Constraints: remove_cv_t<T> is a specialization of pair.

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;

Constraints: remove_cv_t<T> is a specialization of pair.

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;

Constraints: remove_cv_t<T> is a specialization of pair.

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;

Constraints: remove_cv_t<T> is a specialization of pair.

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_](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P> constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;

Constraints: remove_cv_t<T> is a specialization of pair andremove_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:

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)...));