From Jason Turner

[mem.res]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpcgl3k0rk/{from.md → to.md} +46 -49
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:* Equivalent to: `return do_allocate(bytes, alignment);`
 
 
 
 
 
 
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*: The most-derived type of `other` might not match the type of
128
- `this`. For a derived class `D`, an implementation of this function
129
- could immediately return `false` if
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 ([[cpp17.allocator]]). Constructed
144
- with different memory resources, different instances of the same
 
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
- All specializations of class template `pmr::polymorphic_allocator` meet
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 CtorArgs...>
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. It has the following qualities:
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
  ```