Init
This commit is contained in:
1638
cppdraft/mem/composite/types.md
Normal file
1638
cppdraft/mem/composite/types.md
Normal file
File diff suppressed because it is too large
Load Diff
29
cppdraft/mem/general.md
Normal file
29
cppdraft/mem/general.md
Normal file
@@ -0,0 +1,29 @@
|
||||
[mem.general]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.1 General [mem.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6)
|
||||
|
||||
This Clause describes components for memory management[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L9)
|
||||
|
||||
The following subclauses describe general memory management facilities,
|
||||
smart pointers, memory resources, and scoped allocators,
|
||||
as summarized in Table [50](#tab:mem.summary "Table 50: Memory management library summary")[.](#2.sentence-1)
|
||||
|
||||
Table [50](#tab:mem.summary) — Memory management library summary [[tab:mem.summary]](./tab:mem.summary)
|
||||
|
||||
| [ð](#tab:mem.summary-row-1) | **Subclause** | **Header** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:mem.summary-row-2)<br>[[memory]](memory "20.2 Memory") | Memory | <cstdlib>, <memory> |
|
||||
| [ð](#tab:mem.summary-row-3)<br>[[smartptr]](smartptr "20.3 Smart pointers") | Smart pointers | <memory> |
|
||||
| [ð](#tab:mem.summary-row-4)<br>[[mem.composite.types]](mem.composite.types "20.4 Types for composite class design") | Types for composite class design | <memory> |
|
||||
| [ð](#tab:mem.summary-row-5)<br>[[mem.res]](mem.res "20.5 Memory resources") | Memory resources | <memory_resource> |
|
||||
| [ð](#tab:mem.summary-row-6)<br>[[allocator.adaptor]](allocator.adaptor "20.6 Class template scoped_allocator_adaptor") | Scoped allocators | <scoped_allocator> |
|
||||
341
cppdraft/mem/poly/allocator/class.md
Normal file
341
cppdraft/mem/poly/allocator/class.md
Normal file
@@ -0,0 +1,341 @@
|
||||
[mem.poly.allocator.class]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#mem.poly.allocator.class)
|
||||
|
||||
### 20.5.3 Class template polymorphic_allocator [mem.poly.allocator.class]
|
||||
|
||||
#### [20.5.3.1](#general) General [[mem.poly.allocator.class.general]](mem.poly.allocator.class.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7653)
|
||||
|
||||
A specialization of class template pmr::polymorphic_allocator meets
|
||||
the *Cpp17Allocator* requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))
|
||||
if its template argument is a cv-unqualified object type[.](#general-1.sentence-1)
|
||||
|
||||
Constructed with different memory resources,
|
||||
different instances of the same specialization of pmr::polymorphic_allocator can exhibit entirely different allocation behavior[.](#general-1.sentence-2)
|
||||
|
||||
This runtime polymorphism allows objects that use polymorphic_allocator to behave as if they used different allocator types at run time
|
||||
even though they use the same static allocator type[.](#general-1.sentence-3)
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7664)
|
||||
|
||||
A specialization of class template pmr::polymorphic_allocator meets the allocator completeness requirements ([[allocator.requirements.completeness]](allocator.requirements.completeness "16.4.4.6.2 Allocator completeness requirements"))
|
||||
if its template argument is a cv-unqualified object type[.](#general-2.sentence-1)
|
||||
|
||||
[ð](#lib:polymorphic_allocator)
|
||||
|
||||
namespace std::pmr {template<class Tp = byte> class polymorphic_allocator { memory_resource* memory_rsrc; // *exposition only*public:using value_type = Tp; // [[mem.poly.allocator.ctor]](#mem.poly.allocator.ctor "20.5.3.2 Constructors"), constructors polymorphic_allocator() noexcept;
|
||||
polymorphic_allocator(memory_resource* r);
|
||||
|
||||
polymorphic_allocator(const polymorphic_allocator& other) = default; template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
|
||||
|
||||
polymorphic_allocator& operator=(const polymorphic_allocator&) = delete; // [[mem.poly.allocator.mem]](#mem.poly.allocator.mem "20.5.3.3 Member functions"), member functions Tp* allocate(size_t n); void deallocate(Tp* p, size_t n); void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t)); template<class T> T* allocate_object(size_t n = 1); template<class T> void deallocate_object(T* p, size_t n = 1); template<class T, class... CtorArgs> T* new_object(CtorArgs&&... ctor_args); template<class T> void delete_object(T* p); template<class T, class... Args>void construct(T* p, Args&&... args); template<class T>void destroy(T* p);
|
||||
|
||||
polymorphic_allocator select_on_container_copy_construction() const;
|
||||
|
||||
memory_resource* resource() const; // friendsfriend bool operator==(const polymorphic_allocator& a, const polymorphic_allocator& b) noexcept {return *a.resource() == *b.resource(); }};}
|
||||
|
||||
#### [20.5.3.2](#mem.poly.allocator.ctor) Constructors [[mem.poly.allocator.ctor]](mem.poly.allocator.ctor)
|
||||
|
||||
[ð](#lib:polymorphic_allocator,constructor)
|
||||
|
||||
`polymorphic_allocator() noexcept;
|
||||
`
|
||||
|
||||
[1](#mem.poly.allocator.ctor-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7728)
|
||||
|
||||
*Effects*: Sets memory_rsrc to get_default_resource()[.](#mem.poly.allocator.ctor-1.sentence-1)
|
||||
|
||||
[ð](#lib:polymorphic_allocator,constructor_)
|
||||
|
||||
`polymorphic_allocator(memory_resource* r);
|
||||
`
|
||||
|
||||
[2](#mem.poly.allocator.ctor-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7739)
|
||||
|
||||
*Preconditions*: r is non-null[.](#mem.poly.allocator.ctor-2.sentence-1)
|
||||
|
||||
[3](#mem.poly.allocator.ctor-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7743)
|
||||
|
||||
*Effects*: Sets memory_rsrc to r[.](#mem.poly.allocator.ctor-3.sentence-1)
|
||||
|
||||
[4](#mem.poly.allocator.ctor-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7747)
|
||||
|
||||
*Throws*: Nothing[.](#mem.poly.allocator.ctor-4.sentence-1)
|
||||
|
||||
[5](#mem.poly.allocator.ctor-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7751)
|
||||
|
||||
[*Note [1](#mem.poly.allocator.ctor-note-1)*:
|
||||
|
||||
This constructor provides an implicit conversion from memory_resource*[.](#mem.poly.allocator.ctor-5.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:polymorphic_allocator,constructor__)
|
||||
|
||||
`template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#mem.poly.allocator.ctor-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7763)
|
||||
|
||||
*Effects*: Sets memory_rsrc to other.resource()[.](#mem.poly.allocator.ctor-6.sentence-1)
|
||||
|
||||
#### [20.5.3.3](#mem.poly.allocator.mem) Member functions [[mem.poly.allocator.mem]](mem.poly.allocator.mem)
|
||||
|
||||
[ð](#lib:allocate,polymorphic_allocator)
|
||||
|
||||
`Tp* allocate(size_t n);
|
||||
`
|
||||
|
||||
[1](#mem.poly.allocator.mem-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7777)
|
||||
|
||||
*Effects*: If numeric_limits<size_t>::max() / sizeof(Tp) < n,
|
||||
throws bad_array_new_length[.](#mem.poly.allocator.mem-1.sentence-1)
|
||||
|
||||
Otherwise equivalent to:return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));
|
||||
|
||||
[ð](#lib:deallocate,polymorphic_allocator)
|
||||
|
||||
`void deallocate(Tp* p, size_t n);
|
||||
`
|
||||
|
||||
[2](#mem.poly.allocator.mem-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7793)
|
||||
|
||||
*Preconditions*: p was allocated from a memory resource x,
|
||||
equal to *memory_rsrc,
|
||||
using x.allocate(n * sizeof(Tp), alignof(Tp))[.](#mem.poly.allocator.mem-2.sentence-1)
|
||||
|
||||
[3](#mem.poly.allocator.mem-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7799)
|
||||
|
||||
*Effects*: Equivalent to memory_rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp))[.](#mem.poly.allocator.mem-3.sentence-1)
|
||||
|
||||
[4](#mem.poly.allocator.mem-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7803)
|
||||
|
||||
*Throws*: Nothing[.](#mem.poly.allocator.mem-4.sentence-1)
|
||||
|
||||
[ð](#lib:allocate_bytes,polymorphic_allocator)
|
||||
|
||||
`void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
|
||||
`
|
||||
|
||||
[5](#mem.poly.allocator.mem-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7814)
|
||||
|
||||
*Effects*: Equivalent to: return memory_rsrc->allocate(nbytes, alignment);
|
||||
|
||||
[6](#mem.poly.allocator.mem-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7818)
|
||||
|
||||
[*Note [1](#mem.poly.allocator.mem-note-1)*:
|
||||
|
||||
The return type is void* (rather than, e.g., byte*)
|
||||
to support conversion to an arbitrary pointer type U* by static_cast<U*>, thus facilitating construction of a U object in the allocated memory[.](#mem.poly.allocator.mem-6.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:deallocate_bytes,polymorphic_allocator)
|
||||
|
||||
`void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
|
||||
`
|
||||
|
||||
[7](#mem.poly.allocator.mem-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7833)
|
||||
|
||||
*Effects*: Equivalent to memory_rsrc->deallocate(p, nbytes, alignment)[.](#mem.poly.allocator.mem-7.sentence-1)
|
||||
|
||||
[ð](#lib:allocate_object,polymorphic_allocator)
|
||||
|
||||
`template<class T>
|
||||
T* allocate_object(size_t n = 1);
|
||||
`
|
||||
|
||||
[8](#mem.poly.allocator.mem-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7845)
|
||||
|
||||
*Effects*: Allocates memory suitable for holding
|
||||
an array of n objects of type T, as follows:
|
||||
|
||||
- [(8.1)](#mem.poly.allocator.mem-8.1)
|
||||
|
||||
if numeric_limits<size_t>::max() / sizeof(T) < n,
|
||||
throws bad_array_new_length,
|
||||
|
||||
- [(8.2)](#mem.poly.allocator.mem-8.2)
|
||||
|
||||
otherwise equivalent to:return static_cast<T*>(allocate_bytes(n*sizeof(T), alignof(T)));
|
||||
|
||||
[9](#mem.poly.allocator.mem-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7860)
|
||||
|
||||
[*Note [2](#mem.poly.allocator.mem-note-2)*:
|
||||
|
||||
T is not deduced and must therefore be provided as a template argument[.](#mem.poly.allocator.mem-9.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:deallocate_object,polymorphic_allocator)
|
||||
|
||||
`template<class T>
|
||||
void deallocate_object(T* p, size_t n = 1);
|
||||
`
|
||||
|
||||
[10](#mem.poly.allocator.mem-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7873)
|
||||
|
||||
*Effects*: Equivalent to deallocate_bytes(p, n*sizeof(T), alignof(T))[.](#mem.poly.allocator.mem-10.sentence-1)
|
||||
|
||||
[ð](#lib:new_object,polymorphic_allocator)
|
||||
|
||||
`template<class T, class... CtorArgs>
|
||||
T* new_object(CtorArgs&&... ctor_args);
|
||||
`
|
||||
|
||||
[11](#mem.poly.allocator.mem-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7885)
|
||||
|
||||
*Effects*: Allocates and constructs an object of type T, as follows[.](#mem.poly.allocator.mem-11.sentence-1)
|
||||
|
||||
|
||||
Equivalent to:T* p = allocate_object<T>();try { construct(p, std::forward<CtorArgs>(ctor_args)...);} catch (...) { deallocate_object(p); throw;}return p;
|
||||
|
||||
[12](#mem.poly.allocator.mem-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7900)
|
||||
|
||||
[*Note [3](#mem.poly.allocator.mem-note-3)*:
|
||||
|
||||
T is not deduced and must therefore be provided as a template argument[.](#mem.poly.allocator.mem-12.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:new_object,polymorphic_allocator_)
|
||||
|
||||
`template<class T>
|
||||
void delete_object(T* p);
|
||||
`
|
||||
|
||||
[13](#mem.poly.allocator.mem-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7913)
|
||||
|
||||
*Effects*: Equivalent to:destroy(p);
|
||||
deallocate_object(p);
|
||||
|
||||
[ð](#lib:construct,polymorphic_allocator)
|
||||
|
||||
`template<class T, class... Args>
|
||||
void construct(T* p, Args&&... args);
|
||||
`
|
||||
|
||||
[14](#mem.poly.allocator.mem-14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7929)
|
||||
|
||||
*Mandates*: Uses-allocator construction of T with allocator *this (see [[allocator.uses.construction]](allocator.uses.construction "20.2.8.2 Uses-allocator construction"))
|
||||
and constructor arguments std::forward<Args>(args)... is well-formed[.](#mem.poly.allocator.mem-14.sentence-1)
|
||||
|
||||
[15](#mem.poly.allocator.mem-15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7935)
|
||||
|
||||
*Effects*: Constructs a T object in the storage
|
||||
whose address is represented by p by uses-allocator construction with allocator *this and constructor arguments std::forward<Args>(args)...[.](#mem.poly.allocator.mem-15.sentence-1)
|
||||
|
||||
[16](#mem.poly.allocator.mem-16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7942)
|
||||
|
||||
*Throws*: Nothing unless the constructor for T throws[.](#mem.poly.allocator.mem-16.sentence-1)
|
||||
|
||||
[ð](#lib:destroy,polymorphic_allocator)
|
||||
|
||||
`template<class T>
|
||||
void destroy(T* p);
|
||||
`
|
||||
|
||||
[17](#mem.poly.allocator.mem-17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7954)
|
||||
|
||||
*Effects*: Equivalent to p->~T()[.](#mem.poly.allocator.mem-17.sentence-1)
|
||||
|
||||
[ð](#lib:select_on_container_copy_construction,polymorphic_allocator)
|
||||
|
||||
`polymorphic_allocator select_on_container_copy_construction() const;
|
||||
`
|
||||
|
||||
[18](#mem.poly.allocator.mem-18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7965)
|
||||
|
||||
*Returns*: polymorphic_allocator()[.](#mem.poly.allocator.mem-18.sentence-1)
|
||||
|
||||
[19](#mem.poly.allocator.mem-19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7969)
|
||||
|
||||
[*Note [4](#mem.poly.allocator.mem-note-4)*:
|
||||
|
||||
The memory resource is not propagated[.](#mem.poly.allocator.mem-19.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:resource,polymorphic_allocator)
|
||||
|
||||
`memory_resource* resource() const;
|
||||
`
|
||||
|
||||
[20](#mem.poly.allocator.mem-20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7981)
|
||||
|
||||
*Returns*: memory_rsrc[.](#mem.poly.allocator.mem-20.sentence-1)
|
||||
|
||||
#### [20.5.3.4](#mem.poly.allocator.eq) Equality [[mem.poly.allocator.eq]](mem.poly.allocator.eq)
|
||||
|
||||
[ð](#lib:operator==,polymorphic_allocator)
|
||||
|
||||
`template<class T1, class T2>
|
||||
bool operator==(const polymorphic_allocator<T1>& a,
|
||||
const polymorphic_allocator<T2>& b) noexcept;
|
||||
`
|
||||
|
||||
[1](#mem.poly.allocator.eq-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7996)
|
||||
|
||||
*Returns*: *a.resource() == *b.resource()[.](#mem.poly.allocator.eq-1.sentence-1)
|
||||
43
cppdraft/mem/poly/allocator/class/general.md
Normal file
43
cppdraft/mem/poly/allocator/class/general.md
Normal file
@@ -0,0 +1,43 @@
|
||||
[mem.poly.allocator.class.general]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#mem.poly.allocator.class.general)
|
||||
|
||||
### 20.5.3 Class template polymorphic_allocator [[mem.poly.allocator.class]](mem.poly.allocator.class#general)
|
||||
|
||||
#### 20.5.3.1 General [mem.poly.allocator.class.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7653)
|
||||
|
||||
A specialization of class template pmr::polymorphic_allocator meets
|
||||
the *Cpp17Allocator* requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))
|
||||
if its template argument is a cv-unqualified object type[.](#1.sentence-1)
|
||||
|
||||
Constructed with different memory resources,
|
||||
different instances of the same specialization of pmr::polymorphic_allocator can exhibit entirely different allocation behavior[.](#1.sentence-2)
|
||||
|
||||
This runtime polymorphism allows objects that use polymorphic_allocator to behave as if they used different allocator types at run time
|
||||
even though they use the same static allocator type[.](#1.sentence-3)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7664)
|
||||
|
||||
A specialization of class template pmr::polymorphic_allocator meets the allocator completeness requirements ([[allocator.requirements.completeness]](allocator.requirements.completeness "16.4.4.6.2 Allocator completeness requirements"))
|
||||
if its template argument is a cv-unqualified object type[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:polymorphic_allocator)
|
||||
|
||||
namespace std::pmr {template<class Tp = byte> class polymorphic_allocator { memory_resource* memory_rsrc; // *exposition only*public:using value_type = Tp; // [[mem.poly.allocator.ctor]](mem.poly.allocator.ctor "20.5.3.2 Constructors"), constructors polymorphic_allocator() noexcept;
|
||||
polymorphic_allocator(memory_resource* r);
|
||||
|
||||
polymorphic_allocator(const polymorphic_allocator& other) = default; template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
|
||||
|
||||
polymorphic_allocator& operator=(const polymorphic_allocator&) = delete; // [[mem.poly.allocator.mem]](mem.poly.allocator.mem "20.5.3.3 Member functions"), member functions Tp* allocate(size_t n); void deallocate(Tp* p, size_t n); void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t)); template<class T> T* allocate_object(size_t n = 1); template<class T> void deallocate_object(T* p, size_t n = 1); template<class T, class... CtorArgs> T* new_object(CtorArgs&&... ctor_args); template<class T> void delete_object(T* p); template<class T, class... Args>void construct(T* p, Args&&... args); template<class T>void destroy(T* p);
|
||||
|
||||
polymorphic_allocator select_on_container_copy_construction() const;
|
||||
|
||||
memory_resource* resource() const; // friendsfriend bool operator==(const polymorphic_allocator& a, const polymorphic_allocator& b) noexcept {return *a.resource() == *b.resource(); }};}
|
||||
64
cppdraft/mem/poly/allocator/ctor.md
Normal file
64
cppdraft/mem/poly/allocator/ctor.md
Normal file
@@ -0,0 +1,64 @@
|
||||
[mem.poly.allocator.ctor]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#mem.poly.allocator.ctor)
|
||||
|
||||
### 20.5.3 Class template polymorphic_allocator [[mem.poly.allocator.class]](mem.poly.allocator.class#mem.poly.allocator.ctor)
|
||||
|
||||
#### 20.5.3.2 Constructors [mem.poly.allocator.ctor]
|
||||
|
||||
[ð](#lib:polymorphic_allocator,constructor)
|
||||
|
||||
`polymorphic_allocator() noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7728)
|
||||
|
||||
*Effects*: Sets memory_rsrc to get_default_resource()[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:polymorphic_allocator,constructor_)
|
||||
|
||||
`polymorphic_allocator(memory_resource* r);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7739)
|
||||
|
||||
*Preconditions*: r is non-null[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7743)
|
||||
|
||||
*Effects*: Sets memory_rsrc to r[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7747)
|
||||
|
||||
*Throws*: Nothing[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7751)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This constructor provides an implicit conversion from memory_resource*[.](#5.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:polymorphic_allocator,constructor__)
|
||||
|
||||
`template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7763)
|
||||
|
||||
*Effects*: Sets memory_rsrc to other.resource()[.](#6.sentence-1)
|
||||
22
cppdraft/mem/poly/allocator/eq.md
Normal file
22
cppdraft/mem/poly/allocator/eq.md
Normal file
@@ -0,0 +1,22 @@
|
||||
[mem.poly.allocator.eq]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#mem.poly.allocator.eq)
|
||||
|
||||
### 20.5.3 Class template polymorphic_allocator [[mem.poly.allocator.class]](mem.poly.allocator.class#mem.poly.allocator.eq)
|
||||
|
||||
#### 20.5.3.4 Equality [mem.poly.allocator.eq]
|
||||
|
||||
[ð](#lib:operator==,polymorphic_allocator)
|
||||
|
||||
`template<class T1, class T2>
|
||||
bool operator==(const polymorphic_allocator<T1>& a,
|
||||
const polymorphic_allocator<T2>& b) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7996)
|
||||
|
||||
*Returns*: *a.resource() == *b.resource()[.](#1.sentence-1)
|
||||
233
cppdraft/mem/poly/allocator/mem.md
Normal file
233
cppdraft/mem/poly/allocator/mem.md
Normal file
@@ -0,0 +1,233 @@
|
||||
[mem.poly.allocator.mem]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#mem.poly.allocator.mem)
|
||||
|
||||
### 20.5.3 Class template polymorphic_allocator [[mem.poly.allocator.class]](mem.poly.allocator.class#mem.poly.allocator.mem)
|
||||
|
||||
#### 20.5.3.3 Member functions [mem.poly.allocator.mem]
|
||||
|
||||
[ð](#lib:allocate,polymorphic_allocator)
|
||||
|
||||
`Tp* allocate(size_t n);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7777)
|
||||
|
||||
*Effects*: If numeric_limits<size_t>::max() / sizeof(Tp) < n,
|
||||
throws bad_array_new_length[.](#1.sentence-1)
|
||||
|
||||
Otherwise equivalent to:return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));
|
||||
|
||||
[ð](#lib:deallocate,polymorphic_allocator)
|
||||
|
||||
`void deallocate(Tp* p, size_t n);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7793)
|
||||
|
||||
*Preconditions*: p was allocated from a memory resource x,
|
||||
equal to *memory_rsrc,
|
||||
using x.allocate(n * sizeof(Tp), alignof(Tp))[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7799)
|
||||
|
||||
*Effects*: Equivalent to memory_rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp))[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7803)
|
||||
|
||||
*Throws*: Nothing[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:allocate_bytes,polymorphic_allocator)
|
||||
|
||||
`void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7814)
|
||||
|
||||
*Effects*: Equivalent to: return memory_rsrc->allocate(nbytes, alignment);
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7818)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The return type is void* (rather than, e.g., byte*)
|
||||
to support conversion to an arbitrary pointer type U* by static_cast<U*>, thus facilitating construction of a U object in the allocated memory[.](#6.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:deallocate_bytes,polymorphic_allocator)
|
||||
|
||||
`void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7833)
|
||||
|
||||
*Effects*: Equivalent to memory_rsrc->deallocate(p, nbytes, alignment)[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:allocate_object,polymorphic_allocator)
|
||||
|
||||
`template<class T>
|
||||
T* allocate_object(size_t n = 1);
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7845)
|
||||
|
||||
*Effects*: Allocates memory suitable for holding
|
||||
an array of n objects of type T, as follows:
|
||||
|
||||
- [(8.1)](#8.1)
|
||||
|
||||
if numeric_limits<size_t>::max() / sizeof(T) < n,
|
||||
throws bad_array_new_length,
|
||||
|
||||
- [(8.2)](#8.2)
|
||||
|
||||
otherwise equivalent to:return static_cast<T*>(allocate_bytes(n*sizeof(T), alignof(T)));
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7860)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
T is not deduced and must therefore be provided as a template argument[.](#9.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:deallocate_object,polymorphic_allocator)
|
||||
|
||||
`template<class T>
|
||||
void deallocate_object(T* p, size_t n = 1);
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7873)
|
||||
|
||||
*Effects*: Equivalent to deallocate_bytes(p, n*sizeof(T), alignof(T))[.](#10.sentence-1)
|
||||
|
||||
[ð](#lib:new_object,polymorphic_allocator)
|
||||
|
||||
`template<class T, class... CtorArgs>
|
||||
T* new_object(CtorArgs&&... ctor_args);
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7885)
|
||||
|
||||
*Effects*: Allocates and constructs an object of type T, as follows[.](#11.sentence-1)
|
||||
|
||||
|
||||
Equivalent to:T* p = allocate_object<T>();try { construct(p, std::forward<CtorArgs>(ctor_args)...);} catch (...) { deallocate_object(p); throw;}return p;
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7900)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
T is not deduced and must therefore be provided as a template argument[.](#12.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:new_object,polymorphic_allocator_)
|
||||
|
||||
`template<class T>
|
||||
void delete_object(T* p);
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7913)
|
||||
|
||||
*Effects*: Equivalent to:destroy(p);
|
||||
deallocate_object(p);
|
||||
|
||||
[ð](#lib:construct,polymorphic_allocator)
|
||||
|
||||
`template<class T, class... Args>
|
||||
void construct(T* p, Args&&... args);
|
||||
`
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7929)
|
||||
|
||||
*Mandates*: Uses-allocator construction of T with allocator *this (see [[allocator.uses.construction]](allocator.uses.construction "20.2.8.2 Uses-allocator construction"))
|
||||
and constructor arguments std::forward<Args>(args)... is well-formed[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7935)
|
||||
|
||||
*Effects*: Constructs a T object in the storage
|
||||
whose address is represented by p by uses-allocator construction with allocator *this and constructor arguments std::forward<Args>(args)...[.](#15.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7942)
|
||||
|
||||
*Throws*: Nothing unless the constructor for T throws[.](#16.sentence-1)
|
||||
|
||||
[ð](#lib:destroy,polymorphic_allocator)
|
||||
|
||||
`template<class T>
|
||||
void destroy(T* p);
|
||||
`
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7954)
|
||||
|
||||
*Effects*: Equivalent to p->~T()[.](#17.sentence-1)
|
||||
|
||||
[ð](#lib:select_on_container_copy_construction,polymorphic_allocator)
|
||||
|
||||
`polymorphic_allocator select_on_container_copy_construction() const;
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7965)
|
||||
|
||||
*Returns*: polymorphic_allocator()[.](#18.sentence-1)
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7969)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
The memory resource is not propagated[.](#19.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:resource,polymorphic_allocator)
|
||||
|
||||
`memory_resource* resource() const;
|
||||
`
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7981)
|
||||
|
||||
*Returns*: memory_rsrc[.](#20.sentence-1)
|
||||
1078
cppdraft/mem/res.md
Normal file
1078
cppdraft/mem/res.md
Normal file
File diff suppressed because it is too large
Load Diff
168
cppdraft/mem/res/class.md
Normal file
168
cppdraft/mem/res/class.md
Normal file
@@ -0,0 +1,168 @@
|
||||
[mem.res.class]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#class)
|
||||
|
||||
### 20.5.2 Class memory_resource [mem.res.class]
|
||||
|
||||
#### [20.5.2.1](#general) General [[mem.res.class.general]](mem.res.class.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7484)
|
||||
|
||||
The memory_resource class is an abstract interface to an unbounded set of classes encapsulating memory resources[.](#general-1.sentence-1)
|
||||
|
||||
[ð](#lib:memory_resource)
|
||||
|
||||
namespace std::pmr {class memory_resource {static constexpr size_t max_align = alignof(max_align_t); // *exposition only*public: memory_resource() = default;
|
||||
memory_resource(const memory_resource&) = default; virtual ~memory_resource();
|
||||
|
||||
memory_resource& operator=(const memory_resource&) = default; void* allocate(size_t bytes, size_t alignment = max_align); void deallocate(void* p, size_t bytes, size_t alignment = max_align); bool is_equal(const memory_resource& other) const noexcept; private:virtual void* do_allocate(size_t bytes, size_t alignment) = 0; virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0; virtual bool do_is_equal(const memory_resource& other) const noexcept = 0; };}
|
||||
|
||||
#### [20.5.2.2](#mem.res.public) Public member functions [[mem.res.public]](mem.res.public)
|
||||
|
||||
[ð](#lib:memory_resource,destructor)
|
||||
|
||||
`~memory_resource();
|
||||
`
|
||||
|
||||
[1](#mem.res.public-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7524)
|
||||
|
||||
*Effects*: Destroys this memory_resource[.](#mem.res.public-1.sentence-1)
|
||||
|
||||
[ð](#lib:allocate,memory_resource)
|
||||
|
||||
`void* allocate(size_t bytes, size_t alignment = max_align);
|
||||
`
|
||||
|
||||
[2](#mem.res.public-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7535)
|
||||
|
||||
*Effects*: Allocates storage by calling do_allocate(bytes, alignment) and
|
||||
implicitly creates objects within the allocated region of storage[.](#mem.res.public-2.sentence-1)
|
||||
|
||||
[3](#mem.res.public-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7540)
|
||||
|
||||
*Returns*: A pointer to a suitable created object ([[intro.object]](intro.object "6.8.2 Object model"))
|
||||
in the allocated region of storage[.](#mem.res.public-3.sentence-1)
|
||||
|
||||
[4](#mem.res.public-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7545)
|
||||
|
||||
*Throws*: What and when the call to do_allocate throws[.](#mem.res.public-4.sentence-1)
|
||||
|
||||
[ð](#lib:deallocate,memory_resource)
|
||||
|
||||
`void deallocate(void* p, size_t bytes, size_t alignment = max_align);
|
||||
`
|
||||
|
||||
[5](#mem.res.public-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7556)
|
||||
|
||||
*Effects*: Equivalent to do_deallocate(p, bytes, alignment)[.](#mem.res.public-5.sentence-1)
|
||||
|
||||
[ð](#lib:is_equal,memory_resource)
|
||||
|
||||
`bool is_equal(const memory_resource& other) const noexcept;
|
||||
`
|
||||
|
||||
[6](#mem.res.public-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7567)
|
||||
|
||||
*Effects*: Equivalent to: return do_is_equal(other);
|
||||
|
||||
#### [20.5.2.3](#mem.res.private) Private virtual member functions [[mem.res.private]](mem.res.private)
|
||||
|
||||
[ð](#lib:do_allocate,memory_resource)
|
||||
|
||||
`virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
|
||||
`
|
||||
|
||||
[1](#mem.res.private-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7581)
|
||||
|
||||
*Preconditions*: alignment is a power of two[.](#mem.res.private-1.sentence-1)
|
||||
|
||||
[2](#mem.res.private-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7585)
|
||||
|
||||
*Returns*: A derived class shall implement this function to
|
||||
return a pointer to allocated storage ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2 Allocation functions"))
|
||||
with a size of at least bytes,
|
||||
aligned to the specified alignment[.](#mem.res.private-2.sentence-1)
|
||||
|
||||
[3](#mem.res.private-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7592)
|
||||
|
||||
*Throws*: A derived class implementation shall throw an appropriate exception if it is unable to allocate memory with the requested size and alignment[.](#mem.res.private-3.sentence-1)
|
||||
|
||||
[ð](#lib:do_deallocate,memory_resource)
|
||||
|
||||
`virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;
|
||||
`
|
||||
|
||||
[4](#mem.res.private-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7603)
|
||||
|
||||
*Preconditions*: p was returned from a prior call to allocate(bytes, alignment) on a memory resource equal to *this,
|
||||
and the storage at p has not yet been deallocated[.](#mem.res.private-4.sentence-1)
|
||||
|
||||
[5](#mem.res.private-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7609)
|
||||
|
||||
*Effects*: A derived class shall implement this function to dispose of allocated storage[.](#mem.res.private-5.sentence-1)
|
||||
|
||||
[6](#mem.res.private-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7613)
|
||||
|
||||
*Throws*: Nothing[.](#mem.res.private-6.sentence-1)
|
||||
|
||||
[ð](#lib:do_is_equal,memory_resource)
|
||||
|
||||
`virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
|
||||
`
|
||||
|
||||
[7](#mem.res.private-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7624)
|
||||
|
||||
*Returns*: A derived class shall implement this function to return true if memory allocated from *this can be deallocated from other and vice-versa,
|
||||
otherwise false[.](#mem.res.private-7.sentence-1)
|
||||
|
||||
[*Note [1](#mem.res.private-note-1)*:
|
||||
|
||||
It is possible that the most-derived type of other does not match the type of *this[.](#mem.res.private-7.sentence-2)
|
||||
|
||||
For a derived class D, an implementation of this function
|
||||
can immediately return false if dynamic_cast<const D*>(&other) == nullptr[.](#mem.res.private-7.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [20.5.2.4](#mem.res.eq) Equality [[mem.res.eq]](mem.res.eq)
|
||||
|
||||
[ð](#lib:operator==,memory_resource)
|
||||
|
||||
`bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
|
||||
`
|
||||
|
||||
[1](#mem.res.eq-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7644)
|
||||
|
||||
*Returns*: &a == &b || a.is_equal(b)[.](#mem.res.eq-1.sentence-1)
|
||||
22
cppdraft/mem/res/class/general.md
Normal file
22
cppdraft/mem/res/class/general.md
Normal file
@@ -0,0 +1,22 @@
|
||||
[mem.res.class.general]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#class.general)
|
||||
|
||||
### 20.5.2 Class memory_resource [[mem.res.class]](mem.res.class#general)
|
||||
|
||||
#### 20.5.2.1 General [mem.res.class.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7484)
|
||||
|
||||
The memory_resource class is an abstract interface to an unbounded set of classes encapsulating memory resources[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:memory_resource)
|
||||
|
||||
namespace std::pmr {class memory_resource {static constexpr size_t max_align = alignof(max_align_t); // *exposition only*public: memory_resource() = default;
|
||||
memory_resource(const memory_resource&) = default; virtual ~memory_resource();
|
||||
|
||||
memory_resource& operator=(const memory_resource&) = default; void* allocate(size_t bytes, size_t alignment = max_align); void deallocate(void* p, size_t bytes, size_t alignment = max_align); bool is_equal(const memory_resource& other) const noexcept; private:virtual void* do_allocate(size_t bytes, size_t alignment) = 0; virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0; virtual bool do_is_equal(const memory_resource& other) const noexcept = 0; };}
|
||||
20
cppdraft/mem/res/eq.md
Normal file
20
cppdraft/mem/res/eq.md
Normal file
@@ -0,0 +1,20 @@
|
||||
[mem.res.eq]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#eq)
|
||||
|
||||
### 20.5.2 Class memory_resource [[mem.res.class]](mem.res.class#mem.res.eq)
|
||||
|
||||
#### 20.5.2.4 Equality [mem.res.eq]
|
||||
|
||||
[ð](#lib:operator==,memory_resource)
|
||||
|
||||
`bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7644)
|
||||
|
||||
*Returns*: &a == &b || a.is_equal(b)[.](#1.sentence-1)
|
||||
89
cppdraft/mem/res/global.md
Normal file
89
cppdraft/mem/res/global.md
Normal file
@@ -0,0 +1,89 @@
|
||||
[mem.res.global]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#global)
|
||||
|
||||
### 20.5.4 Access to program-wide memory_resource objects [mem.res.global]
|
||||
|
||||
[ð](#lib:new_delete_resource)
|
||||
|
||||
`memory_resource* new_delete_resource() noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8009)
|
||||
|
||||
*Returns*: A pointer to a static-duration object of a type derived from memory_resource that can serve as a resource for allocating memory
|
||||
using ::operator new and ::operator delete[.](#1.sentence-1)
|
||||
|
||||
The same value is returned every time this function is called[.](#1.sentence-2)
|
||||
|
||||
For a return value p and a memory resource r,p->is_equal(r) returns &r == p[.](#1.sentence-3)
|
||||
|
||||
[ð](#lib:null_memory_resource)
|
||||
|
||||
`memory_resource* null_memory_resource() noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8025)
|
||||
|
||||
*Returns*: A pointer to a static-duration object of a type derived from memory_resource for which allocate() always throws bad_alloc and
|
||||
for which deallocate() has no effect[.](#2.sentence-1)
|
||||
|
||||
The same value is returned every time this function is called[.](#2.sentence-2)
|
||||
|
||||
For a return value p and a memory resource r,p->is_equal(r) returns &r == p[.](#2.sentence-3)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8035)
|
||||
|
||||
The [*default memory resource pointer*](#def:default_memory_resource_pointer "20.5.4 Access to program-wide memory_resource objects [mem.res.global]") is a pointer to a memory resource
|
||||
that is used by certain facilities when an explicit memory resource
|
||||
is not supplied through the interface[.](#3.sentence-1)
|
||||
|
||||
Its initial value is the return value of new_delete_resource()[.](#3.sentence-2)
|
||||
|
||||
[ð](#lib:set_default_resource)
|
||||
|
||||
`memory_resource* set_default_resource(memory_resource* r) noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8047)
|
||||
|
||||
*Effects*: If r is non-null,
|
||||
sets the value of the default memory resource pointer to r,
|
||||
otherwise sets the default memory resource pointer to new_delete_resource()[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8053)
|
||||
|
||||
*Returns*: The previous value of the default memory resource pointer[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8057)
|
||||
|
||||
*Remarks*: Calling the set_default_resource andget_default_resource functions shall not incur a data race ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#6.sentence-1)
|
||||
|
||||
A call to the set_default_resource function
|
||||
synchronizes with subsequent calls to
|
||||
the set_default_resource and get_default_resource functions[.](#6.sentence-2)
|
||||
|
||||
[ð](#lib:get_default_resource)
|
||||
|
||||
`memory_resource* get_default_resource() noexcept;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8072)
|
||||
|
||||
*Returns*: The current value of the default memory resource pointer[.](#7.sentence-1)
|
||||
189
cppdraft/mem/res/monotonic/buffer.md
Normal file
189
cppdraft/mem/res/monotonic/buffer.md
Normal file
@@ -0,0 +1,189 @@
|
||||
[mem.res.monotonic.buffer]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#monotonic.buffer)
|
||||
|
||||
### 20.5.6 Class monotonic_buffer_resource [mem.res.monotonic.buffer]
|
||||
|
||||
#### [20.5.6.1](#general) General [[mem.res.monotonic.buffer.general]](mem.res.monotonic.buffer.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8395)
|
||||
|
||||
A monotonic_buffer_resource is a special-purpose memory resource
|
||||
intended for very fast memory allocations in situations
|
||||
where memory is used to build up a few objects
|
||||
and then is released all at once when the memory resource object is destroyed[.](#general-1.sentence-1)
|
||||
|
||||
[ð](#lib:monotonic_buffer_resource)
|
||||
|
||||
namespace std::pmr {class monotonic_buffer_resource : public memory_resource { memory_resource* upstream_rsrc; // *exposition only*void* current_buffer; // *exposition only* size_t next_buffer_size; // *exposition only*public:explicit monotonic_buffer_resource(memory_resource* upstream);
|
||||
monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
|
||||
monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
|
||||
|
||||
monotonic_buffer_resource(): monotonic_buffer_resource(get_default_resource()) {}explicit monotonic_buffer_resource(size_t initial_size): monotonic_buffer_resource(initial_size, get_default_resource()) {} monotonic_buffer_resource(void* buffer, size_t buffer_size): monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {} monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; virtual ~monotonic_buffer_resource();
|
||||
|
||||
monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete; void release();
|
||||
memory_resource* upstream_resource() const; protected:void* do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; };}
|
||||
|
||||
#### [20.5.6.2](#ctor) Constructors and destructor [[mem.res.monotonic.buffer.ctor]](mem.res.monotonic.buffer.ctor)
|
||||
|
||||
[ð](#lib:monotonic_buffer_resource,constructor)
|
||||
|
||||
`explicit monotonic_buffer_resource(memory_resource* upstream);
|
||||
monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
|
||||
`
|
||||
|
||||
[1](#ctor-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8448)
|
||||
|
||||
*Preconditions*: upstream is the address of a valid memory resource[.](#ctor-1.sentence-1)
|
||||
|
||||
initial_size, if specified, is greater than zero[.](#ctor-1.sentence-2)
|
||||
|
||||
[2](#ctor-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8453)
|
||||
|
||||
*Effects*: Sets upstream_rsrc to upstream andcurrent_buffer to nullptr[.](#ctor-2.sentence-1)
|
||||
|
||||
If initial_size is specified,
|
||||
sets next_buffer_size to at least initial_size;
|
||||
otherwise sets next_buffer_size to animplementation-defined size[.](#ctor-2.sentence-2)
|
||||
|
||||
[ð](#lib:monotonic_buffer_resource,constructor_)
|
||||
|
||||
`monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
|
||||
`
|
||||
|
||||
[3](#ctor-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8469)
|
||||
|
||||
*Preconditions*: upstream is the address of a valid memory resource[.](#ctor-3.sentence-1)
|
||||
|
||||
buffer_size is no larger than the number of bytes in buffer[.](#ctor-3.sentence-2)
|
||||
|
||||
[4](#ctor-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8474)
|
||||
|
||||
*Effects*: Sets upstream_rsrc to upstream,current_buffer to buffer, andnext_buffer_size to buffer_size (but not less than 1),
|
||||
then increases next_buffer_size by an implementation-defined growth factor (which need not be integral)[.](#ctor-4.sentence-1)
|
||||
|
||||
[ð](#lib:monotonic_buffer_resource,destructor)
|
||||
|
||||
`~monotonic_buffer_resource();
|
||||
`
|
||||
|
||||
[5](#ctor-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8489)
|
||||
|
||||
*Effects*: Calls release()[.](#ctor-5.sentence-1)
|
||||
|
||||
#### [20.5.6.3](#mem) Members [[mem.res.monotonic.buffer.mem]](mem.res.monotonic.buffer.mem)
|
||||
|
||||
[ð](#lib:release,monotonic_buffer_resource)
|
||||
|
||||
`void release();
|
||||
`
|
||||
|
||||
[1](#mem-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8503)
|
||||
|
||||
*Effects*: Calls upstream_rsrc->deallocate() as necessary
|
||||
to release all allocated memory[.](#mem-1.sentence-1)
|
||||
|
||||
Resets current_buffer and next_buffer_size to their initial values at construction[.](#mem-1.sentence-2)
|
||||
|
||||
[2](#mem-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8510)
|
||||
|
||||
[*Note [1](#mem-note-1)*:
|
||||
|
||||
The memory is released back to upstream_rsrc even if some blocks that were allocated from *this have not been deallocated from *this[.](#mem-2.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:upstream_resource,monotonic_buffer_resource)
|
||||
|
||||
`memory_resource* upstream_resource() const;
|
||||
`
|
||||
|
||||
[3](#mem-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8524)
|
||||
|
||||
*Returns*: The value of upstream_rsrc[.](#mem-3.sentence-1)
|
||||
|
||||
[ð](#lib:do_allocate,monotonic_buffer_resource)
|
||||
|
||||
`void* do_allocate(size_t bytes, size_t alignment) override;
|
||||
`
|
||||
|
||||
[4](#mem-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8535)
|
||||
|
||||
*Effects*: If the unused space in current_buffer can fit a block with the specified bytes and alignment,
|
||||
then allocate the return block from current_buffer;
|
||||
otherwise set current_buffer to upstream_rsrc->allocate(n, m),
|
||||
where n is not less than max(bytes, next_buffer_size) andm is not less than alignment,
|
||||
and increase next_buffer_size by an implementation-defined growth factor (which need not be integral),
|
||||
then allocate the return block from the newly-allocated current_buffer[.](#mem-4.sentence-1)
|
||||
|
||||
[5](#mem-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8547)
|
||||
|
||||
*Returns*: A pointer to allocated storage ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2 Allocation functions"))
|
||||
with a size of at least bytes[.](#mem-5.sentence-1)
|
||||
|
||||
The size and alignment of the allocated memory shall meet the requirements
|
||||
for a class derived from memory_resource ([[mem.res.class]](mem.res.class "20.5.2 Class memory_resource"))[.](#mem-5.sentence-2)
|
||||
|
||||
[6](#mem-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8554)
|
||||
|
||||
*Throws*: Nothing unless upstream_rsrc->allocate() throws[.](#mem-6.sentence-1)
|
||||
|
||||
[ð](#lib:do_deallocate,monotonic_buffer_resource)
|
||||
|
||||
`void do_deallocate(void* p, size_t bytes, size_t alignment) override;
|
||||
`
|
||||
|
||||
[7](#mem-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8565)
|
||||
|
||||
*Effects*: None[.](#mem-7.sentence-1)
|
||||
|
||||
[8](#mem-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8569)
|
||||
|
||||
*Throws*: Nothing[.](#mem-8.sentence-1)
|
||||
|
||||
[9](#mem-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8573)
|
||||
|
||||
*Remarks*: Memory used by this resource increases monotonically until its destruction[.](#mem-9.sentence-1)
|
||||
|
||||
[ð](#lib:do_is_equal,monotonic_buffer_resource)
|
||||
|
||||
`bool do_is_equal(const memory_resource& other) const noexcept override;
|
||||
`
|
||||
|
||||
[10](#mem-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8584)
|
||||
|
||||
*Returns*: this == &other[.](#mem-10.sentence-1)
|
||||
64
cppdraft/mem/res/monotonic/buffer/ctor.md
Normal file
64
cppdraft/mem/res/monotonic/buffer/ctor.md
Normal file
@@ -0,0 +1,64 @@
|
||||
[mem.res.monotonic.buffer.ctor]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#monotonic.buffer.ctor)
|
||||
|
||||
### 20.5.6 Class monotonic_buffer_resource [[mem.res.monotonic.buffer]](mem.res.monotonic.buffer#ctor)
|
||||
|
||||
#### 20.5.6.2 Constructors and destructor [mem.res.monotonic.buffer.ctor]
|
||||
|
||||
[ð](#lib:monotonic_buffer_resource,constructor)
|
||||
|
||||
`explicit monotonic_buffer_resource(memory_resource* upstream);
|
||||
monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8448)
|
||||
|
||||
*Preconditions*: upstream is the address of a valid memory resource[.](#1.sentence-1)
|
||||
|
||||
initial_size, if specified, is greater than zero[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8453)
|
||||
|
||||
*Effects*: Sets upstream_rsrc to upstream andcurrent_buffer to nullptr[.](#2.sentence-1)
|
||||
|
||||
If initial_size is specified,
|
||||
sets next_buffer_size to at least initial_size;
|
||||
otherwise sets next_buffer_size to animplementation-defined size[.](#2.sentence-2)
|
||||
|
||||
[ð](#lib:monotonic_buffer_resource,constructor_)
|
||||
|
||||
`monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8469)
|
||||
|
||||
*Preconditions*: upstream is the address of a valid memory resource[.](#3.sentence-1)
|
||||
|
||||
buffer_size is no larger than the number of bytes in buffer[.](#3.sentence-2)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8474)
|
||||
|
||||
*Effects*: Sets upstream_rsrc to upstream,current_buffer to buffer, andnext_buffer_size to buffer_size (but not less than 1),
|
||||
then increases next_buffer_size by an implementation-defined growth factor (which need not be integral)[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:monotonic_buffer_resource,destructor)
|
||||
|
||||
`~monotonic_buffer_resource();
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8489)
|
||||
|
||||
*Effects*: Calls release()[.](#5.sentence-1)
|
||||
29
cppdraft/mem/res/monotonic/buffer/general.md
Normal file
29
cppdraft/mem/res/monotonic/buffer/general.md
Normal file
@@ -0,0 +1,29 @@
|
||||
[mem.res.monotonic.buffer.general]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#monotonic.buffer.general)
|
||||
|
||||
### 20.5.6 Class monotonic_buffer_resource [[mem.res.monotonic.buffer]](mem.res.monotonic.buffer#general)
|
||||
|
||||
#### 20.5.6.1 General [mem.res.monotonic.buffer.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8395)
|
||||
|
||||
A monotonic_buffer_resource is a special-purpose memory resource
|
||||
intended for very fast memory allocations in situations
|
||||
where memory is used to build up a few objects
|
||||
and then is released all at once when the memory resource object is destroyed[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:monotonic_buffer_resource)
|
||||
|
||||
namespace std::pmr {class monotonic_buffer_resource : public memory_resource { memory_resource* upstream_rsrc; // *exposition only*void* current_buffer; // *exposition only* size_t next_buffer_size; // *exposition only*public:explicit monotonic_buffer_resource(memory_resource* upstream);
|
||||
monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
|
||||
monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
|
||||
|
||||
monotonic_buffer_resource(): monotonic_buffer_resource(get_default_resource()) {}explicit monotonic_buffer_resource(size_t initial_size): monotonic_buffer_resource(initial_size, get_default_resource()) {} monotonic_buffer_resource(void* buffer, size_t buffer_size): monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {} monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; virtual ~monotonic_buffer_resource();
|
||||
|
||||
monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete; void release();
|
||||
memory_resource* upstream_resource() const; protected:void* do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; };}
|
||||
110
cppdraft/mem/res/monotonic/buffer/mem.md
Normal file
110
cppdraft/mem/res/monotonic/buffer/mem.md
Normal file
@@ -0,0 +1,110 @@
|
||||
[mem.res.monotonic.buffer.mem]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#monotonic.buffer.mem)
|
||||
|
||||
### 20.5.6 Class monotonic_buffer_resource [[mem.res.monotonic.buffer]](mem.res.monotonic.buffer#mem)
|
||||
|
||||
#### 20.5.6.3 Members [mem.res.monotonic.buffer.mem]
|
||||
|
||||
[ð](#lib:release,monotonic_buffer_resource)
|
||||
|
||||
`void release();
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8503)
|
||||
|
||||
*Effects*: Calls upstream_rsrc->deallocate() as necessary
|
||||
to release all allocated memory[.](#1.sentence-1)
|
||||
|
||||
Resets current_buffer and next_buffer_size to their initial values at construction[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8510)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The memory is released back to upstream_rsrc even if some blocks that were allocated from *this have not been deallocated from *this[.](#2.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:upstream_resource,monotonic_buffer_resource)
|
||||
|
||||
`memory_resource* upstream_resource() const;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8524)
|
||||
|
||||
*Returns*: The value of upstream_rsrc[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:do_allocate,monotonic_buffer_resource)
|
||||
|
||||
`void* do_allocate(size_t bytes, size_t alignment) override;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8535)
|
||||
|
||||
*Effects*: If the unused space in current_buffer can fit a block with the specified bytes and alignment,
|
||||
then allocate the return block from current_buffer;
|
||||
otherwise set current_buffer to upstream_rsrc->allocate(n, m),
|
||||
where n is not less than max(bytes, next_buffer_size) andm is not less than alignment,
|
||||
and increase next_buffer_size by an implementation-defined growth factor (which need not be integral),
|
||||
then allocate the return block from the newly-allocated current_buffer[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8547)
|
||||
|
||||
*Returns*: A pointer to allocated storage ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2 Allocation functions"))
|
||||
with a size of at least bytes[.](#5.sentence-1)
|
||||
|
||||
The size and alignment of the allocated memory shall meet the requirements
|
||||
for a class derived from memory_resource ([[mem.res.class]](mem.res.class "20.5.2 Class memory_resource"))[.](#5.sentence-2)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8554)
|
||||
|
||||
*Throws*: Nothing unless upstream_rsrc->allocate() throws[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:do_deallocate,monotonic_buffer_resource)
|
||||
|
||||
`void do_deallocate(void* p, size_t bytes, size_t alignment) override;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8565)
|
||||
|
||||
*Effects*: None[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8569)
|
||||
|
||||
*Throws*: Nothing[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8573)
|
||||
|
||||
*Remarks*: Memory used by this resource increases monotonically until its destruction[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:do_is_equal,monotonic_buffer_resource)
|
||||
|
||||
`bool do_is_equal(const memory_resource& other) const noexcept override;
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8584)
|
||||
|
||||
*Returns*: this == &other[.](#10.sentence-1)
|
||||
302
cppdraft/mem/res/pool.md
Normal file
302
cppdraft/mem/res/pool.md
Normal file
@@ -0,0 +1,302 @@
|
||||
[mem.res.pool]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#pool)
|
||||
|
||||
### 20.5.5 Pool resource classes [mem.res.pool]
|
||||
|
||||
#### [20.5.5.1](#overview) Classes synchronized_pool_resource and unsynchronized_pool_resource [[mem.res.pool.overview]](mem.res.pool.overview)
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8081)
|
||||
|
||||
The synchronized_pool_resource andunsynchronized_pool_resource classes
|
||||
(collectively called [*pool resource classes*](#def:pool_resource_classes "20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]"))
|
||||
are general-purpose memory resources having the following qualities:
|
||||
|
||||
- [(1.1)](#overview-1.1)
|
||||
|
||||
Each resource frees its allocated memory on destruction,
|
||||
even if deallocate has not been called for some of the allocated blocks[.](#overview-1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#overview-1.2)
|
||||
|
||||
A pool resource consists of a collection of [*pools*](#def:pools "20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]"),
|
||||
serving requests for different block sizes[.](#overview-1.2.sentence-1)
|
||||
Each individual pool manages a collection of [*chunks*](#def:chunks "20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]") that are in turn divided into blocks of uniform size,
|
||||
returned via calls to do_allocate[.](#overview-1.2.sentence-2)
|
||||
Each call to do_allocate(size, alignment) is dispatched
|
||||
to the pool serving the smallest blocks accommodating at least size bytes[.](#overview-1.2.sentence-3)
|
||||
|
||||
- [(1.3)](#overview-1.3)
|
||||
|
||||
When a particular pool is exhausted,
|
||||
allocating a block from that pool results in the allocation
|
||||
of an additional chunk of memory from the [*upstream allocator*](#def:upstream_allocator "20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]") (supplied at construction), thus replenishing the pool[.](#overview-1.3.sentence-1)
|
||||
With each successive replenishment,
|
||||
the chunk size obtained increases geometrically[.](#overview-1.3.sentence-2)
|
||||
[*Note [1](#overview-note-1)*:
|
||||
By allocating memory in chunks,
|
||||
the pooling strategy increases the chance that consecutive allocations
|
||||
will be close together in memory[.](#overview-1.3.sentence-3)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#overview-1.4)
|
||||
|
||||
Allocation requests that exceed the largest block size of any pool
|
||||
are fulfilled directly from the upstream allocator[.](#overview-1.4.sentence-1)
|
||||
|
||||
- [(1.5)](#overview-1.5)
|
||||
|
||||
A pool_options struct may be passed to the pool resource constructors
|
||||
to tune the largest block size and the maximum chunk size[.](#overview-1.5.sentence-1)
|
||||
|
||||
[2](#overview-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8118)
|
||||
|
||||
A synchronized_pool_resource may be accessed from multiple threads
|
||||
without external synchronization
|
||||
and may have thread-specific pools to reduce synchronization costs[.](#overview-2.sentence-1)
|
||||
|
||||
An unsynchronized_pool_resource class may not be accessed
|
||||
from multiple threads simultaneously
|
||||
and thus avoids the cost of synchronization entirely
|
||||
in single-threaded applications[.](#overview-2.sentence-2)
|
||||
|
||||
[ð](#lib:pool_options)
|
||||
|
||||
namespace std::pmr {struct pool_options { size_t max_blocks_per_chunk = 0;
|
||||
size_t largest_required_pool_block = 0; }; class synchronized_pool_resource : public memory_resource {public: synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
|
||||
|
||||
synchronized_pool_resource(): synchronized_pool_resource(pool_options(), get_default_resource()) {}explicit synchronized_pool_resource(memory_resource* upstream): synchronized_pool_resource(pool_options(), upstream) {}explicit synchronized_pool_resource(const pool_options& opts): synchronized_pool_resource(opts, get_default_resource()) {} synchronized_pool_resource(const synchronized_pool_resource&) = delete; virtual ~synchronized_pool_resource();
|
||||
|
||||
synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete; void release();
|
||||
memory_resource* upstream_resource() const;
|
||||
pool_options options() const; protected:void* do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; }; class unsynchronized_pool_resource : public memory_resource {public: unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
|
||||
|
||||
unsynchronized_pool_resource(): unsynchronized_pool_resource(pool_options(), get_default_resource()) {}explicit unsynchronized_pool_resource(memory_resource* upstream): unsynchronized_pool_resource(pool_options(), upstream) {}explicit unsynchronized_pool_resource(const pool_options& opts): unsynchronized_pool_resource(opts, get_default_resource()) {} unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete; virtual ~unsynchronized_pool_resource();
|
||||
|
||||
unsynchronized_pool_resource& operator=(const unsynchronized_pool_resource&) = delete; void release();
|
||||
memory_resource* upstream_resource() const;
|
||||
pool_options options() const; protected:void* do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; };}
|
||||
|
||||
#### [20.5.5.2](#options) pool_options data members [[mem.res.pool.options]](mem.res.pool.options)
|
||||
|
||||
[1](#options-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8195)
|
||||
|
||||
The members of pool_options comprise a set of constructor options for pool resources[.](#options-1.sentence-1)
|
||||
|
||||
The effect of each option on the pool resource behavior is described below:
|
||||
|
||||
[ð](#lib:pool_options,max_blocks_per_chunk)
|
||||
|
||||
`size_t max_blocks_per_chunk;
|
||||
`
|
||||
|
||||
[2](#options-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8206)
|
||||
|
||||
The maximum number of blocks that will be allocated at once
|
||||
from the upstream memory resource ([[mem.res.monotonic.buffer]](mem.res.monotonic.buffer "20.5.6 Class monotonic_buffer_resource"))
|
||||
to replenish a pool[.](#options-2.sentence-1)
|
||||
|
||||
If the value of max_blocks_per_chunk is zero or
|
||||
is greater than an implementation-defined
|
||||
limit, that limit is used instead[.](#options-2.sentence-2)
|
||||
|
||||
The implementation
|
||||
may choose to use a smaller value than is specified in this member and
|
||||
may use different values for different pools[.](#options-2.sentence-3)
|
||||
|
||||
[ð](#lib:pool_options,largest_required_pool_block)
|
||||
|
||||
`size_t largest_required_pool_block;
|
||||
`
|
||||
|
||||
[3](#options-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8224)
|
||||
|
||||
The largest allocation size that is required to be fulfilled
|
||||
using the pooling mechanism[.](#options-3.sentence-1)
|
||||
|
||||
Attempts to allocate a single block larger than this threshold
|
||||
will be allocated directly from the upstream memory resource[.](#options-3.sentence-2)
|
||||
|
||||
If largest_required_pool_block is zero or
|
||||
is greater than an implementation-defined
|
||||
limit, that limit is used instead[.](#options-3.sentence-3)
|
||||
|
||||
The implementation may choose a pass-through threshold
|
||||
larger than specified in this member[.](#options-3.sentence-4)
|
||||
|
||||
#### [20.5.5.3](#ctor) Constructors and destructors [[mem.res.pool.ctor]](mem.res.pool.ctor)
|
||||
|
||||
[ð](#lib:synchronized_pool_resource,constructor)
|
||||
|
||||
`synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
|
||||
unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
|
||||
`
|
||||
|
||||
[1](#ctor-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8246)
|
||||
|
||||
*Preconditions*: upstream is the address of a valid memory resource[.](#ctor-1.sentence-1)
|
||||
|
||||
[2](#ctor-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8250)
|
||||
|
||||
*Effects*: Constructs a pool resource object that will obtain memory from upstream whenever the pool resource is unable to satisfy a memory request
|
||||
from its own internal data structures[.](#ctor-2.sentence-1)
|
||||
|
||||
The resulting object will hold a copy of upstream,
|
||||
but will not own the resource to which upstream points[.](#ctor-2.sentence-2)
|
||||
|
||||
[*Note [1](#ctor-note-1)*:
|
||||
|
||||
The intention is that calls to upstream->allocate() will be substantially fewer than calls to this->allocate() in most cases[.](#ctor-2.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The behavior of the pooling mechanism is tuned
|
||||
according to the value of the opts argument[.](#ctor-2.sentence-4)
|
||||
|
||||
[3](#ctor-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8265)
|
||||
|
||||
*Throws*: Nothing unless upstream->allocate() throws[.](#ctor-3.sentence-1)
|
||||
|
||||
It is unspecified if, or under what conditions,
|
||||
this constructor calls upstream->allocate()[.](#ctor-3.sentence-2)
|
||||
|
||||
[ð](#lib:synchronized_pool_resource,destructor)
|
||||
|
||||
`virtual ~synchronized_pool_resource();
|
||||
virtual ~unsynchronized_pool_resource();
|
||||
`
|
||||
|
||||
[4](#ctor-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8280)
|
||||
|
||||
*Effects*: Calls release()[.](#ctor-4.sentence-1)
|
||||
|
||||
#### [20.5.5.4](#mem) Members [[mem.res.pool.mem]](mem.res.pool.mem)
|
||||
|
||||
[ð](#lib:release,synchronized_pool_resource)
|
||||
|
||||
`void release();
|
||||
`
|
||||
|
||||
[1](#mem-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8294)
|
||||
|
||||
*Effects*: Calls upstream_resource()->deallocate() as necessary
|
||||
to release all allocated memory[.](#mem-1.sentence-1)
|
||||
|
||||
[*Note [1](#mem-note-1)*:
|
||||
|
||||
The memory is released back to upstream_resource() even if deallocate has not been called
|
||||
for some of the allocated blocks[.](#mem-1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:upstream_resource,synchronized_pool_resource)
|
||||
|
||||
`memory_resource* upstream_resource() const;
|
||||
`
|
||||
|
||||
[2](#mem-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8312)
|
||||
|
||||
*Returns*: The value of the upstream argument
|
||||
provided to the constructor of this object[.](#mem-2.sentence-1)
|
||||
|
||||
[ð](#lib:options,synchronized_pool_resource)
|
||||
|
||||
`pool_options options() const;
|
||||
`
|
||||
|
||||
[3](#mem-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8325)
|
||||
|
||||
*Returns*: The options that control the pooling behavior of this resource[.](#mem-3.sentence-1)
|
||||
|
||||
The values in the returned struct may differ
|
||||
from those supplied to the pool resource constructor in that
|
||||
values of zero will be replaced with implementation-defined
|
||||
defaults, and sizes may be rounded to unspecified granularity[.](#mem-3.sentence-2)
|
||||
|
||||
[ð](#lib:do_allocate,synchronized_pool_resource)
|
||||
|
||||
`void* do_allocate(size_t bytes, size_t alignment) override;
|
||||
`
|
||||
|
||||
[4](#mem-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8341)
|
||||
|
||||
*Effects*: If the pool selected for a block of size bytes is unable to satisfy the memory request from its own internal data structures,
|
||||
it will call upstream_resource()->allocate() to obtain more memory[.](#mem-4.sentence-1)
|
||||
|
||||
If bytes is larger than that which the largest pool can handle,
|
||||
then memory will be allocated using upstream_resource()->allocate()[.](#mem-4.sentence-2)
|
||||
|
||||
[5](#mem-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8349)
|
||||
|
||||
*Returns*: A pointer to allocated storage ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2 Allocation functions"))
|
||||
with a size of at least bytes[.](#mem-5.sentence-1)
|
||||
|
||||
The size and alignment of the allocated memory shall meet the requirements
|
||||
for a class derived from memory_resource ([[mem.res.class]](mem.res.class "20.5.2 Class memory_resource"))[.](#mem-5.sentence-2)
|
||||
|
||||
[6](#mem-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8356)
|
||||
|
||||
*Throws*: Nothing unless upstream_resource()->allocate() throws[.](#mem-6.sentence-1)
|
||||
|
||||
[ð](#lib:do_deallocate,synchronized_pool_resource)
|
||||
|
||||
`void do_deallocate(void* p, size_t bytes, size_t alignment) override;
|
||||
`
|
||||
|
||||
[7](#mem-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8368)
|
||||
|
||||
*Effects*: Returns the memory at p to the pool[.](#mem-7.sentence-1)
|
||||
|
||||
It is unspecified if, or under what circumstances,
|
||||
this operation will result in a call to upstream_resource()->deallocate()[.](#mem-7.sentence-2)
|
||||
|
||||
[8](#mem-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8374)
|
||||
|
||||
*Throws*: Nothing[.](#mem-8.sentence-1)
|
||||
|
||||
[ð](#lib:do_is_equal,synchronized_pool_resource)
|
||||
|
||||
`bool do_is_equal(const memory_resource& other) const noexcept override;
|
||||
`
|
||||
|
||||
[9](#mem-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8386)
|
||||
|
||||
*Returns*: this == &other[.](#mem-9.sentence-1)
|
||||
61
cppdraft/mem/res/pool/ctor.md
Normal file
61
cppdraft/mem/res/pool/ctor.md
Normal file
@@ -0,0 +1,61 @@
|
||||
[mem.res.pool.ctor]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#pool.ctor)
|
||||
|
||||
### 20.5.5 Pool resource classes [[mem.res.pool]](mem.res.pool#ctor)
|
||||
|
||||
#### 20.5.5.3 Constructors and destructors [mem.res.pool.ctor]
|
||||
|
||||
[ð](#lib:synchronized_pool_resource,constructor)
|
||||
|
||||
`synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
|
||||
unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8246)
|
||||
|
||||
*Preconditions*: upstream is the address of a valid memory resource[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8250)
|
||||
|
||||
*Effects*: Constructs a pool resource object that will obtain memory from upstream whenever the pool resource is unable to satisfy a memory request
|
||||
from its own internal data structures[.](#2.sentence-1)
|
||||
|
||||
The resulting object will hold a copy of upstream,
|
||||
but will not own the resource to which upstream points[.](#2.sentence-2)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The intention is that calls to upstream->allocate() will be substantially fewer than calls to this->allocate() in most cases[.](#2.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The behavior of the pooling mechanism is tuned
|
||||
according to the value of the opts argument[.](#2.sentence-4)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8265)
|
||||
|
||||
*Throws*: Nothing unless upstream->allocate() throws[.](#3.sentence-1)
|
||||
|
||||
It is unspecified if, or under what conditions,
|
||||
this constructor calls upstream->allocate()[.](#3.sentence-2)
|
||||
|
||||
[ð](#lib:synchronized_pool_resource,destructor)
|
||||
|
||||
`virtual ~synchronized_pool_resource();
|
||||
virtual ~unsynchronized_pool_resource();
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8280)
|
||||
|
||||
*Effects*: Calls release()[.](#4.sentence-1)
|
||||
118
cppdraft/mem/res/pool/mem.md
Normal file
118
cppdraft/mem/res/pool/mem.md
Normal file
@@ -0,0 +1,118 @@
|
||||
[mem.res.pool.mem]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#pool.mem)
|
||||
|
||||
### 20.5.5 Pool resource classes [[mem.res.pool]](mem.res.pool#mem)
|
||||
|
||||
#### 20.5.5.4 Members [mem.res.pool.mem]
|
||||
|
||||
[ð](#lib:release,synchronized_pool_resource)
|
||||
|
||||
`void release();
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8294)
|
||||
|
||||
*Effects*: Calls upstream_resource()->deallocate() as necessary
|
||||
to release all allocated memory[.](#1.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The memory is released back to upstream_resource() even if deallocate has not been called
|
||||
for some of the allocated blocks[.](#1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:upstream_resource,synchronized_pool_resource)
|
||||
|
||||
`memory_resource* upstream_resource() const;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8312)
|
||||
|
||||
*Returns*: The value of the upstream argument
|
||||
provided to the constructor of this object[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:options,synchronized_pool_resource)
|
||||
|
||||
`pool_options options() const;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8325)
|
||||
|
||||
*Returns*: The options that control the pooling behavior of this resource[.](#3.sentence-1)
|
||||
|
||||
The values in the returned struct may differ
|
||||
from those supplied to the pool resource constructor in that
|
||||
values of zero will be replaced with implementation-defined
|
||||
defaults, and sizes may be rounded to unspecified granularity[.](#3.sentence-2)
|
||||
|
||||
[ð](#lib:do_allocate,synchronized_pool_resource)
|
||||
|
||||
`void* do_allocate(size_t bytes, size_t alignment) override;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8341)
|
||||
|
||||
*Effects*: If the pool selected for a block of size bytes is unable to satisfy the memory request from its own internal data structures,
|
||||
it will call upstream_resource()->allocate() to obtain more memory[.](#4.sentence-1)
|
||||
|
||||
If bytes is larger than that which the largest pool can handle,
|
||||
then memory will be allocated using upstream_resource()->allocate()[.](#4.sentence-2)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8349)
|
||||
|
||||
*Returns*: A pointer to allocated storage ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2 Allocation functions"))
|
||||
with a size of at least bytes[.](#5.sentence-1)
|
||||
|
||||
The size and alignment of the allocated memory shall meet the requirements
|
||||
for a class derived from memory_resource ([[mem.res.class]](mem.res.class "20.5.2 Class memory_resource"))[.](#5.sentence-2)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8356)
|
||||
|
||||
*Throws*: Nothing unless upstream_resource()->allocate() throws[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:do_deallocate,synchronized_pool_resource)
|
||||
|
||||
`void do_deallocate(void* p, size_t bytes, size_t alignment) override;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8368)
|
||||
|
||||
*Effects*: Returns the memory at p to the pool[.](#7.sentence-1)
|
||||
|
||||
It is unspecified if, or under what circumstances,
|
||||
this operation will result in a call to upstream_resource()->deallocate()[.](#7.sentence-2)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8374)
|
||||
|
||||
*Throws*: Nothing[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:do_is_equal,synchronized_pool_resource)
|
||||
|
||||
`bool do_is_equal(const memory_resource& other) const noexcept override;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8386)
|
||||
|
||||
*Returns*: this == &other[.](#9.sentence-1)
|
||||
60
cppdraft/mem/res/pool/options.md
Normal file
60
cppdraft/mem/res/pool/options.md
Normal file
@@ -0,0 +1,60 @@
|
||||
[mem.res.pool.options]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#pool.options)
|
||||
|
||||
### 20.5.5 Pool resource classes [[mem.res.pool]](mem.res.pool#options)
|
||||
|
||||
#### 20.5.5.2 pool_options data members [mem.res.pool.options]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8195)
|
||||
|
||||
The members of pool_options comprise a set of constructor options for pool resources[.](#1.sentence-1)
|
||||
|
||||
The effect of each option on the pool resource behavior is described below:
|
||||
|
||||
[ð](#lib:pool_options,max_blocks_per_chunk)
|
||||
|
||||
`size_t max_blocks_per_chunk;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8206)
|
||||
|
||||
The maximum number of blocks that will be allocated at once
|
||||
from the upstream memory resource ([[mem.res.monotonic.buffer]](mem.res.monotonic.buffer "20.5.6 Class monotonic_buffer_resource"))
|
||||
to replenish a pool[.](#2.sentence-1)
|
||||
|
||||
If the value of max_blocks_per_chunk is zero or
|
||||
is greater than an implementation-defined
|
||||
limit, that limit is used instead[.](#2.sentence-2)
|
||||
|
||||
The implementation
|
||||
may choose to use a smaller value than is specified in this member and
|
||||
may use different values for different pools[.](#2.sentence-3)
|
||||
|
||||
[ð](#lib:pool_options,largest_required_pool_block)
|
||||
|
||||
`size_t largest_required_pool_block;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8224)
|
||||
|
||||
The largest allocation size that is required to be fulfilled
|
||||
using the pooling mechanism[.](#3.sentence-1)
|
||||
|
||||
Attempts to allocate a single block larger than this threshold
|
||||
will be allocated directly from the upstream memory resource[.](#3.sentence-2)
|
||||
|
||||
If largest_required_pool_block is zero or
|
||||
is greater than an implementation-defined
|
||||
limit, that limit is used instead[.](#3.sentence-3)
|
||||
|
||||
The implementation may choose a pass-through threshold
|
||||
larger than specified in this member[.](#3.sentence-4)
|
||||
84
cppdraft/mem/res/pool/overview.md
Normal file
84
cppdraft/mem/res/pool/overview.md
Normal file
@@ -0,0 +1,84 @@
|
||||
[mem.res.pool.overview]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#pool.overview)
|
||||
|
||||
### 20.5.5 Pool resource classes [[mem.res.pool]](mem.res.pool#overview)
|
||||
|
||||
#### 20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8081)
|
||||
|
||||
The synchronized_pool_resource andunsynchronized_pool_resource classes
|
||||
(collectively called [*pool resource classes*](#def:pool_resource_classes "20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]"))
|
||||
are general-purpose memory resources having the following qualities:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
Each resource frees its allocated memory on destruction,
|
||||
even if deallocate has not been called for some of the allocated blocks[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
A pool resource consists of a collection of [*pools*](#def:pools "20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]"),
|
||||
serving requests for different block sizes[.](#1.2.sentence-1)
|
||||
Each individual pool manages a collection of [*chunks*](#def:chunks "20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]") that are in turn divided into blocks of uniform size,
|
||||
returned via calls to do_allocate[.](#1.2.sentence-2)
|
||||
Each call to do_allocate(size, alignment) is dispatched
|
||||
to the pool serving the smallest blocks accommodating at least size bytes[.](#1.2.sentence-3)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
When a particular pool is exhausted,
|
||||
allocating a block from that pool results in the allocation
|
||||
of an additional chunk of memory from the [*upstream allocator*](#def:upstream_allocator "20.5.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]") (supplied at construction), thus replenishing the pool[.](#1.3.sentence-1)
|
||||
With each successive replenishment,
|
||||
the chunk size obtained increases geometrically[.](#1.3.sentence-2)
|
||||
[*Note [1](#note-1)*:
|
||||
By allocating memory in chunks,
|
||||
the pooling strategy increases the chance that consecutive allocations
|
||||
will be close together in memory[.](#1.3.sentence-3)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
Allocation requests that exceed the largest block size of any pool
|
||||
are fulfilled directly from the upstream allocator[.](#1.4.sentence-1)
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
A pool_options struct may be passed to the pool resource constructors
|
||||
to tune the largest block size and the maximum chunk size[.](#1.5.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L8118)
|
||||
|
||||
A synchronized_pool_resource may be accessed from multiple threads
|
||||
without external synchronization
|
||||
and may have thread-specific pools to reduce synchronization costs[.](#2.sentence-1)
|
||||
|
||||
An unsynchronized_pool_resource class may not be accessed
|
||||
from multiple threads simultaneously
|
||||
and thus avoids the cost of synchronization entirely
|
||||
in single-threaded applications[.](#2.sentence-2)
|
||||
|
||||
[ð](#lib:pool_options)
|
||||
|
||||
namespace std::pmr {struct pool_options { size_t max_blocks_per_chunk = 0;
|
||||
size_t largest_required_pool_block = 0; }; class synchronized_pool_resource : public memory_resource {public: synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
|
||||
|
||||
synchronized_pool_resource(): synchronized_pool_resource(pool_options(), get_default_resource()) {}explicit synchronized_pool_resource(memory_resource* upstream): synchronized_pool_resource(pool_options(), upstream) {}explicit synchronized_pool_resource(const pool_options& opts): synchronized_pool_resource(opts, get_default_resource()) {} synchronized_pool_resource(const synchronized_pool_resource&) = delete; virtual ~synchronized_pool_resource();
|
||||
|
||||
synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete; void release();
|
||||
memory_resource* upstream_resource() const;
|
||||
pool_options options() const; protected:void* do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; }; class unsynchronized_pool_resource : public memory_resource {public: unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
|
||||
|
||||
unsynchronized_pool_resource(): unsynchronized_pool_resource(pool_options(), get_default_resource()) {}explicit unsynchronized_pool_resource(memory_resource* upstream): unsynchronized_pool_resource(pool_options(), upstream) {}explicit unsynchronized_pool_resource(const pool_options& opts): unsynchronized_pool_resource(opts, get_default_resource()) {} unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete; virtual ~unsynchronized_pool_resource();
|
||||
|
||||
unsynchronized_pool_resource& operator=(const unsynchronized_pool_resource&) = delete; void release();
|
||||
memory_resource* upstream_resource() const;
|
||||
pool_options options() const; protected:void* do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; };}
|
||||
80
cppdraft/mem/res/private.md
Normal file
80
cppdraft/mem/res/private.md
Normal file
@@ -0,0 +1,80 @@
|
||||
[mem.res.private]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#private)
|
||||
|
||||
### 20.5.2 Class memory_resource [[mem.res.class]](mem.res.class#mem.res.private)
|
||||
|
||||
#### 20.5.2.3 Private virtual member functions [mem.res.private]
|
||||
|
||||
[ð](#lib:do_allocate,memory_resource)
|
||||
|
||||
`virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7581)
|
||||
|
||||
*Preconditions*: alignment is a power of two[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7585)
|
||||
|
||||
*Returns*: A derived class shall implement this function to
|
||||
return a pointer to allocated storage ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2 Allocation functions"))
|
||||
with a size of at least bytes,
|
||||
aligned to the specified alignment[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7592)
|
||||
|
||||
*Throws*: A derived class implementation shall throw an appropriate exception if it is unable to allocate memory with the requested size and alignment[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:do_deallocate,memory_resource)
|
||||
|
||||
`virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7603)
|
||||
|
||||
*Preconditions*: p was returned from a prior call to allocate(bytes, alignment) on a memory resource equal to *this,
|
||||
and the storage at p has not yet been deallocated[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7609)
|
||||
|
||||
*Effects*: A derived class shall implement this function to dispose of allocated storage[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7613)
|
||||
|
||||
*Throws*: Nothing[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:do_is_equal,memory_resource)
|
||||
|
||||
`virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7624)
|
||||
|
||||
*Returns*: A derived class shall implement this function to return true if memory allocated from *this can be deallocated from other and vice-versa,
|
||||
otherwise false[.](#7.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
It is possible that the most-derived type of other does not match the type of *this[.](#7.sentence-2)
|
||||
|
||||
For a derived class D, an implementation of this function
|
||||
can immediately return false if dynamic_cast<const D*>(&other) == nullptr[.](#7.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
67
cppdraft/mem/res/public.md
Normal file
67
cppdraft/mem/res/public.md
Normal file
@@ -0,0 +1,67 @@
|
||||
[mem.res.public]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#public)
|
||||
|
||||
### 20.5.2 Class memory_resource [[mem.res.class]](mem.res.class#mem.res.public)
|
||||
|
||||
#### 20.5.2.2 Public member functions [mem.res.public]
|
||||
|
||||
[ð](#lib:memory_resource,destructor)
|
||||
|
||||
`~memory_resource();
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7524)
|
||||
|
||||
*Effects*: Destroys this memory_resource[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:allocate,memory_resource)
|
||||
|
||||
`void* allocate(size_t bytes, size_t alignment = max_align);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7535)
|
||||
|
||||
*Effects*: Allocates storage by calling do_allocate(bytes, alignment) and
|
||||
implicitly creates objects within the allocated region of storage[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7540)
|
||||
|
||||
*Returns*: A pointer to a suitable created object ([[intro.object]](intro.object "6.8.2 Object model"))
|
||||
in the allocated region of storage[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7545)
|
||||
|
||||
*Throws*: What and when the call to do_allocate throws[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:deallocate,memory_resource)
|
||||
|
||||
`void deallocate(void* p, size_t bytes, size_t alignment = max_align);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7556)
|
||||
|
||||
*Effects*: Equivalent to do_deallocate(p, bytes, alignment)[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:is_equal,memory_resource)
|
||||
|
||||
`bool is_equal(const memory_resource& other) const noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L7567)
|
||||
|
||||
*Effects*: Equivalent to: return do_is_equal(other);
|
||||
14
cppdraft/mem/res/syn.md
Normal file
14
cppdraft/mem/res/syn.md
Normal file
@@ -0,0 +1,14 @@
|
||||
[mem.res.syn]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.5 Memory resources [[mem.res]](mem.res#syn)
|
||||
|
||||
### 20.5.1 Header <memory_resource> synopsis [mem.res.syn]
|
||||
|
||||
[ð](#header:%3cmemory_resource%3e)
|
||||
|
||||
namespace std::pmr {// [[mem.res.class]](mem.res.class "20.5.2 Class memory_resource"), class memory_resourceclass memory_resource; bool operator==(const memory_resource& a, const memory_resource& b) noexcept; // [[mem.poly.allocator.class]](mem.poly.allocator.class "20.5.3 Class template polymorphic_allocator"), class template polymorphic_allocatortemplate<class Tp = byte> class polymorphic_allocator; template<class T1, class T2>bool operator==(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) noexcept; // [[mem.res.global]](mem.res.global "20.5.4 Access to program-wide memory_resource objects"), global memory resources memory_resource* new_delete_resource() noexcept;
|
||||
memory_resource* null_memory_resource() noexcept;
|
||||
memory_resource* set_default_resource(memory_resource* r) noexcept;
|
||||
memory_resource* get_default_resource() noexcept; // [[mem.res.pool]](mem.res.pool "20.5.5 Pool resource classes"), pool resource classesstruct pool_options; class synchronized_pool_resource; class unsynchronized_pool_resource; class monotonic_buffer_resource;}
|
||||
Reference in New Issue
Block a user