Init
This commit is contained in:
380
cppdraft/allocator/adaptor.md
Normal file
380
cppdraft/allocator/adaptor.md
Normal file
@@ -0,0 +1,380 @@
|
||||
[allocator.adaptor]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.6 Class template scoped_allocator_adaptor [allocator.adaptor]
|
||||
|
||||
### [20.6.1](#syn) Header <scoped_allocator> synopsis [[allocator.adaptor.syn]](allocator.adaptor.syn)
|
||||
|
||||
[ð](#header:%3cscoped_allocator%3e)
|
||||
|
||||
namespace std {// class template scoped_allocator_adaptortemplate<class OuterAlloc, class... InnerAlloc>class scoped_allocator_adaptor; // [[scoped.adaptor.operators]](#scoped.adaptor.operators "20.6.5 Operators"), scoped allocator operatorstemplate<class OuterA1, class OuterA2, class... InnerAllocs>bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;}
|
||||
|
||||
[1](#syn-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8608)
|
||||
|
||||
The class template scoped_allocator_adaptor is an allocator template that
|
||||
specifies an allocator resource (the outer allocator) to be used by a container (as any
|
||||
other allocator does) and also specifies an inner allocator resource to be passed to the
|
||||
constructor of every element within the container[.](#syn-1.sentence-1)
|
||||
|
||||
This adaptor is instantiated with one
|
||||
outer and zero or more inner allocator types[.](#syn-1.sentence-2)
|
||||
|
||||
If instantiated with only one allocator
|
||||
type, the inner allocator becomes the scoped_allocator_adaptor itself, thus
|
||||
using the same allocator resource for the container and every element within the
|
||||
container and, if the elements themselves are containers, each of their elements
|
||||
recursively[.](#syn-1.sentence-3)
|
||||
|
||||
If instantiated with more than one allocator, the first allocator is the
|
||||
outer allocator for use by the container, the second allocator is passed to the
|
||||
constructors of the container's elements, and, if the elements themselves are
|
||||
containers, the third allocator is passed to the elements' elements, and so on[.](#syn-1.sentence-4)
|
||||
|
||||
If
|
||||
containers are nested to a depth greater than the number of allocators, the last
|
||||
allocator is used repeatedly, as in the single-allocator case, for any remaining
|
||||
recursions[.](#syn-1.sentence-5)
|
||||
|
||||
[*Note [1](#syn-note-1)*:
|
||||
|
||||
The scoped_allocator_adaptor is derived from the outer
|
||||
allocator type so it can be substituted for the outer allocator type in most
|
||||
expressions[.](#syn-1.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor)
|
||||
|
||||
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 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...>;}
|
||||
|
||||
### [20.6.2](#types) Member types [[allocator.adaptor.types]](allocator.adaptor.types)
|
||||
|
||||
[ð](#lib:inner_allocator_type,scoped_allocator_adaptor)
|
||||
|
||||
`using inner_allocator_type = see below;
|
||||
`
|
||||
|
||||
[1](#types-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8722)
|
||||
|
||||
*Type*: scoped_allocator_adaptor<OuterAlloc> if sizeof...(InnerAllocs) is
|
||||
zero; otherwise,
|
||||
|
||||
scoped_allocator_adaptor<InnerAllocs...>[.](#types-1.sentence-2)
|
||||
|
||||
[ð](#lib:propagate_on_container_copy_assignment,scoped_allocator_adaptor)
|
||||
|
||||
`using propagate_on_container_copy_assignment = see below;
|
||||
`
|
||||
|
||||
[2](#types-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8733)
|
||||
|
||||
*Type*: true_type ifallocator_traits<A>::propagate_on_container_copy_assignment::value istrue for any A in the set of OuterAlloc andInnerAllocs...; otherwise, false_type[.](#types-2.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_move_assignment,scoped_allocator_adaptor)
|
||||
|
||||
`using propagate_on_container_move_assignment = see below;
|
||||
`
|
||||
|
||||
[3](#types-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8746)
|
||||
|
||||
*Type*: true_type ifallocator_traits<A>::propagate_on_container_move_assignment::value istrue for any A in the set of OuterAlloc andInnerAllocs...; otherwise, false_type[.](#types-3.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_swap,scoped_allocator_adaptor)
|
||||
|
||||
`using propagate_on_container_swap = see below;
|
||||
`
|
||||
|
||||
[4](#types-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8759)
|
||||
|
||||
*Type*: true_type ifallocator_traits<A>::propagate_on_container_swap::value istrue for any A in the set of OuterAlloc andInnerAllocs...; otherwise, false_type[.](#types-4.sentence-1)
|
||||
|
||||
[ð](#lib:is_always_equal,scoped_allocator_adaptor)
|
||||
|
||||
`using is_always_equal = see below;
|
||||
`
|
||||
|
||||
[5](#types-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8772)
|
||||
|
||||
*Type*: true_type ifallocator_traits<A>::is_always_equal::value istrue for every A in the set of OuterAlloc andInnerAllocs...; otherwise, false_type[.](#types-5.sentence-1)
|
||||
|
||||
### [20.6.3](#cnstr) Constructors [[allocator.adaptor.cnstr]](allocator.adaptor.cnstr)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor)
|
||||
|
||||
`scoped_allocator_adaptor();
|
||||
`
|
||||
|
||||
[1](#cnstr-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8787)
|
||||
|
||||
*Effects*: Value-initializes the OuterAlloc base class and the inner allocator
|
||||
object[.](#cnstr-1.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor_)
|
||||
|
||||
`template<class OuterA2>
|
||||
scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept;
|
||||
`
|
||||
|
||||
[2](#cnstr-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8800)
|
||||
|
||||
*Constraints*: is_constructible_v<OuterAlloc, OuterA2> is true[.](#cnstr-2.sentence-1)
|
||||
|
||||
[3](#cnstr-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8804)
|
||||
|
||||
*Effects*: Initializes the OuterAlloc base class withstd::forward<OuterA2>(outerAlloc) and inner with innerAllocs... (hence recursively initializing each allocator within the adaptor with the corresponding
|
||||
allocator from the argument list)[.](#cnstr-3.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor__)
|
||||
|
||||
`scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
|
||||
`
|
||||
|
||||
[4](#cnstr-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8818)
|
||||
|
||||
*Effects*: Initializes each allocator within the adaptor with the corresponding allocator
|
||||
from other[.](#cnstr-4.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor___)
|
||||
|
||||
`scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
|
||||
`
|
||||
|
||||
[5](#cnstr-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8830)
|
||||
|
||||
*Effects*: Move constructs each allocator within the adaptor with the corresponding allocator
|
||||
from other[.](#cnstr-5.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor____)
|
||||
|
||||
`template<class OuterA2>
|
||||
scoped_allocator_adaptor(
|
||||
const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#cnstr-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8844)
|
||||
|
||||
*Constraints*: is_constructible_v<OuterAlloc, const OuterA2&> is true[.](#cnstr-6.sentence-1)
|
||||
|
||||
[7](#cnstr-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8848)
|
||||
|
||||
*Effects*: Initializes each allocator within the adaptor with the corresponding allocator
|
||||
from other[.](#cnstr-7.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor_____)
|
||||
|
||||
`template<class OuterA2>
|
||||
scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
|
||||
`
|
||||
|
||||
[8](#cnstr-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8861)
|
||||
|
||||
*Constraints*: is_constructible_v<OuterAlloc, OuterA2> is true[.](#cnstr-8.sentence-1)
|
||||
|
||||
[9](#cnstr-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8865)
|
||||
|
||||
*Effects*: Initializes each allocator within the adaptor with the corresponding allocator rvalue
|
||||
from other[.](#cnstr-9.sentence-1)
|
||||
|
||||
### [20.6.4](#members) Members [[allocator.adaptor.members]](allocator.adaptor.members)
|
||||
|
||||
[1](#members-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8873)
|
||||
|
||||
In the construct member functions,*OUTERMOST*(x) is*OUTERMOST*(x.outer_allocator()) if
|
||||
the expression x.outer_allocator() is
|
||||
valid ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")) andx otherwise;*OUTERMOST_ALLOC_TRAITS*(x) isallocator_traits<remove_reference_t<decltype(*OUTERMOST*(x))>>[.](#members-1.sentence-1)
|
||||
|
||||
[*Note [1](#members-note-1)*:
|
||||
|
||||
*OUTERMOST*(x) and*OUTERMOST_ALLOC_TRAITS*(x) are recursive operations[.](#members-1.sentence-2)
|
||||
|
||||
It
|
||||
is incumbent upon the definition of outer_allocator() to ensure that the
|
||||
recursion terminates[.](#members-1.sentence-3)
|
||||
|
||||
It will terminate for all instantiations ofscoped_allocator_adaptor[.](#members-1.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:inner_allocator,scoped_allocator_adaptor)
|
||||
|
||||
`inner_allocator_type& inner_allocator() noexcept;
|
||||
const inner_allocator_type& inner_allocator() const noexcept;
|
||||
`
|
||||
|
||||
[2](#members-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8897)
|
||||
|
||||
*Returns*: *this if sizeof...(InnerAllocs) is zero; otherwise,inner[.](#members-2.sentence-1)
|
||||
|
||||
[ð](#lib:outer_allocator,scoped_allocator_adaptor)
|
||||
|
||||
`outer_allocator_type& outer_allocator() noexcept;
|
||||
`
|
||||
|
||||
[3](#members-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8909)
|
||||
|
||||
*Returns*: static_cast<OuterAlloc&>(*this)[.](#members-3.sentence-1)
|
||||
|
||||
[ð](#lib:outer_allocator,scoped_allocator_adaptor_)
|
||||
|
||||
`const outer_allocator_type& outer_allocator() const noexcept;
|
||||
`
|
||||
|
||||
[4](#members-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8920)
|
||||
|
||||
*Returns*: static_cast<const OuterAlloc&>(*this)[.](#members-4.sentence-1)
|
||||
|
||||
[ð](#lib:allocate,scoped_allocator_adaptor)
|
||||
|
||||
`pointer allocate(size_type n);
|
||||
`
|
||||
|
||||
[5](#members-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8931)
|
||||
|
||||
*Returns*: allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)[.](#members-5.sentence-1)
|
||||
|
||||
[ð](#lib:allocate,scoped_allocator_adaptor_)
|
||||
|
||||
`pointer allocate(size_type n, const_void_pointer hint);
|
||||
`
|
||||
|
||||
[6](#members-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8942)
|
||||
|
||||
*Returns*: allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)[.](#members-6.sentence-1)
|
||||
|
||||
[ð](#lib:deallocate,scoped_allocator_adaptor)
|
||||
|
||||
`void deallocate(pointer p, size_type n) noexcept;
|
||||
`
|
||||
|
||||
[7](#members-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8953)
|
||||
|
||||
*Effects*: As if by:allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n);
|
||||
|
||||
[ð](#lib:max_size,scoped_allocator_adaptor)
|
||||
|
||||
`size_type max_size() const;
|
||||
`
|
||||
|
||||
[8](#members-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8965)
|
||||
|
||||
*Returns*: allocator_traits<OuterAlloc>::max_size(outer_allocator())[.](#members-8.sentence-1)
|
||||
|
||||
[ð](#lib:construct,scoped_allocator_adaptor)
|
||||
|
||||
`template<class T, class... Args>
|
||||
void construct(T* p, Args&&... args);
|
||||
`
|
||||
|
||||
[9](#members-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8977)
|
||||
|
||||
*Effects*: Equivalent to:apply([p, this](auto&&... newargs) {*OUTERMOST_ALLOC_TRAITS*(*this)::construct(*OUTERMOST*(*this), p,
|
||||
std::forward<decltype(newargs)>(newargs)...); },
|
||||
uses_allocator_construction_args<T>(inner_allocator(),
|
||||
std::forward<Args>(args)...));
|
||||
|
||||
[ð](#lib:destroy,scoped_allocator_adaptor)
|
||||
|
||||
`template<class T>
|
||||
void destroy(T* p);
|
||||
`
|
||||
|
||||
[10](#members-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8998)
|
||||
|
||||
*Effects*: Calls *OUTERMOST_ALLOC_TRAITS*(*this)::destroy(*OUTERMOST*(*this), p)[.](#members-10.sentence-1)
|
||||
|
||||
[ð](#lib:select_on_container_copy_construction,scoped_allocator_adaptor)
|
||||
|
||||
`scoped_allocator_adaptor select_on_container_copy_construction() const;
|
||||
`
|
||||
|
||||
[11](#members-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L9009)
|
||||
|
||||
*Returns*: A new scoped_allocator_adaptor object
|
||||
where each allocator a1 within the adaptor
|
||||
is initialized withallocator_traits<A1>::select_on_container_copy_construction(a2),
|
||||
where A1 is the type of a1 anda2 is the corresponding allocator in *this[.](#members-11.sentence-1)
|
||||
|
||||
### [20.6.5](#scoped.adaptor.operators) Operators [[scoped.adaptor.operators]](scoped.adaptor.operators)
|
||||
|
||||
[ð](#lib:operator==,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;
|
||||
`
|
||||
|
||||
[1](#scoped.adaptor.operators-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L9029)
|
||||
|
||||
*Returns*: If sizeof...(InnerAllocs) is zero,a.outer_allocator() == b.outer_allocator() otherwisea.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_allocator()
|
||||
Reference in New Issue
Block a user