23 General utilities library [utilities]

23.13 Class template scoped_­allocator_­adaptor [allocator.adaptor]

23.13.4 Scoped allocator adaptor members [allocator.adaptor.members]

In the construct member functions, OUTERMOST(x) is x if x does not have an outer_­allocator() member function and OUTERMOST(x.outer_­allocator()) otherwise; OUTERMOST_­ALLOC_­TRAITS(x) is allocator_­traits<decltype(OUTERMOST(x))>.
[Note
:
OUTERMOST(x) and OUTERMOST_­ALLOC_­TRAITS(x) are recursive operations.
It is incumbent upon the definition of outer_­allocator() to ensure that the recursion terminates.
It will terminate for all instantiations of scoped_­allocator_­adaptor.
end note
]
inner_allocator_type& inner_allocator() noexcept; const inner_allocator_type& inner_allocator() const noexcept;
Returns: *this if sizeof...(InnerAllocs) is zero; otherwise, inner.
outer_allocator_type& outer_allocator() noexcept;
Returns: static_­cast<OuterAlloc&>(*this).
const outer_allocator_type& outer_allocator() const noexcept;
Returns: static_­cast<const OuterAlloc&>(*this).
pointer allocate(size_type n);
Returns: allocator_­traits<OuterAlloc>​::​allocate(outer_­allocator(), n).
pointer allocate(size_type n, const_void_pointer hint);
Returns: allocator_­traits<OuterAlloc>​::​allocate(outer_­allocator(), n, hint).
void deallocate(pointer p, size_type n) noexcept;
Effects: As if by: allocator_­traits<OuterAlloc>​::​deallocate(outer_­allocator(), p, n);
size_type max_size() const;
Returns: allocator_­traits<OuterAlloc>​::​max_­size(outer_­allocator()).
template <class T, class... Args> void construct(T* p, Args&&... args);
Effects:
  • If uses_­allocator_­v<T, inner_­allocator_­type> is false and is_­constructible_­v<T,
    Args...>
    is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, std::forward<Args>(args)...)
  • Otherwise, if uses_­allocator_­v<T, inner_­allocator_­type> is true and is_­constructible_­v<T, allocator_­arg_­t, inner_­allocator_­type&, Args...> is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, allocator_arg, inner_allocator(), std::forward<Args>(args)...)
  • Otherwise, if uses_­allocator_­v<T, inner_­allocator_­type> is true and is_­constructible_­v<T, Args..., inner_­allocator_­type&> is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, std::forward<Args>(args)..., inner_allocator())
  • Otherwise, the program is ill-formed.
    [Note
    :
    An error will result if uses_­allocator evaluates to true but the specific constructor does not take an allocator.
    This definition prevents a silent failure to pass an inner allocator to a contained element.
    end note
    ]
template <class T1, class T2, class... Args1, class... Args2> void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
Requires: All of the types in Args1 and Args2 shall be CopyConstructible.
Effects: Constructs a tuple object xprime from x by the following rules:
  • If uses_­allocator_­v<T1, inner_­allocator_­type> is false and is_­constructible_­v<T1,
    Args1...>
    is true, then xprime is x.
  • Otherwise, if uses_­allocator_­v<T1, inner_­allocator_­type> is true and is_­constructible_­v<T1, allocator_­arg_­t, inner_­allocator_­type&, Args1...> is true, then xprime is:
    tuple_cat(
        tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()),
        std::move(x))
  • Otherwise, if uses_­allocator_­v<T1, inner_­allocator_­type> is true and is_­constructible_­v<T1, Args1..., inner_­allocator_­type&> is true, then xprime is:
    tuple_cat(std::move(x), tuple<inner_allocator_type&>(inner_allocator()))
  • Otherwise, the program is ill-formed.
and constructs a tuple object yprime from y by the following rules:
  • If uses_­allocator_­v<T2, inner_­allocator_­type> is false and is_­constructible_­v<T2,
    Args2...>
    is true, then yprime is y.
  • Otherwise, if uses_­allocator_­v<T2, inner_­allocator_­type> is true and is_­constructible_­v<T2, allocator_­arg_­t, inner_­allocator_­type&, Args2...> is true, then yprime is:
    tuple_cat(
        tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()),
        std::move(y))
  • Otherwise, if uses_­allocator_­v<T2, inner_­allocator_­type> is true and is_­constructible_­v<T2, Args2..., inner_­allocator_­type&> is true, then yprime is:
    tuple_cat(std::move(y), tuple<inner_allocator_type&>(inner_allocator()))
  • Otherwise, the program is ill-formed.
then calls:
OUTERMOST_ALLOC_TRAITS(*this)::construct(
    OUTERMOST(*this), p, piecewise_construct, std::move(xprime), std::move(yprime))
template <class T1, class T2> void construct(pair<T1, T2>* p);
Effects: Equivalent to:
construct(p, piecewise_construct, tuple<>(), tuple<>());
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, U&& x, V&& y);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(x)),
          forward_as_tuple(std::forward<V>(y)));
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, const pair<U, V>& x);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(x.first),
          forward_as_tuple(x.second));
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, pair<U, V>&& x);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(x.first)),
          forward_as_tuple(std::forward<V>(x.second)));
template <class T> void destroy(T* p);
Effects: Calls OUTERMOST_­ALLOC_­TRAITS(*this)​::​destroy(OUTERMOST(*this), p).
scoped_allocator_adaptor select_on_container_copy_construction() const;
Returns: A new scoped_­allocator_­adaptor object where each allocator A in the adaptor is initialized from the result of calling allocator_­traits<A>​::​select_­on_­container_­copy_­construction() on the corresponding allocator in *this.