[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)
