tmp/tmpcgl3k0rk/{from.md → to.md}
RENAMED
|
@@ -8,11 +8,11 @@ namespace std::pmr {
|
|
| 8 |
class memory_resource;
|
| 9 |
|
| 10 |
bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
|
| 11 |
|
| 12 |
// [mem.poly.allocator.class], class template polymorphic_allocator
|
| 13 |
-
template<class Tp> class polymorphic_allocator;
|
| 14 |
|
| 15 |
template<class T1, class T2>
|
| 16 |
bool operator==(const polymorphic_allocator<T1>& a,
|
| 17 |
const polymorphic_allocator<T2>& b) noexcept;
|
| 18 |
|
|
@@ -30,10 +30,12 @@ namespace std::pmr {
|
|
| 30 |
}
|
| 31 |
```
|
| 32 |
|
| 33 |
### Class `memory_resource` <a id="mem.res.class">[[mem.res.class]]</a>
|
| 34 |
|
|
|
|
|
|
|
| 35 |
The `memory_resource` class is an abstract interface to an unbounded set
|
| 36 |
of classes encapsulating memory resources.
|
| 37 |
|
| 38 |
``` cpp
|
| 39 |
namespace std::pmr {
|
|
@@ -71,11 +73,17 @@ namespace std::pmr {
|
|
| 71 |
|
| 72 |
``` cpp
|
| 73 |
[[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align);
|
| 74 |
```
|
| 75 |
|
| 76 |
-
*Effects:*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
``` cpp
|
| 79 |
void deallocate(void* p, size_t bytes, size_t alignment = max_align);
|
| 80 |
```
|
| 81 |
|
|
@@ -122,13 +130,13 @@ virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
|
|
| 122 |
|
| 123 |
*Returns:* A derived class shall implement this function to return
|
| 124 |
`true` if memory allocated from `this` can be deallocated from `other`
|
| 125 |
and vice-versa, otherwise `false`.
|
| 126 |
|
| 127 |
-
[*Note 1*:
|
| 128 |
-
`this`. For a derived class `D`, an implementation
|
| 129 |
-
|
| 130 |
`dynamic_cast<const D*>(&other) == nullptr`. — *end note*]
|
| 131 |
|
| 132 |
#### Equality <a id="mem.res.eq">[[mem.res.eq]]</a>
|
| 133 |
|
| 134 |
``` cpp
|
|
@@ -137,22 +145,26 @@ bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
|
|
| 137 |
|
| 138 |
*Returns:* `&a == &b || a.is_equal(b)`.
|
| 139 |
|
| 140 |
### Class template `polymorphic_allocator` <a id="mem.poly.allocator.class">[[mem.poly.allocator.class]]</a>
|
| 141 |
|
|
|
|
|
|
|
| 142 |
A specialization of class template `pmr::polymorphic_allocator` meets
|
| 143 |
-
the *Cpp17Allocator* requirements
|
| 144 |
-
|
|
|
|
| 145 |
specialization of `pmr::polymorphic_allocator` can exhibit entirely
|
| 146 |
different allocation behavior. This runtime polymorphism allows objects
|
| 147 |
that use `polymorphic_allocator` to behave as if they used different
|
| 148 |
allocator types at run time even though they use the same static
|
| 149 |
allocator type.
|
| 150 |
|
| 151 |
-
|
| 152 |
the allocator completeness requirements
|
| 153 |
-
[[allocator.requirements.completeness]]
|
|
|
|
| 154 |
|
| 155 |
``` cpp
|
| 156 |
namespace std::pmr {
|
| 157 |
template<class Tp = byte> class polymorphic_allocator {
|
| 158 |
memory_resource* memory_rsrc; // exposition only
|
|
@@ -183,16 +195,19 @@ namespace std::pmr {
|
|
| 183 |
template<class T> void delete_object(T* p);
|
| 184 |
|
| 185 |
template<class T, class... Args>
|
| 186 |
void construct(T* p, Args&&... args);
|
| 187 |
|
| 188 |
-
template<class T>
|
| 189 |
-
void destroy(T* p);
|
| 190 |
-
|
| 191 |
polymorphic_allocator select_on_container_copy_construction() const;
|
| 192 |
|
| 193 |
memory_resource* resource() const;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
};
|
| 195 |
}
|
| 196 |
```
|
| 197 |
|
| 198 |
#### Constructors <a id="mem.poly.allocator.ctor">[[mem.poly.allocator.ctor]]</a>
|
|
@@ -290,11 +305,11 @@ template<class T>
|
|
| 290 |
```
|
| 291 |
|
| 292 |
*Effects:* Equivalent to `deallocate_bytes(p, n*sizeof(T), alignof(T))`.
|
| 293 |
|
| 294 |
``` cpp
|
| 295 |
-
template<class T, class
|
| 296 |
[[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
|
| 297 |
```
|
| 298 |
|
| 299 |
*Effects:* Allocates and constructs an object of type `T`, as follows.
|
| 300 |
Equivalent to:
|
|
@@ -319,11 +334,11 @@ template<class T>
|
|
| 319 |
```
|
| 320 |
|
| 321 |
*Effects:* Equivalent to:
|
| 322 |
|
| 323 |
``` cpp
|
| 324 |
-
destroy(p);
|
| 325 |
deallocate_object(p);
|
| 326 |
```
|
| 327 |
|
| 328 |
``` cpp
|
| 329 |
template<class T, class... Args>
|
|
@@ -338,17 +353,10 @@ template<class T, class... Args>
|
|
| 338 |
represented by `p` by uses-allocator construction with allocator `*this`
|
| 339 |
and constructor arguments `std::forward<Args>(args)...`.
|
| 340 |
|
| 341 |
*Throws:* Nothing unless the constructor for `T` throws.
|
| 342 |
|
| 343 |
-
``` cpp
|
| 344 |
-
template<class T>
|
| 345 |
-
void destroy(T* p);
|
| 346 |
-
```
|
| 347 |
-
|
| 348 |
-
*Effects:* As if by `p->T̃()`.
|
| 349 |
-
|
| 350 |
``` cpp
|
| 351 |
polymorphic_allocator select_on_container_copy_construction() const;
|
| 352 |
```
|
| 353 |
|
| 354 |
*Returns:* `polymorphic_allocator()`.
|
|
@@ -611,22 +619,22 @@ rounded to unspecified granularity.
|
|
| 611 |
|
| 612 |
``` cpp
|
| 613 |
void* do_allocate(size_t bytes, size_t alignment) override;
|
| 614 |
```
|
| 615 |
|
| 616 |
-
*Returns:* A pointer to allocated
|
| 617 |
-
storage [[basic.stc.dynamic.allocation]] with a size of at least
|
| 618 |
-
`bytes`. The size and alignment of the allocated memory shall meet the
|
| 619 |
-
requirements for a class derived from `memory_resource`
|
| 620 |
-
[[mem.res.class]].
|
| 621 |
-
|
| 622 |
*Effects:* If the pool selected for a block of size `bytes` is unable to
|
| 623 |
satisfy the memory request from its own internal data structures, it
|
| 624 |
will call `upstream_resource()->allocate()` to obtain more memory. If
|
| 625 |
`bytes` is larger than that which the largest pool can handle, then
|
| 626 |
memory will be allocated using `upstream_resource()->allocate()`.
|
| 627 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 628 |
*Throws:* Nothing unless `upstream_resource()->allocate()` throws.
|
| 629 |
|
| 630 |
``` cpp
|
| 631 |
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
|
| 632 |
```
|
|
@@ -643,28 +651,16 @@ bool do_is_equal(const memory_resource& other) const noexcept override;
|
|
| 643 |
|
| 644 |
*Returns:* `this == &other`.
|
| 645 |
|
| 646 |
### Class `monotonic_buffer_resource` <a id="mem.res.monotonic.buffer">[[mem.res.monotonic.buffer]]</a>
|
| 647 |
|
|
|
|
|
|
|
| 648 |
A `monotonic_buffer_resource` is a special-purpose memory resource
|
| 649 |
intended for very fast memory allocations in situations where memory is
|
| 650 |
used to build up a few objects and then is released all at once when the
|
| 651 |
-
memory resource object is destroyed.
|
| 652 |
-
|
| 653 |
-
- A call to `deallocate` has no effect, thus the amount of memory
|
| 654 |
-
consumed increases monotonically until the resource is destroyed.
|
| 655 |
-
- The program can supply an initial buffer, which the allocator uses to
|
| 656 |
-
satisfy memory requests.
|
| 657 |
-
- When the initial buffer (if any) is exhausted, it obtains additional
|
| 658 |
-
buffers from an *upstream* memory resource supplied at construction.
|
| 659 |
-
Each additional buffer is larger than the previous one, following a
|
| 660 |
-
geometric progression.
|
| 661 |
-
- It is intended for access from one thread of control at a time.
|
| 662 |
-
Specifically, calls to `allocate` and `deallocate` do not synchronize
|
| 663 |
-
with one another.
|
| 664 |
-
- It frees the allocated memory on destruction, even if `deallocate` has
|
| 665 |
-
not been called for some of the allocated blocks.
|
| 666 |
|
| 667 |
``` cpp
|
| 668 |
namespace std::pmr {
|
| 669 |
class monotonic_buffer_resource : public memory_resource {
|
| 670 |
memory_resource* upstream_rsrc; // exposition only
|
|
@@ -739,11 +735,12 @@ factor (which need not be integral).
|
|
| 739 |
``` cpp
|
| 740 |
void release();
|
| 741 |
```
|
| 742 |
|
| 743 |
*Effects:* Calls `upstream_rsrc->deallocate()` as necessary to release
|
| 744 |
-
all allocated memory.
|
|
|
|
| 745 |
|
| 746 |
[*Note 1*: The memory is released back to `upstream_rsrc` even if some
|
| 747 |
blocks that were allocated from `this` have not been deallocated from
|
| 748 |
`this`. — *end note*]
|
| 749 |
|
|
@@ -755,25 +752,25 @@ memory_resource* upstream_resource() const;
|
|
| 755 |
|
| 756 |
``` cpp
|
| 757 |
void* do_allocate(size_t bytes, size_t alignment) override;
|
| 758 |
```
|
| 759 |
|
| 760 |
-
*Returns:* A pointer to allocated
|
| 761 |
-
storage [[basic.stc.dynamic.allocation]] with a size of at least
|
| 762 |
-
`bytes`. The size and alignment of the allocated memory shall meet the
|
| 763 |
-
requirements for a class derived from `memory_resource`
|
| 764 |
-
[[mem.res.class]].
|
| 765 |
-
|
| 766 |
*Effects:* If the unused space in `current_buffer` can fit a block with
|
| 767 |
the specified `bytes` and `alignment`, then allocate the return block
|
| 768 |
from `current_buffer`; otherwise set `current_buffer` to
|
| 769 |
`upstream_rsrc->allocate(n, m)`, where `n` is not less than
|
| 770 |
`max(bytes, next_buffer_size)` and `m` is not less than `alignment`, and
|
| 771 |
increase `next_buffer_size` by an *implementation-defined* growth factor
|
| 772 |
(which need not be integral), then allocate the return block from the
|
| 773 |
newly-allocated `current_buffer`.
|
| 774 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 775 |
*Throws:* Nothing unless `upstream_rsrc->allocate()` throws.
|
| 776 |
|
| 777 |
``` cpp
|
| 778 |
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
|
| 779 |
```
|
|
|
|
| 8 |
class memory_resource;
|
| 9 |
|
| 10 |
bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
|
| 11 |
|
| 12 |
// [mem.poly.allocator.class], class template polymorphic_allocator
|
| 13 |
+
template<class Tp = byte> class polymorphic_allocator;
|
| 14 |
|
| 15 |
template<class T1, class T2>
|
| 16 |
bool operator==(const polymorphic_allocator<T1>& a,
|
| 17 |
const polymorphic_allocator<T2>& b) noexcept;
|
| 18 |
|
|
|
|
| 30 |
}
|
| 31 |
```
|
| 32 |
|
| 33 |
### Class `memory_resource` <a id="mem.res.class">[[mem.res.class]]</a>
|
| 34 |
|
| 35 |
+
#### General <a id="mem.res.class.general">[[mem.res.class.general]]</a>
|
| 36 |
+
|
| 37 |
The `memory_resource` class is an abstract interface to an unbounded set
|
| 38 |
of classes encapsulating memory resources.
|
| 39 |
|
| 40 |
``` cpp
|
| 41 |
namespace std::pmr {
|
|
|
|
| 73 |
|
| 74 |
``` cpp
|
| 75 |
[[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align);
|
| 76 |
```
|
| 77 |
|
| 78 |
+
*Effects:* Allocates storage by calling `do_allocate(bytes, alignment)`
|
| 79 |
+
and implicitly creates objects within the allocated region of storage.
|
| 80 |
+
|
| 81 |
+
*Returns:* A pointer to a suitable created object [[intro.object]] in
|
| 82 |
+
the allocated region of storage.
|
| 83 |
+
|
| 84 |
+
*Throws:* What and when the call to `do_allocate` throws.
|
| 85 |
|
| 86 |
``` cpp
|
| 87 |
void deallocate(void* p, size_t bytes, size_t alignment = max_align);
|
| 88 |
```
|
| 89 |
|
|
|
|
| 130 |
|
| 131 |
*Returns:* A derived class shall implement this function to return
|
| 132 |
`true` if memory allocated from `this` can be deallocated from `other`
|
| 133 |
and vice-versa, otherwise `false`.
|
| 134 |
|
| 135 |
+
[*Note 1*: It is possible that the most-derived type of `other` does
|
| 136 |
+
not match the type of `this`. For a derived class `D`, an implementation
|
| 137 |
+
of this function can immediately return `false` if
|
| 138 |
`dynamic_cast<const D*>(&other) == nullptr`. — *end note*]
|
| 139 |
|
| 140 |
#### Equality <a id="mem.res.eq">[[mem.res.eq]]</a>
|
| 141 |
|
| 142 |
``` cpp
|
|
|
|
| 145 |
|
| 146 |
*Returns:* `&a == &b || a.is_equal(b)`.
|
| 147 |
|
| 148 |
### Class template `polymorphic_allocator` <a id="mem.poly.allocator.class">[[mem.poly.allocator.class]]</a>
|
| 149 |
|
| 150 |
+
#### General <a id="mem.poly.allocator.class.general">[[mem.poly.allocator.class.general]]</a>
|
| 151 |
+
|
| 152 |
A specialization of class template `pmr::polymorphic_allocator` meets
|
| 153 |
+
the *Cpp17Allocator* requirements [[allocator.requirements.general]] if
|
| 154 |
+
its template argument is a cv-unqualified object type. Constructed with
|
| 155 |
+
different memory resources, different instances of the same
|
| 156 |
specialization of `pmr::polymorphic_allocator` can exhibit entirely
|
| 157 |
different allocation behavior. This runtime polymorphism allows objects
|
| 158 |
that use `polymorphic_allocator` to behave as if they used different
|
| 159 |
allocator types at run time even though they use the same static
|
| 160 |
allocator type.
|
| 161 |
|
| 162 |
+
A specialization of class template `pmr::polymorphic_allocator` meets
|
| 163 |
the allocator completeness requirements
|
| 164 |
+
[[allocator.requirements.completeness]] if its template argument is a
|
| 165 |
+
cv-unqualified object type.
|
| 166 |
|
| 167 |
``` cpp
|
| 168 |
namespace std::pmr {
|
| 169 |
template<class Tp = byte> class polymorphic_allocator {
|
| 170 |
memory_resource* memory_rsrc; // exposition only
|
|
|
|
| 195 |
template<class T> void delete_object(T* p);
|
| 196 |
|
| 197 |
template<class T, class... Args>
|
| 198 |
void construct(T* p, Args&&... args);
|
| 199 |
|
|
|
|
|
|
|
|
|
|
| 200 |
polymorphic_allocator select_on_container_copy_construction() const;
|
| 201 |
|
| 202 |
memory_resource* resource() const;
|
| 203 |
+
|
| 204 |
+
// friends
|
| 205 |
+
friend bool operator==(const polymorphic_allocator& a,
|
| 206 |
+
const polymorphic_allocator& b) noexcept {
|
| 207 |
+
return *a.resource() == *b.resource();
|
| 208 |
+
}
|
| 209 |
};
|
| 210 |
}
|
| 211 |
```
|
| 212 |
|
| 213 |
#### Constructors <a id="mem.poly.allocator.ctor">[[mem.poly.allocator.ctor]]</a>
|
|
|
|
| 305 |
```
|
| 306 |
|
| 307 |
*Effects:* Equivalent to `deallocate_bytes(p, n*sizeof(T), alignof(T))`.
|
| 308 |
|
| 309 |
``` cpp
|
| 310 |
+
template<class T, class... CtorArgs>
|
| 311 |
[[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
|
| 312 |
```
|
| 313 |
|
| 314 |
*Effects:* Allocates and constructs an object of type `T`, as follows.
|
| 315 |
Equivalent to:
|
|
|
|
| 334 |
```
|
| 335 |
|
| 336 |
*Effects:* Equivalent to:
|
| 337 |
|
| 338 |
``` cpp
|
| 339 |
+
allocator_traits<polymorphic_allocator>::destroy(*this, p);
|
| 340 |
deallocate_object(p);
|
| 341 |
```
|
| 342 |
|
| 343 |
``` cpp
|
| 344 |
template<class T, class... Args>
|
|
|
|
| 353 |
represented by `p` by uses-allocator construction with allocator `*this`
|
| 354 |
and constructor arguments `std::forward<Args>(args)...`.
|
| 355 |
|
| 356 |
*Throws:* Nothing unless the constructor for `T` throws.
|
| 357 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 358 |
``` cpp
|
| 359 |
polymorphic_allocator select_on_container_copy_construction() const;
|
| 360 |
```
|
| 361 |
|
| 362 |
*Returns:* `polymorphic_allocator()`.
|
|
|
|
| 619 |
|
| 620 |
``` cpp
|
| 621 |
void* do_allocate(size_t bytes, size_t alignment) override;
|
| 622 |
```
|
| 623 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 624 |
*Effects:* If the pool selected for a block of size `bytes` is unable to
|
| 625 |
satisfy the memory request from its own internal data structures, it
|
| 626 |
will call `upstream_resource()->allocate()` to obtain more memory. If
|
| 627 |
`bytes` is larger than that which the largest pool can handle, then
|
| 628 |
memory will be allocated using `upstream_resource()->allocate()`.
|
| 629 |
|
| 630 |
+
*Returns:* A pointer to allocated
|
| 631 |
+
storage [[basic.stc.dynamic.allocation]] with a size of at least
|
| 632 |
+
`bytes`. The size and alignment of the allocated memory shall meet the
|
| 633 |
+
requirements for a class derived from `memory_resource`
|
| 634 |
+
[[mem.res.class]].
|
| 635 |
+
|
| 636 |
*Throws:* Nothing unless `upstream_resource()->allocate()` throws.
|
| 637 |
|
| 638 |
``` cpp
|
| 639 |
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
|
| 640 |
```
|
|
|
|
| 651 |
|
| 652 |
*Returns:* `this == &other`.
|
| 653 |
|
| 654 |
### Class `monotonic_buffer_resource` <a id="mem.res.monotonic.buffer">[[mem.res.monotonic.buffer]]</a>
|
| 655 |
|
| 656 |
+
#### General <a id="mem.res.monotonic.buffer.general">[[mem.res.monotonic.buffer.general]]</a>
|
| 657 |
+
|
| 658 |
A `monotonic_buffer_resource` is a special-purpose memory resource
|
| 659 |
intended for very fast memory allocations in situations where memory is
|
| 660 |
used to build up a few objects and then is released all at once when the
|
| 661 |
+
memory resource object is destroyed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 662 |
|
| 663 |
``` cpp
|
| 664 |
namespace std::pmr {
|
| 665 |
class monotonic_buffer_resource : public memory_resource {
|
| 666 |
memory_resource* upstream_rsrc; // exposition only
|
|
|
|
| 735 |
``` cpp
|
| 736 |
void release();
|
| 737 |
```
|
| 738 |
|
| 739 |
*Effects:* Calls `upstream_rsrc->deallocate()` as necessary to release
|
| 740 |
+
all allocated memory. Resets `current_buffer` and `next_buffer_size` to
|
| 741 |
+
their initial values at construction.
|
| 742 |
|
| 743 |
[*Note 1*: The memory is released back to `upstream_rsrc` even if some
|
| 744 |
blocks that were allocated from `this` have not been deallocated from
|
| 745 |
`this`. — *end note*]
|
| 746 |
|
|
|
|
| 752 |
|
| 753 |
``` cpp
|
| 754 |
void* do_allocate(size_t bytes, size_t alignment) override;
|
| 755 |
```
|
| 756 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 757 |
*Effects:* If the unused space in `current_buffer` can fit a block with
|
| 758 |
the specified `bytes` and `alignment`, then allocate the return block
|
| 759 |
from `current_buffer`; otherwise set `current_buffer` to
|
| 760 |
`upstream_rsrc->allocate(n, m)`, where `n` is not less than
|
| 761 |
`max(bytes, next_buffer_size)` and `m` is not less than `alignment`, and
|
| 762 |
increase `next_buffer_size` by an *implementation-defined* growth factor
|
| 763 |
(which need not be integral), then allocate the return block from the
|
| 764 |
newly-allocated `current_buffer`.
|
| 765 |
|
| 766 |
+
*Returns:* A pointer to allocated
|
| 767 |
+
storage [[basic.stc.dynamic.allocation]] with a size of at least
|
| 768 |
+
`bytes`. The size and alignment of the allocated memory shall meet the
|
| 769 |
+
requirements for a class derived from `memory_resource`
|
| 770 |
+
[[mem.res.class]].
|
| 771 |
+
|
| 772 |
*Throws:* Nothing unless `upstream_rsrc->allocate()` throws.
|
| 773 |
|
| 774 |
``` cpp
|
| 775 |
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
|
| 776 |
```
|