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()
|
||||
101
cppdraft/allocator/adaptor/cnstr.md
Normal file
101
cppdraft/allocator/adaptor/cnstr.md
Normal file
@@ -0,0 +1,101 @@
|
||||
[allocator.adaptor.cnstr]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.6 Class template scoped_allocator_adaptor [[allocator.adaptor]](allocator.adaptor#cnstr)
|
||||
|
||||
### 20.6.3 Constructors [allocator.adaptor.cnstr]
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor)
|
||||
|
||||
`scoped_allocator_adaptor();
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8787)
|
||||
|
||||
*Effects*: Value-initializes the OuterAlloc base class and the inner allocator
|
||||
object[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor_)
|
||||
|
||||
`template<class OuterA2>
|
||||
scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8800)
|
||||
|
||||
*Constraints*: is_constructible_v<OuterAlloc, OuterA2> is true[.](#2.sentence-1)
|
||||
|
||||
[3](#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)[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor__)
|
||||
|
||||
`scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
|
||||
`
|
||||
|
||||
[4](#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[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor___)
|
||||
|
||||
`scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
|
||||
`
|
||||
|
||||
[5](#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[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor____)
|
||||
|
||||
`template<class OuterA2>
|
||||
scoped_allocator_adaptor(
|
||||
const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8844)
|
||||
|
||||
*Constraints*: is_constructible_v<OuterAlloc, const OuterA2&> is true[.](#6.sentence-1)
|
||||
|
||||
[7](#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[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:scoped_allocator_adaptor,constructor_____)
|
||||
|
||||
`template<class OuterA2>
|
||||
scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8861)
|
||||
|
||||
*Constraints*: is_constructible_v<OuterAlloc, OuterA2> is true[.](#8.sentence-1)
|
||||
|
||||
[9](#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[.](#9.sentence-1)
|
||||
146
cppdraft/allocator/adaptor/members.md
Normal file
146
cppdraft/allocator/adaptor/members.md
Normal file
@@ -0,0 +1,146 @@
|
||||
[allocator.adaptor.members]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.6 Class template scoped_allocator_adaptor [[allocator.adaptor]](allocator.adaptor#members)
|
||||
|
||||
### 20.6.4 Members [allocator.adaptor.members]
|
||||
|
||||
[1](#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))>>[.](#1.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
*OUTERMOST*(x) and*OUTERMOST_ALLOC_TRAITS*(x) are recursive operations[.](#1.sentence-2)
|
||||
|
||||
It
|
||||
is incumbent upon the definition of outer_allocator() to ensure that the
|
||||
recursion terminates[.](#1.sentence-3)
|
||||
|
||||
It will terminate for all instantiations ofscoped_allocator_adaptor[.](#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](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8897)
|
||||
|
||||
*Returns*: *this if sizeof...(InnerAllocs) is zero; otherwise,inner[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:outer_allocator,scoped_allocator_adaptor)
|
||||
|
||||
`outer_allocator_type& outer_allocator() noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8909)
|
||||
|
||||
*Returns*: static_cast<OuterAlloc&>(*this)[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:outer_allocator,scoped_allocator_adaptor_)
|
||||
|
||||
`const outer_allocator_type& outer_allocator() const noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8920)
|
||||
|
||||
*Returns*: static_cast<const OuterAlloc&>(*this)[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:allocate,scoped_allocator_adaptor)
|
||||
|
||||
`pointer allocate(size_type n);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8931)
|
||||
|
||||
*Returns*: allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:allocate,scoped_allocator_adaptor_)
|
||||
|
||||
`pointer allocate(size_type n, const_void_pointer hint);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8942)
|
||||
|
||||
*Returns*: allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:deallocate,scoped_allocator_adaptor)
|
||||
|
||||
`void deallocate(pointer p, size_type n) noexcept;
|
||||
`
|
||||
|
||||
[7](#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](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8965)
|
||||
|
||||
*Returns*: allocator_traits<OuterAlloc>::max_size(outer_allocator())[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:construct,scoped_allocator_adaptor)
|
||||
|
||||
`template<class T, class... Args>
|
||||
void construct(T* p, Args&&... args);
|
||||
`
|
||||
|
||||
[9](#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](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8998)
|
||||
|
||||
*Effects*: Calls *OUTERMOST_ALLOC_TRAITS*(*this)::destroy(*OUTERMOST*(*this), p)[.](#10.sentence-1)
|
||||
|
||||
[ð](#lib:select_on_container_copy_construction,scoped_allocator_adaptor)
|
||||
|
||||
`scoped_allocator_adaptor select_on_container_copy_construction() const;
|
||||
`
|
||||
|
||||
[11](#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[.](#11.sentence-1)
|
||||
68
cppdraft/allocator/adaptor/syn.md
Normal file
68
cppdraft/allocator/adaptor/syn.md
Normal file
@@ -0,0 +1,68 @@
|
||||
[allocator.adaptor.syn]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.6 Class template scoped_allocator_adaptor [[allocator.adaptor]](allocator.adaptor#syn)
|
||||
|
||||
### 20.6.1 Header <scoped_allocator> synopsis [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](#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[.](#1.sentence-1)
|
||||
|
||||
This adaptor is instantiated with one
|
||||
outer and zero or more inner allocator types[.](#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[.](#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[.](#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[.](#1.sentence-5)
|
||||
|
||||
[*Note [1](#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[.](#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...>;}
|
||||
65
cppdraft/allocator/adaptor/types.md
Normal file
65
cppdraft/allocator/adaptor/types.md
Normal file
@@ -0,0 +1,65 @@
|
||||
[allocator.adaptor.types]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.6 Class template scoped_allocator_adaptor [[allocator.adaptor]](allocator.adaptor#types)
|
||||
|
||||
### 20.6.2 Member types [allocator.adaptor.types]
|
||||
|
||||
[ð](#lib:inner_allocator_type,scoped_allocator_adaptor)
|
||||
|
||||
`using inner_allocator_type = see below;
|
||||
`
|
||||
|
||||
[1](#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...>[.](#1.sentence-2)
|
||||
|
||||
[ð](#lib:propagate_on_container_copy_assignment,scoped_allocator_adaptor)
|
||||
|
||||
`using propagate_on_container_copy_assignment = see below;
|
||||
`
|
||||
|
||||
[2](#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[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_move_assignment,scoped_allocator_adaptor)
|
||||
|
||||
`using propagate_on_container_move_assignment = see below;
|
||||
`
|
||||
|
||||
[3](#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[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_swap,scoped_allocator_adaptor)
|
||||
|
||||
`using propagate_on_container_swap = see below;
|
||||
`
|
||||
|
||||
[4](#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[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:is_always_equal,scoped_allocator_adaptor)
|
||||
|
||||
`using is_always_equal = see below;
|
||||
`
|
||||
|
||||
[5](#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[.](#5.sentence-1)
|
||||
21
cppdraft/allocator/globals.md
Normal file
21
cppdraft/allocator/globals.md
Normal file
@@ -0,0 +1,21 @@
|
||||
[allocator.globals]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.globals)
|
||||
|
||||
### 20.2.10 The default allocator [[default.allocator]](default.allocator#allocator.globals)
|
||||
|
||||
#### 20.2.10.3 Operators [allocator.globals]
|
||||
|
||||
[ð](#lib:operator==,allocator)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2104)
|
||||
|
||||
*Returns*: true[.](#1.sentence-1)
|
||||
129
cppdraft/allocator/members.md
Normal file
129
cppdraft/allocator/members.md
Normal file
@@ -0,0 +1,129 @@
|
||||
[allocator.members]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.members)
|
||||
|
||||
### 20.2.10 The default allocator [[default.allocator]](default.allocator#allocator.members)
|
||||
|
||||
#### 20.2.10.2 Members [allocator.members]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1994)
|
||||
|
||||
Except for the destructor, member functions of the default allocator shall not introduce
|
||||
data races ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")) as a result of concurrent calls to those member
|
||||
functions from different threads[.](#1.sentence-1)
|
||||
|
||||
Calls to these functions that allocate or deallocate a
|
||||
particular unit of storage shall occur in a single total order, and each such
|
||||
deallocation call shall happen before the next allocation (if any) in this order[.](#1.sentence-2)
|
||||
|
||||
[ð](#lib:allocate,allocator)
|
||||
|
||||
`constexpr T* allocate(size_t n);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2007)
|
||||
|
||||
*Mandates*: T is not an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1 General"))[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2011)
|
||||
|
||||
*Returns*: A pointer to the initial element of an array of n T[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2015)
|
||||
|
||||
*Throws*: bad_array_new_length ifnumeric_limits<size_t>::max() / sizeof(T) < n, orbad_alloc if the storage cannot be obtained[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2021)
|
||||
|
||||
*Remarks*: The storage for the array
|
||||
is obtained by calling ::operator new ([[new.delete]](new.delete "17.6.3 Storage allocation and deallocation")),
|
||||
but it is unspecified when or how often this
|
||||
function is called[.](#5.sentence-1)
|
||||
|
||||
This function starts the lifetime of the array object,
|
||||
but not that of any of the array elements[.](#5.sentence-2)
|
||||
|
||||
[ð](#lib:allocate_at_least,allocator)
|
||||
|
||||
`constexpr allocation_result<T*> allocate_at_least(size_t n);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2037)
|
||||
|
||||
*Mandates*: T is not an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1 General"))[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2041)
|
||||
|
||||
*Returns*: allocation_result<T*>{ptr, count},
|
||||
where ptr is a pointer to
|
||||
the initial element of an array of count T andcount ⥠n[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2048)
|
||||
|
||||
*Throws*: bad_array_new_length if numeric_limits<size_t>::max() / sizeof(T) < n,
|
||||
or bad_alloc if the storage cannot be obtained[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2054)
|
||||
|
||||
*Remarks*: The storage for the array is obtained by calling ::operator new,
|
||||
but it is unspecified when or how often this function is called[.](#9.sentence-1)
|
||||
|
||||
This function starts the lifetime of the array object,
|
||||
but not that of any of the array elements[.](#9.sentence-2)
|
||||
|
||||
[ð](#lib:deallocate,allocator)
|
||||
|
||||
`constexpr void deallocate(T* p, size_t n);
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2068)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
If p is memory that was obtained by a call to allocate_at_least,
|
||||
let ret be the value returned andreq be the value passed as the first argument to that call[.](#10.1.sentence-1)
|
||||
p is equal to ret.ptr andn is a value such that req ⤠n ⤠ret.count[.](#10.1.sentence-2)
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
Otherwise, p is a pointer value obtained from allocate[.](#10.2.sentence-1)
|
||||
n equals the value passed as the first argument
|
||||
to the invocation of allocate which returned p[.](#10.2.sentence-2)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2083)
|
||||
|
||||
*Effects*: Deallocates the storage referenced by p[.](#11.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2087)
|
||||
|
||||
*Remarks*: Uses::operator delete ([[new.delete]](new.delete "17.6.3 Storage allocation and deallocation")),
|
||||
but it is unspecified
|
||||
when this function is called[.](#12.sentence-1)
|
||||
1029
cppdraft/allocator/requirements.md
Normal file
1029
cppdraft/allocator/requirements.md
Normal file
File diff suppressed because it is too large
Load Diff
26
cppdraft/allocator/requirements/completeness.md
Normal file
26
cppdraft/allocator/requirements/completeness.md
Normal file
@@ -0,0 +1,26 @@
|
||||
[allocator.requirements.completeness]
|
||||
|
||||
# 16 Library introduction [[library]](./#library)
|
||||
|
||||
## 16.4 Library-wide requirements [[requirements]](requirements#allocator.requirements.completeness)
|
||||
|
||||
### 16.4.4 Requirements on types and expressions [[utility.requirements]](utility.requirements#allocator.requirements.completeness)
|
||||
|
||||
#### 16.4.4.6 *Cpp17Allocator* requirements [[allocator.requirements]](allocator.requirements#completeness)
|
||||
|
||||
#### 16.4.4.6.2 Allocator completeness requirements [allocator.requirements.completeness]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2964)
|
||||
|
||||
If X is an allocator class for type T,X additionally meets the allocator completeness requirements if,
|
||||
whether or not T is a complete type:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
X is a complete type, and
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
all the member types of [allocator_traits<X>](allocator.traits "20.2.9 Allocator traits [allocator.traits]") other than value_type are complete types[.](#1.sentence-1)
|
||||
1012
cppdraft/allocator/requirements/general.md
Normal file
1012
cppdraft/allocator/requirements/general.md
Normal file
File diff suppressed because it is too large
Load Diff
25
cppdraft/allocator/tag.md
Normal file
25
cppdraft/allocator/tag.md
Normal file
@@ -0,0 +1,25 @@
|
||||
[allocator.tag]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.tag)
|
||||
|
||||
### 20.2.7 Allocator argument tag [allocator.tag]
|
||||
|
||||
[ð](#lib:allocator_arg_t)
|
||||
|
||||
`namespace std {
|
||||
struct allocator_arg_t { explicit allocator_arg_t() = default; };
|
||||
inline constexpr allocator_arg_t allocator_arg{};
|
||||
}
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1271)
|
||||
|
||||
The allocator_arg_t struct is an empty class type used as a unique type to
|
||||
disambiguate constructor and function overloading[.](#1.sentence-1)
|
||||
|
||||
Specifically, several types (seetuple [[tuple]](tuple "22.4 Tuples")) have constructors with allocator_arg_t as the first
|
||||
argument, immediately followed by an argument of a type that meets the[*Cpp17Allocator*](allocator.requirements.general#:Cpp17Allocator "16.4.4.6.1 General [allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#1.sentence-2)
|
||||
292
cppdraft/allocator/traits.md
Normal file
292
cppdraft/allocator/traits.md
Normal file
@@ -0,0 +1,292 @@
|
||||
[allocator.traits]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.traits)
|
||||
|
||||
### 20.2.9 Allocator traits [allocator.traits]
|
||||
|
||||
#### [20.2.9.1](#general) General [[allocator.traits.general]](allocator.traits.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1640)
|
||||
|
||||
The class template allocator_traits supplies a uniform interface to all
|
||||
allocator types[.](#general-1.sentence-1)
|
||||
|
||||
An allocator cannot be a non-class type, however, even if allocator_traits supplies the entire required interface[.](#general-1.sentence-2)
|
||||
|
||||
[*Note [1](#general-note-1)*:
|
||||
|
||||
Thus, it is always possible to create
|
||||
a derived class from an allocator[.](#general-1.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
If a program declares
|
||||
an explicit or partial specialization of allocator_traits,
|
||||
the program is ill-formed, no diagnostic required[.](#general-1.sentence-4)
|
||||
|
||||
[ð](#lib:allocator_traits)
|
||||
|
||||
namespace std {template<class Alloc> struct allocator_traits {using allocator_type = Alloc; using value_type = typename Alloc::value_type; using pointer = *see below*; using const_pointer = *see below*; using void_pointer = *see below*; using const_void_pointer = *see below*; using difference_type = *see below*; using size_type = *see below*; 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 T> using rebind_alloc = *see below*; template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>; static constexpr pointer allocate(Alloc& a, size_type n); static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); static constexpr allocation_result<pointer, size_type> allocate_at_least(Alloc& a, size_type n); static constexpr void deallocate(Alloc& a, pointer p, size_type n); template<class T, class... Args>static constexpr void construct(Alloc& a, T* p, Args&&... args); template<class T>static constexpr void destroy(Alloc& a, T* p); static constexpr size_type max_size(const Alloc& a) noexcept; static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs); };}
|
||||
|
||||
#### [20.2.9.2](#types) Member types [[allocator.traits.types]](allocator.traits.types)
|
||||
|
||||
[ð](#lib:pointer,allocator_traits)
|
||||
|
||||
`using pointer = see below;
|
||||
`
|
||||
|
||||
[1](#types-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1705)
|
||||
|
||||
*Type*: Alloc::pointer if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::pointer is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise, value_type*[.](#types-1.sentence-1)
|
||||
|
||||
[ð](#lib:const_pointer,allocator_traits)
|
||||
|
||||
`using const_pointer = see below;
|
||||
`
|
||||
|
||||
[2](#types-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1717)
|
||||
|
||||
*Type*: Alloc::const_pointer if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::const_pointer is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<const value_type>[.](#types-2.sentence-1)
|
||||
|
||||
[ð](#lib:void_pointer,allocator_traits)
|
||||
|
||||
`using void_pointer = see below;
|
||||
`
|
||||
|
||||
[3](#types-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1730)
|
||||
|
||||
*Type*: Alloc::void_pointer if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::void_pointer is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<void>[.](#types-3.sentence-1)
|
||||
|
||||
[ð](#lib:const_void_pointer,allocator_traits)
|
||||
|
||||
`using const_void_pointer = see below;
|
||||
`
|
||||
|
||||
[4](#types-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1743)
|
||||
|
||||
*Type*: Alloc::const_void_pointer if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::const_void_pointer is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<const void>[.](#types-4.sentence-1)
|
||||
|
||||
[ð](#lib:difference_type,allocator_traits)
|
||||
|
||||
`using difference_type = see below;
|
||||
`
|
||||
|
||||
[5](#types-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1756)
|
||||
|
||||
*Type*: Alloc::difference_type if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::difference_type is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::difference_type[.](#types-5.sentence-1)
|
||||
|
||||
[ð](#lib:size_type,allocator_traits)
|
||||
|
||||
`using size_type = see below;
|
||||
`
|
||||
|
||||
[6](#types-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1769)
|
||||
|
||||
*Type*: Alloc::size_type if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::size_type is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,make_unsigned_t<difference_type>[.](#types-6.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_copy_assignment,allocator_traits)
|
||||
|
||||
`using propagate_on_container_copy_assignment = see below;
|
||||
`
|
||||
|
||||
[7](#types-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1782)
|
||||
|
||||
*Type*: Alloc::propagate_on_container_copy_assignment if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_copy_assignment is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#types-7.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_move_assignment,allocator_traits)
|
||||
|
||||
`using propagate_on_container_move_assignment = see below;
|
||||
`
|
||||
|
||||
[8](#types-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1795)
|
||||
|
||||
*Type*: Alloc::propagate_on_container_move_assignment if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_move_assignment is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#types-8.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_swap,allocator_traits)
|
||||
|
||||
`using propagate_on_container_swap = see below;
|
||||
`
|
||||
|
||||
[9](#types-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1808)
|
||||
|
||||
*Type*: Alloc::propagate_on_container_swap if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_swap is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#types-9.sentence-1)
|
||||
|
||||
[ð](#lib:is_always_equal,allocator_traits)
|
||||
|
||||
`using is_always_equal = see below;
|
||||
`
|
||||
|
||||
[10](#types-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1821)
|
||||
|
||||
*Type*: Alloc::is_always_equal if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::is_always_equal is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction"));
|
||||
otherwise is_empty<Alloc>::type[.](#types-10.sentence-1)
|
||||
|
||||
[ð](#lib:rebind_alloc,allocator_traits)
|
||||
|
||||
`template<class T> using rebind_alloc = see below;
|
||||
`
|
||||
|
||||
[11](#types-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1834)
|
||||
|
||||
*Alias template*: Alloc::rebind<T>::other if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::rebind<T>::other is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,Alloc<T, Args> if Alloc is a class template instantiation
|
||||
of the form Alloc<U, Args>, where Args is zero or more type arguments;
|
||||
otherwise, the instantiation of rebind_alloc is ill-formed[.](#types-11.sentence-1)
|
||||
|
||||
#### [20.2.9.3](#members) Static member functions [[allocator.traits.members]](allocator.traits.members)
|
||||
|
||||
[ð](#lib:allocate,allocator_traits)
|
||||
|
||||
`static constexpr pointer allocate(Alloc& a, size_type n);
|
||||
`
|
||||
|
||||
[1](#members-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1851)
|
||||
|
||||
*Returns*: a.allocate(n)[.](#members-1.sentence-1)
|
||||
|
||||
[ð](#lib:allocate,allocator_traits_)
|
||||
|
||||
`static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
|
||||
`
|
||||
|
||||
[2](#members-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1862)
|
||||
|
||||
*Returns*: a.allocate(n, hint) if that expression is well-formed; otherwise, a.allocate(n)[.](#members-2.sentence-1)
|
||||
|
||||
[ð](#lib:allocate_at_least,allocator_traits)
|
||||
|
||||
`static constexpr allocation_result<pointer, size_type> allocate_at_least(Alloc& a, size_type n);
|
||||
`
|
||||
|
||||
[3](#members-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1873)
|
||||
|
||||
*Returns*: a.allocate_at_least(n) if that expression is well-formed;
|
||||
otherwise, {a.allocate(n), n}[.](#members-3.sentence-1)
|
||||
|
||||
[ð](#lib:deallocate,allocator_traits)
|
||||
|
||||
`static constexpr void deallocate(Alloc& a, pointer p, size_type n);
|
||||
`
|
||||
|
||||
[4](#members-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1885)
|
||||
|
||||
*Effects*: Calls a.deallocate(p, n)[.](#members-4.sentence-1)
|
||||
|
||||
[5](#members-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1889)
|
||||
|
||||
*Throws*: Nothing[.](#members-5.sentence-1)
|
||||
|
||||
[ð](#lib:construct,allocator_traits)
|
||||
|
||||
`template<class T, class... Args>
|
||||
static constexpr void construct(Alloc& a, T* p, Args&&... args);
|
||||
`
|
||||
|
||||
[6](#members-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1901)
|
||||
|
||||
*Effects*: Calls a.construct(p, std::forward<Args>(args)...) if that call is well-formed;
|
||||
otherwise, invokes construct_at(p, std::forward<Args>(args)...)[.](#members-6.sentence-1)
|
||||
|
||||
[ð](#lib:destroy,allocator_traits)
|
||||
|
||||
`template<class T>
|
||||
static constexpr void destroy(Alloc& a, T* p);
|
||||
`
|
||||
|
||||
[7](#members-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1915)
|
||||
|
||||
*Effects*: Calls a.destroy(p) if that call is well-formed; otherwise, invokesdestroy_at(p)[.](#members-7.sentence-1)
|
||||
|
||||
[ð](#lib:max_size,allocator_traits)
|
||||
|
||||
`static constexpr size_type max_size(const Alloc& a) noexcept;
|
||||
`
|
||||
|
||||
[8](#members-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1927)
|
||||
|
||||
*Returns*: a.max_size() if that expression is well-formed; otherwise,numeric_limits<size_type>::max() / sizeof(value_type)[.](#members-8.sentence-1)
|
||||
|
||||
[ð](#lib:select_on_container_copy_construction,allocator_traits)
|
||||
|
||||
`static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs);
|
||||
`
|
||||
|
||||
[9](#members-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1939)
|
||||
|
||||
*Returns*: rhs.select_on_container_copy_construction() if that expression is
|
||||
well-formed; otherwise, rhs[.](#members-9.sentence-1)
|
||||
|
||||
#### [20.2.9.4](#other) Other [[allocator.traits.other]](allocator.traits.other)
|
||||
|
||||
[1](#other-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1947)
|
||||
|
||||
The class template allocation_result has
|
||||
the template parameters, data members, and special members specified above[.](#other-1.sentence-1)
|
||||
|
||||
It has no base classes or members other than those specified[.](#other-1.sentence-2)
|
||||
33
cppdraft/allocator/traits/general.md
Normal file
33
cppdraft/allocator/traits/general.md
Normal file
@@ -0,0 +1,33 @@
|
||||
[allocator.traits.general]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.traits.general)
|
||||
|
||||
### 20.2.9 Allocator traits [[allocator.traits]](allocator.traits#general)
|
||||
|
||||
#### 20.2.9.1 General [allocator.traits.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1640)
|
||||
|
||||
The class template allocator_traits supplies a uniform interface to all
|
||||
allocator types[.](#1.sentence-1)
|
||||
|
||||
An allocator cannot be a non-class type, however, even if allocator_traits supplies the entire required interface[.](#1.sentence-2)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Thus, it is always possible to create
|
||||
a derived class from an allocator[.](#1.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
If a program declares
|
||||
an explicit or partial specialization of allocator_traits,
|
||||
the program is ill-formed, no diagnostic required[.](#1.sentence-4)
|
||||
|
||||
[ð](#lib:allocator_traits)
|
||||
|
||||
namespace std {template<class Alloc> struct allocator_traits {using allocator_type = Alloc; using value_type = typename Alloc::value_type; using pointer = *see below*; using const_pointer = *see below*; using void_pointer = *see below*; using const_void_pointer = *see below*; using difference_type = *see below*; using size_type = *see below*; 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 T> using rebind_alloc = *see below*; template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>; static constexpr pointer allocate(Alloc& a, size_type n); static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); static constexpr allocation_result<pointer, size_type> allocate_at_least(Alloc& a, size_type n); static constexpr void deallocate(Alloc& a, pointer p, size_type n); template<class T, class... Args>static constexpr void construct(Alloc& a, T* p, Args&&... args); template<class T>static constexpr void destroy(Alloc& a, T* p); static constexpr size_type max_size(const Alloc& a) noexcept; static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs); };}
|
||||
108
cppdraft/allocator/traits/members.md
Normal file
108
cppdraft/allocator/traits/members.md
Normal file
@@ -0,0 +1,108 @@
|
||||
[allocator.traits.members]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.traits.members)
|
||||
|
||||
### 20.2.9 Allocator traits [[allocator.traits]](allocator.traits#members)
|
||||
|
||||
#### 20.2.9.3 Static member functions [allocator.traits.members]
|
||||
|
||||
[ð](#lib:allocate,allocator_traits)
|
||||
|
||||
`static constexpr pointer allocate(Alloc& a, size_type n);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1851)
|
||||
|
||||
*Returns*: a.allocate(n)[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:allocate,allocator_traits_)
|
||||
|
||||
`static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1862)
|
||||
|
||||
*Returns*: a.allocate(n, hint) if that expression is well-formed; otherwise, a.allocate(n)[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:allocate_at_least,allocator_traits)
|
||||
|
||||
`static constexpr allocation_result<pointer, size_type> allocate_at_least(Alloc& a, size_type n);
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1873)
|
||||
|
||||
*Returns*: a.allocate_at_least(n) if that expression is well-formed;
|
||||
otherwise, {a.allocate(n), n}[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:deallocate,allocator_traits)
|
||||
|
||||
`static constexpr void deallocate(Alloc& a, pointer p, size_type n);
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1885)
|
||||
|
||||
*Effects*: Calls a.deallocate(p, n)[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1889)
|
||||
|
||||
*Throws*: Nothing[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:construct,allocator_traits)
|
||||
|
||||
`template<class T, class... Args>
|
||||
static constexpr void construct(Alloc& a, T* p, Args&&... args);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1901)
|
||||
|
||||
*Effects*: Calls a.construct(p, std::forward<Args>(args)...) if that call is well-formed;
|
||||
otherwise, invokes construct_at(p, std::forward<Args>(args)...)[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:destroy,allocator_traits)
|
||||
|
||||
`template<class T>
|
||||
static constexpr void destroy(Alloc& a, T* p);
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1915)
|
||||
|
||||
*Effects*: Calls a.destroy(p) if that call is well-formed; otherwise, invokesdestroy_at(p)[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:max_size,allocator_traits)
|
||||
|
||||
`static constexpr size_type max_size(const Alloc& a) noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1927)
|
||||
|
||||
*Returns*: a.max_size() if that expression is well-formed; otherwise,numeric_limits<size_type>::max() / sizeof(value_type)[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:select_on_container_copy_construction,allocator_traits)
|
||||
|
||||
`static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs);
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1939)
|
||||
|
||||
*Returns*: rhs.select_on_container_copy_construction() if that expression is
|
||||
well-formed; otherwise, rhs[.](#9.sentence-1)
|
||||
18
cppdraft/allocator/traits/other.md
Normal file
18
cppdraft/allocator/traits/other.md
Normal file
@@ -0,0 +1,18 @@
|
||||
[allocator.traits.other]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.traits.other)
|
||||
|
||||
### 20.2.9 Allocator traits [[allocator.traits]](allocator.traits#other)
|
||||
|
||||
#### 20.2.9.4 Other [allocator.traits.other]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1947)
|
||||
|
||||
The class template allocation_result has
|
||||
the template parameters, data members, and special members specified above[.](#1.sentence-1)
|
||||
|
||||
It has no base classes or members other than those specified[.](#1.sentence-2)
|
||||
154
cppdraft/allocator/traits/types.md
Normal file
154
cppdraft/allocator/traits/types.md
Normal file
@@ -0,0 +1,154 @@
|
||||
[allocator.traits.types]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.traits.types)
|
||||
|
||||
### 20.2.9 Allocator traits [[allocator.traits]](allocator.traits#types)
|
||||
|
||||
#### 20.2.9.2 Member types [allocator.traits.types]
|
||||
|
||||
[ð](#lib:pointer,allocator_traits)
|
||||
|
||||
`using pointer = see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1705)
|
||||
|
||||
*Type*: Alloc::pointer if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::pointer is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise, value_type*[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:const_pointer,allocator_traits)
|
||||
|
||||
`using const_pointer = see below;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1717)
|
||||
|
||||
*Type*: Alloc::const_pointer if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::const_pointer is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<const value_type>[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:void_pointer,allocator_traits)
|
||||
|
||||
`using void_pointer = see below;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1730)
|
||||
|
||||
*Type*: Alloc::void_pointer if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::void_pointer is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<void>[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:const_void_pointer,allocator_traits)
|
||||
|
||||
`using const_void_pointer = see below;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1743)
|
||||
|
||||
*Type*: Alloc::const_void_pointer if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::const_void_pointer is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<const void>[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:difference_type,allocator_traits)
|
||||
|
||||
`using difference_type = see below;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1756)
|
||||
|
||||
*Type*: Alloc::difference_type if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::difference_type is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::difference_type[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:size_type,allocator_traits)
|
||||
|
||||
`using size_type = see below;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1769)
|
||||
|
||||
*Type*: Alloc::size_type if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::size_type is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,make_unsigned_t<difference_type>[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_copy_assignment,allocator_traits)
|
||||
|
||||
`using propagate_on_container_copy_assignment = see below;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1782)
|
||||
|
||||
*Type*: Alloc::propagate_on_container_copy_assignment if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_copy_assignment is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_move_assignment,allocator_traits)
|
||||
|
||||
`using propagate_on_container_move_assignment = see below;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1795)
|
||||
|
||||
*Type*: Alloc::propagate_on_container_move_assignment if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_move_assignment is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:propagate_on_container_swap,allocator_traits)
|
||||
|
||||
`using propagate_on_container_swap = see below;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1808)
|
||||
|
||||
*Type*: Alloc::propagate_on_container_swap if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_swap is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:is_always_equal,allocator_traits)
|
||||
|
||||
`using is_always_equal = see below;
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1821)
|
||||
|
||||
*Type*: Alloc::is_always_equal if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::is_always_equal is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction"));
|
||||
otherwise is_empty<Alloc>::type[.](#10.sentence-1)
|
||||
|
||||
[ð](#lib:rebind_alloc,allocator_traits)
|
||||
|
||||
`template<class T> using rebind_alloc = see below;
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1834)
|
||||
|
||||
*Alias template*: Alloc::rebind<T>::other if
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::rebind<T>::other is valid and denotes a
|
||||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,Alloc<T, Args> if Alloc is a class template instantiation
|
||||
of the form Alloc<U, Args>, where Args is zero or more type arguments;
|
||||
otherwise, the instantiation of rebind_alloc is ill-formed[.](#11.sentence-1)
|
||||
343
cppdraft/allocator/uses.md
Normal file
343
cppdraft/allocator/uses.md
Normal file
@@ -0,0 +1,343 @@
|
||||
[allocator.uses]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.uses)
|
||||
|
||||
### 20.2.8 uses_allocator [allocator.uses]
|
||||
|
||||
#### [20.2.8.1](#trait) uses_allocator trait [[allocator.uses.trait]](allocator.uses.trait)
|
||||
|
||||
[ð](#lib:uses_allocator)
|
||||
|
||||
`template<class T, class Alloc> struct uses_allocator;
|
||||
`
|
||||
|
||||
[1](#trait-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1288)
|
||||
|
||||
*Remarks*: Automatically detects whether T has a nested allocator_type that
|
||||
is convertible from Alloc[.](#trait-1.sentence-1)
|
||||
|
||||
Meets the [*Cpp17BinaryTypeTrait*](meta.rqmts#:Cpp17BinaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#trait-1.sentence-2)
|
||||
|
||||
The implementation shall provide a definition that is
|
||||
derived from true_type if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") T::allocator_type is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")) andis_convertible_v<Alloc, T::allocator_type> != false, otherwise it shall be
|
||||
derived from false_type[.](#trait-1.sentence-3)
|
||||
|
||||
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:
|
||||
|
||||
- [(1.1)](#trait-1.1)
|
||||
|
||||
the first argument of a constructor has type allocator_arg_t and the
|
||||
second argument has type Alloc or
|
||||
|
||||
- [(1.2)](#trait-1.2)
|
||||
|
||||
the last argument of a constructor has type Alloc[.](#trait-1.sentence-4)
|
||||
|
||||
#### [20.2.8.2](#construction) Uses-allocator construction [[allocator.uses.construction]](allocator.uses.construction)
|
||||
|
||||
[1](#construction-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1310)
|
||||
|
||||
[*Uses-allocator construction*](#def:uses-allocator_construction "20.2.8.2 Uses-allocator construction [allocator.uses.construction]") with allocator alloc and constructor arguments args... refers to the construction of an object of type T such that alloc is passed to the constructor of T if T uses an allocator type compatible with alloc[.](#construction-1.sentence-1)
|
||||
|
||||
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[.](#construction-1.sentence-2)
|
||||
|
||||
[2](#construction-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1320)
|
||||
|
||||
The following utility functions support
|
||||
three conventions for passing alloc to a constructor:
|
||||
|
||||
- [(2.1)](#construction-2.1)
|
||||
|
||||
If T does not use an allocator compatible with alloc,
|
||||
then alloc is ignored[.](#construction-2.1.sentence-1)
|
||||
|
||||
- [(2.2)](#construction-2.2)
|
||||
|
||||
Otherwise, if T has a constructor invocable as T(allocator_arg, alloc, args...) (leading-allocator convention),
|
||||
then uses-allocator construction chooses this constructor form[.](#construction-2.2.sentence-1)
|
||||
|
||||
- [(2.3)](#construction-2.3)
|
||||
|
||||
Otherwise, if T has a constructor invocable as T(args..., alloc) (trailing-allocator convention),
|
||||
then uses-allocator construction chooses this constructor form[.](#construction-2.3.sentence-1)
|
||||
|
||||
[3](#construction-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1337)
|
||||
|
||||
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[.](#construction-3.sentence-1)
|
||||
|
||||
Additionally, overloads are provided
|
||||
that treat specializations of pair such that uses-allocator construction is applied individually
|
||||
to the first and second data members[.](#construction-3.sentence-2)
|
||||
|
||||
The make_obj_using_allocator anduninitialized_construct_using_allocator function templates
|
||||
apply the modified constructor arguments
|
||||
to construct an object of type T as a return value or in-place, respectively[.](#construction-3.sentence-3)
|
||||
|
||||
[*Note [1](#construction-note-1)*:
|
||||
|
||||
For uses_allocator_construction_args andmake_obj_using_allocator, type T is not deduced and must therefore be specified explicitly by the caller[.](#construction-3.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args)
|
||||
|
||||
`template<class T, class Alloc, class... Args>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||||
Args&&... args) noexcept;
|
||||
`
|
||||
|
||||
[4](#construction-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1364)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is not a specialization of pair[.](#construction-4.sentence-1)
|
||||
|
||||
[5](#construction-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1368)
|
||||
|
||||
*Returns*: A tuple value determined as follows:
|
||||
|
||||
- [(5.1)](#construction-5.1)
|
||||
|
||||
If uses_allocator_v<remove_cv_t<T>, Alloc> is false and is_constructible_v<T, Args...> is true,
|
||||
return forward_as_tuple(std::forward<Args>(args)...)[.](#construction-5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#construction-5.2)
|
||||
|
||||
Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and is_constructible_v<T, allocator_arg_t, const Alloc&, Args...> is true,
|
||||
returntuple<allocator_arg_t, const Alloc&, Args&&...>( allocator_arg, alloc, std::forward<Args>(args)...)
|
||||
|
||||
- [(5.3)](#construction-5.3)
|
||||
|
||||
Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and is_constructible_v<T, Args..., const Alloc&> is true,
|
||||
return forward_as_tuple(std::forward<Args>(args)..., alloc)[.](#construction-5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#construction-5.4)
|
||||
|
||||
Otherwise, the program is ill-formed[.](#construction-5.4.sentence-1)
|
||||
|
||||
[*Note [2](#construction-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[.](#construction-5.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args_)
|
||||
|
||||
`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;
|
||||
`
|
||||
|
||||
[6](#construction-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1407)
|
||||
|
||||
Let T1 be T::first_type[.](#construction-6.sentence-1)
|
||||
|
||||
Let T2 be T::second_type[.](#construction-6.sentence-2)
|
||||
|
||||
[7](#construction-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1411)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#construction-7.sentence-1)
|
||||
|
||||
[8](#construction-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1415)
|
||||
|
||||
*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)));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args__)
|
||||
|
||||
`template<class T, class Alloc>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept;
|
||||
`
|
||||
|
||||
[9](#construction-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1439)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#construction-9.sentence-1)
|
||||
|
||||
[10](#construction-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1443)
|
||||
|
||||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||||
tuple<>{}, tuple<>{});
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args___)
|
||||
|
||||
`template<class T, class Alloc, class U, class V>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||||
U&& u, V&& v) noexcept;
|
||||
`
|
||||
|
||||
[11](#construction-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1460)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#construction-11.sentence-1)
|
||||
|
||||
[12](#construction-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1464)
|
||||
|
||||
*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)));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args____)
|
||||
|
||||
`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;
|
||||
`
|
||||
|
||||
[13](#construction-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1485)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#construction-13.sentence-1)
|
||||
|
||||
[14](#construction-14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1489)
|
||||
|
||||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||||
forward_as_tuple(pr.first),
|
||||
forward_as_tuple(pr.second));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args_____)
|
||||
|
||||
`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;
|
||||
`
|
||||
|
||||
[15](#construction-15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1510)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#construction-15.sentence-1)
|
||||
|
||||
[16](#construction-16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1514)
|
||||
|
||||
*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))));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args______)
|
||||
|
||||
`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;
|
||||
`
|
||||
|
||||
[17](#construction-17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1531)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair andremove_cvref_t<P> is not a specialization of ranges::subrange[.](#construction-17.sentence-1)
|
||||
|
||||
[18](#construction-18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1536)
|
||||
|
||||
*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))));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args_______)
|
||||
|
||||
`template<class T, class Alloc, class U>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
|
||||
`
|
||||
|
||||
[19](#construction-19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1553)
|
||||
|
||||
Let *FUN* be the function template:template<class A, class B>void *FUN*(const pair<A, B>&);
|
||||
|
||||
[20](#construction-20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1560)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair, and either:
|
||||
|
||||
- [(20.1)](#construction-20.1)
|
||||
|
||||
remove_cvref_t<U> is a specialization of ranges::subrange, or
|
||||
|
||||
- [(20.2)](#construction-20.2)
|
||||
|
||||
U does not satisfy [*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") and
|
||||
the expression *FUN*(u) is not well-formed
|
||||
when considered as an unevaluated operand[.](#construction-20.sentence-1)
|
||||
|
||||
[21](#construction-21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1572)
|
||||
|
||||
Let *pair-constructor* be an exposition-only class defined as follows:class *pair-constructor* {using *pair-type* = remove_cv_t<T>; // *exposition only*constexpr auto *do-construct*(const *pair-type*& p) const { // *exposition only*return make_obj_using_allocator<*pair-type*>(*alloc_*, p); }constexpr auto *do-construct*(*pair-type*&& p) const { // *exposition only*return make_obj_using_allocator<*pair-type*>(*alloc_*, std::move(p)); }const Alloc& *alloc_*; // *exposition only* U& *u_*; // *exposition only*public:constexpr operator *pair-type*() const {return *do-construct*(std::forward<U>(*u_*)); }};
|
||||
|
||||
[22](#construction-22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1595)
|
||||
|
||||
*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[.](#construction-22.sentence-1)
|
||||
|
||||
[ð](#lib:make_obj_using_allocator)
|
||||
|
||||
`template<class T, class Alloc, class... Args>
|
||||
constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
|
||||
`
|
||||
|
||||
[23](#construction-23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1610)
|
||||
|
||||
*Effects*: Equivalent to:return make_from_tuple<T>(uses_allocator_construction_args<T>( alloc, std::forward<Args>(args)...));
|
||||
|
||||
[ð](#lib:uninitialized_construct_using_allocator)
|
||||
|
||||
`template<class T, class Alloc, class... Args>
|
||||
constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
|
||||
`
|
||||
|
||||
[24](#construction-24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1626)
|
||||
|
||||
*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)...));
|
||||
311
cppdraft/allocator/uses/construction.md
Normal file
311
cppdraft/allocator/uses/construction.md
Normal file
@@ -0,0 +1,311 @@
|
||||
[allocator.uses.construction]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.uses.construction)
|
||||
|
||||
### 20.2.8 uses_allocator [[allocator.uses]](allocator.uses#construction)
|
||||
|
||||
#### 20.2.8.2 Uses-allocator construction [allocator.uses.construction]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1310)
|
||||
|
||||
[*Uses-allocator construction*](#def:uses-allocator_construction "20.2.8.2 Uses-allocator construction [allocator.uses.construction]") with allocator alloc and constructor arguments args... refers to the construction of an object of type T such that alloc is passed to the constructor of T if T uses an allocator type compatible with alloc[.](#1.sentence-1)
|
||||
|
||||
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[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1320)
|
||||
|
||||
The following utility functions support
|
||||
three conventions for passing alloc to a constructor:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
If T does not use an allocator compatible with alloc,
|
||||
then alloc is ignored[.](#2.1.sentence-1)
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
Otherwise, if T has a constructor invocable as T(allocator_arg, alloc, args...) (leading-allocator convention),
|
||||
then uses-allocator construction chooses this constructor form[.](#2.2.sentence-1)
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
Otherwise, if T has a constructor invocable as T(args..., alloc) (trailing-allocator convention),
|
||||
then uses-allocator construction chooses this constructor form[.](#2.3.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1337)
|
||||
|
||||
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[.](#3.sentence-1)
|
||||
|
||||
Additionally, overloads are provided
|
||||
that treat specializations of pair such that uses-allocator construction is applied individually
|
||||
to the first and second data members[.](#3.sentence-2)
|
||||
|
||||
The make_obj_using_allocator anduninitialized_construct_using_allocator function templates
|
||||
apply the modified constructor arguments
|
||||
to construct an object of type T as a return value or in-place, respectively[.](#3.sentence-3)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
For uses_allocator_construction_args andmake_obj_using_allocator, type T is not deduced and must therefore be specified explicitly by the caller[.](#3.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args)
|
||||
|
||||
`template<class T, class Alloc, class... Args>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||||
Args&&... args) noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1364)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is not a specialization of pair[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1368)
|
||||
|
||||
*Returns*: A tuple value determined as follows:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
If uses_allocator_v<remove_cv_t<T>, Alloc> is false and is_constructible_v<T, Args...> is true,
|
||||
return forward_as_tuple(std::forward<Args>(args)...)[.](#5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and is_constructible_v<T, allocator_arg_t, const Alloc&, Args...> is true,
|
||||
returntuple<allocator_arg_t, const Alloc&, Args&&...>( allocator_arg, alloc, std::forward<Args>(args)...)
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and is_constructible_v<T, Args..., const Alloc&> is true,
|
||||
return forward_as_tuple(std::forward<Args>(args)..., alloc)[.](#5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
Otherwise, the program is ill-formed[.](#5.4.sentence-1)
|
||||
|
||||
[*Note [2](#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[.](#5.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args_)
|
||||
|
||||
`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;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1407)
|
||||
|
||||
Let T1 be T::first_type[.](#6.sentence-1)
|
||||
|
||||
Let T2 be T::second_type[.](#6.sentence-2)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1411)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1415)
|
||||
|
||||
*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)));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args__)
|
||||
|
||||
`template<class T, class Alloc>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1439)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1443)
|
||||
|
||||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||||
tuple<>{}, tuple<>{});
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args___)
|
||||
|
||||
`template<class T, class Alloc, class U, class V>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||||
U&& u, V&& v) noexcept;
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1460)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#11.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1464)
|
||||
|
||||
*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)));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args____)
|
||||
|
||||
`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;
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1485)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1489)
|
||||
|
||||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||||
forward_as_tuple(pr.first),
|
||||
forward_as_tuple(pr.second));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args_____)
|
||||
|
||||
`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;
|
||||
`
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1510)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#15.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1514)
|
||||
|
||||
*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))));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args______)
|
||||
|
||||
`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;
|
||||
`
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1531)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair andremove_cvref_t<P> is not a specialization of ranges::subrange[.](#17.sentence-1)
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1536)
|
||||
|
||||
*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))));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args_______)
|
||||
|
||||
`template<class T, class Alloc, class U>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
|
||||
`
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1553)
|
||||
|
||||
Let *FUN* be the function template:template<class A, class B>void *FUN*(const pair<A, B>&);
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1560)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair, and either:
|
||||
|
||||
- [(20.1)](#20.1)
|
||||
|
||||
remove_cvref_t<U> is a specialization of ranges::subrange, or
|
||||
|
||||
- [(20.2)](#20.2)
|
||||
|
||||
U does not satisfy [*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") and
|
||||
the expression *FUN*(u) is not well-formed
|
||||
when considered as an unevaluated operand[.](#20.sentence-1)
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1572)
|
||||
|
||||
Let *pair-constructor* be an exposition-only class defined as follows:class *pair-constructor* {using *pair-type* = remove_cv_t<T>; // *exposition only*constexpr auto *do-construct*(const *pair-type*& p) const { // *exposition only*return make_obj_using_allocator<*pair-type*>(*alloc_*, p); }constexpr auto *do-construct*(*pair-type*&& p) const { // *exposition only*return make_obj_using_allocator<*pair-type*>(*alloc_*, std::move(p)); }const Alloc& *alloc_*; // *exposition only* U& *u_*; // *exposition only*public:constexpr operator *pair-type*() const {return *do-construct*(std::forward<U>(*u_*)); }};
|
||||
|
||||
[22](#22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1595)
|
||||
|
||||
*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[.](#22.sentence-1)
|
||||
|
||||
[ð](#lib:make_obj_using_allocator)
|
||||
|
||||
`template<class T, class Alloc, class... Args>
|
||||
constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
|
||||
`
|
||||
|
||||
[23](#23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1610)
|
||||
|
||||
*Effects*: Equivalent to:return make_from_tuple<T>(uses_allocator_construction_args<T>( alloc, std::forward<Args>(args)...));
|
||||
|
||||
[ð](#lib:uninitialized_construct_using_allocator)
|
||||
|
||||
`template<class T, class Alloc, class... Args>
|
||||
constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
|
||||
`
|
||||
|
||||
[24](#24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1626)
|
||||
|
||||
*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)...));
|
||||
39
cppdraft/allocator/uses/trait.md
Normal file
39
cppdraft/allocator/uses/trait.md
Normal file
@@ -0,0 +1,39 @@
|
||||
[allocator.uses.trait]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.uses.trait)
|
||||
|
||||
### 20.2.8 uses_allocator [[allocator.uses]](allocator.uses#trait)
|
||||
|
||||
#### 20.2.8.1 uses_allocator trait [allocator.uses.trait]
|
||||
|
||||
[ð](#lib:uses_allocator)
|
||||
|
||||
`template<class T, class Alloc> struct uses_allocator;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1288)
|
||||
|
||||
*Remarks*: Automatically detects whether T has a nested allocator_type that
|
||||
is convertible from Alloc[.](#1.sentence-1)
|
||||
|
||||
Meets the [*Cpp17BinaryTypeTrait*](meta.rqmts#:Cpp17BinaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#1.sentence-2)
|
||||
|
||||
The implementation shall provide a definition that is
|
||||
derived from true_type if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") T::allocator_type is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")) andis_convertible_v<Alloc, T::allocator_type> != false, otherwise it shall be
|
||||
derived from false_type[.](#1.sentence-3)
|
||||
|
||||
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:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
the first argument of a constructor has type allocator_arg_t and the
|
||||
second argument has type Alloc or
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
the last argument of a constructor has type Alloc[.](#1.sentence-4)
|
||||
Reference in New Issue
Block a user