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.