// scoped allocator adaptor
template <class OuterAlloc, class... InnerAlloc>
class scoped_allocator_adaptor;
template <class OuterA1, class OuterA2, class... InnerAllocs>
bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
template <class OuterA1, class OuterA2, class... InnerAllocs>
bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Шаблон классаscoped_allocator_adaptor - это шаблон распределителя, который указывает ресурс памяти (внешний распределитель), который будет использоваться контейнером (как и любой другой распределитель), а также определяет ресурс внутреннего распределителя, который должен быть передан конструктору каждого элемента в контейнере. Этот адаптер создается с одним внешним и нулевым или несколькими типами внутреннего распределителя. При создании экземпляра только с одним типом распределителя внутренний распределитель становитсяscoped_allocator_adaptor самим собой, таким образом используя один и тот же ресурс распределителя для контейнера и каждого элемента в контейнере, а если сами элементы являются контейнерами, каждый из их элементов рекурсивно. При создании экземпляра с более чем одним распределителем первый распределитель является внешним распределителем для использования контейнером, второй распределитель передается конструкторам элементов контейнера, и, если сами элементы являются контейнерами, третий распределитель передается в элементы и т. д. Если контейнеры вложены на глубину, превышающую количество распределителей, последний распределитель используется повторно, как в случае с одним распределителем, для любых оставшихся рекурсий. [ Происходят от внешнего вида распределителя так что он может быть заменен на внешний тип распределителя в большинстве выражений. ] Note: scoped_allocator_adaptor — end note
namespace std { template <class OuterAlloc, class... InnerAllocs> class scoped_allocator_adaptor : public OuterAlloc { private: using OuterTraits = allocator_traits<OuterAlloc>; // exposition only scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only public: using outer_allocator_type = OuterAlloc; using inner_allocator_type = see below; using value_type = typename OuterTraits::value_type; using size_type = typename OuterTraits::size_type; using difference_type = typename OuterTraits::difference_type; using pointer = typename OuterTraits::pointer; using const_pointer = typename OuterTraits::const_pointer; using void_pointer = typename OuterTraits::void_pointer; using const_void_pointer = typename OuterTraits::const_void_pointer; using propagate_on_container_copy_assignment = see below; using propagate_on_container_move_assignment = see below; using propagate_on_container_swap = see below; using is_always_equal = see below; template <class Tp> struct rebind { using other = scoped_allocator_adaptor< OuterTraits::template rebind_alloc<Tp>, InnerAllocs...>; }; scoped_allocator_adaptor(); template <class OuterA2> scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept; scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept; scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept; template <class OuterA2> scoped_allocator_adaptor( const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept; template <class OuterA2> scoped_allocator_adaptor( scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept; scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; ~scoped_allocator_adaptor(); inner_allocator_type& inner_allocator() noexcept; const inner_allocator_type& inner_allocator() const noexcept; outer_allocator_type& outer_allocator() noexcept; const outer_allocator_type& outer_allocator() const noexcept; pointer allocate(size_type n); pointer allocate(size_type n, const_void_pointer hint); void deallocate(pointer p, size_type n); size_type max_size() const; template <class T, class... Args> void construct(T* p, Args&&... args); template <class T1, class T2, class... Args1, class... Args2> void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y); template <class T1, class T2> void construct(pair<T1, T2>* p); template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, U&& x, V&& y); template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, const pair<U, V>& x); template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, pair<U, V>&& x); template <class T> void destroy(T* p); scoped_allocator_adaptor select_on_container_copy_construction() const; }; template<class OuterAlloc, class... InnerAllocs> scoped_allocator_adaptor(OuterAlloc, InnerAllocs...) -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>; template <class OuterA1, class OuterA2, class... InnerAllocs> bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; template <class OuterA1, class OuterA2, class... InnerAllocs> bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; }
using inner_allocator_type = see below;
Type:scoped_allocator_adaptor<OuterAlloc> еслиsizeof...(InnerAllocs) равно нулю; в противном случае
scoped_allocator_adaptor<InnerAllocs...>.
using propagate_on_container_copy_assignment = see below;
Type:true_type если allocator_traits<A>::propagate_on_container_copy_assignment::value это true для любогоA в набореOuterAlloc и InnerAllocs...; в противном случаеfalse_type.
using propagate_on_container_move_assignment = see below;
Type:true_type если allocator_traits<A>::propagate_on_container_move_assignment::value это true для любогоA в набореOuterAlloc и InnerAllocs...; в противном случаеfalse_type.
using propagate_on_container_swap = see below;
Type:true_type если allocator_traits<A>::propagate_on_container_swap::value это true для любогоA в набореOuterAlloc и InnerAllocs...; в противном случаеfalse_type.
using is_always_equal = see below;
scoped_allocator_adaptor();
template <class OuterA2>
scoped_allocator_adaptor(OuterA2&& outerAlloc,
const InnerAllocs&... innerAllocs) noexcept;
Effects: ИнициализируетOuterAlloc базовый класс с помощью std::forward<OuterA2>(outerAlloc) иinner сinnerAllocs... (следовательно, рекурсивно инициализирует каждый распределитель в адаптере соответствующим распределителем из списка аргументов).
Remarks: Этот конструктор не должен участвовать в разрешении перегрузки , если is_constructible_v<OuterAlloc, OuterA2> неtrue.
scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
template <class OuterA2>
scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2,
InnerAllocs...>& other) noexcept;
Remarks: Этот конструктор не должен участвовать в разрешении перегрузки , если is_constructible_v<OuterAlloc, const OuterA2&> неtrue.
template <class OuterA2>
scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2,
InnerAllocs...>&& other) noexcept;
Effects: Инициализирует каждый распределитель в адаптере соответствующим rvalue распределителя изother.
Вconstruct функциях-членах OUTERMOST(x) isx ifx не имеет outer_allocator() функции-члена, а в OUTERMOST(x.outer_allocator()) противном случае; OUTERMOST_ALLOC_TRAITS(x) есть allocator_traits<decltype(OUTERMOST(x))>. [ Note:OUTERMOST(x) и OUTERMOST_ALLOC_TRAITS(x) являются рекурсивными операциями. Определениеouter_allocator() должно гарантировать, что рекурсия завершится. Это прекратится для всех экземпляров scoped_allocator_adaptor. ] — end note
inner_allocator_type& inner_allocator() noexcept;
const inner_allocator_type& inner_allocator() const noexcept;
outer_allocator_type& outer_allocator() noexcept;
const outer_allocator_type& outer_allocator() const noexcept;
pointer allocate(size_type n);
pointer allocate(size_type n, const_void_pointer hint);
void deallocate(pointer p, size_type n) noexcept;
size_type max_size() const;
template <class T, class... Args>
void construct(T* p, Args&&... args);
Effects:
Еслиuses_allocator_v<T, inner_allocator_type> естьfalse и
is_constructible_v<T,
Args...> естьtrue, звонки:
OUTERMOST_ALLOC_TRAITS(*this)::construct( OUTERMOST(*this), p, std::forward<Args>(args)...)
В противном случае, еслиuses_allocator_v<T, inner_allocator_type> естьtrue и is_constructible_v<T, allocator_arg_t, inner_allocator_type&, Args...> естьtrue, вызывает:
OUTERMOST_ALLOC_TRAITS(*this)::construct( OUTERMOST(*this), p, allocator_arg, inner_allocator(), std::forward<Args>(args)...)
В противном случае, еслиuses_allocator_v<T, inner_allocator_type> естьtrue и is_constructible_v<T, Args..., inner_allocator_type&> естьtrue, вызывает:
OUTERMOST_ALLOC_TRAITS(*this)::construct( OUTERMOST(*this), p, std::forward<Args>(args)..., inner_allocator())
В противном случае программа имеет неверный формат. [ Note: Произойдет ошибка, если uses_allocator вычислено значение,true но конкретный конструктор не использует распределитель. Это определение предотвращает тихую ошибку передачи внутреннего распределителя в содержащийся элемент. ] — 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: все типы вArgs1 иArgs2 должны быть CopyConstructible.
Effects: Создаётtuple объектxprime изx следующих правил:
Еслиuses_allocator_v<T1, inner_allocator_type> естьfalse и
is_constructible_v<T1,
Args1...> естьtrue, значит,xprime естьx.
В противном случае, еслиuses_allocator_v<T1, inner_allocator_type> естьtrue и is_constructible_v<T1, allocator_arg_t, inner_allocator_type&, Args1...> есть true, тоxprime это:
tuple_cat( tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()), std::move(x))
В противном случае, еслиuses_allocator_v<T1, inner_allocator_type> есть true и is_constructible_v<T1, Args1..., inner_allocator_type&> естьtrue, тоxprime это:
tuple_cat(std::move(x), tuple<inner_allocator_type&>(inner_allocator()))
В противном случае программа имеет неверный формат.
и строитtuple объектyprime изy следующих правил:
Еслиuses_allocator_v<T2, inner_allocator_type> естьfalse и
is_constructible_v<T2,
Args2...> естьtrue, значит,yprime естьy.
В противном случае, еслиuses_allocator_v<T2, inner_allocator_type> естьtrue и is_constructible_v<T2, allocator_arg_t, inner_allocator_type&, Args2...> есть true, тоyprime это:
tuple_cat( tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()), std::move(y))
В противном случае, еслиuses_allocator_v<T2, inner_allocator_type> есть true и is_constructible_v<T2, Args2..., inner_allocator_type&> естьtrue, тоyprime это:
tuple_cat(std::move(y), tuple<inner_allocator_type&>(inner_allocator()))
В противном случае программа имеет неверный формат.
затем звонит:
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);
template <class T1, class T2, class U, class V>
void construct(pair<T1, T2>* p, U&& x, V&& y);
Effects: Эквивалентен:
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: Эквивалентен:
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: Эквивалентен:
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);
scoped_allocator_adaptor select_on_container_copy_construction() const;
template <class OuterA1, class OuterA2, class... InnerAllocs>
bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Returns: Еслиsizeof...(InnerAllocs) равно нулю,
a.outer_allocator() == b.outer_allocator()
иначе
a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_allocator()
template <class OuterA1, class OuterA2, class... InnerAllocs>
bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;