...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::container::pmr::monotonic_buffer_resource
// In header: <boost/container/pmr/monotonic_buffer_resource.hpp> class monotonic_buffer_resource : public boost::container::pmr::memory_resource { public: // construct/copy/destruct explicit monotonic_buffer_resource(memory_resource * = 0) noexcept; explicit monotonic_buffer_resource(std::size_t, memory_resource * = 0) noexcept; monotonic_buffer_resource(void *, std::size_t, memory_resource * = 0) noexcept; monotonic_buffer_resource(const monotonic_buffer_resource &) = delete; monotonic_buffer_resource operator=(const monotonic_buffer_resource &) = delete; ~monotonic_buffer_resource(); // public member functions void release() noexcept; memory_resource * upstream_resource() const noexcept; std::size_t remaining_storage(std::size_t, std::size_t &) const noexcept; std::size_t remaining_storage(std::size_t = 1u) const noexcept; const void * current_buffer() const noexcept; std::size_t next_buffer_size() const noexcept; // protected member functions virtual void * do_allocate(std::size_t, std::size_t); virtual void do_deallocate(void *, std::size_t, std::size_t) noexcept; virtual bool do_is_equal(const memory_resource &) const noexcept; // public data members static const std::size_t initial_next_buffer_size; };
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. It has the following qualities:
A call to deallocate has no effect, thus the amount of memory consumed increases monotonically until the resource is destroyed.
The program can supply an initial buffer, which the allocator uses to satisfy memory requests.
When the initial buffer (if any) is exhausted, it obtains additional buffers from an upstream memory resource supplied at construction. Each additional buffer is larger than the previous one, following a geometric progression.
It is intended for access from one thread of control at a time. Specifically, calls to allocate and deallocate do not synchronize with one another.
It owns the allocated memory and frees it on destruction, even if deallocate has not been called for some of the allocated blocks.
monotonic_buffer_resource
public
construct/copy/destructexplicit monotonic_buffer_resource(memory_resource * upstream = 0) noexcept;
Requires: upstream
shall be the address of a valid memory resource or nullptr
Effects: If upstream
is not nullptr, sets the internal resource to upstream
, to get_default_resource() otherwise. Sets the internal current_buffer
to nullptr
and the internal next_buffer_size
to an implementation-defined size.
explicit monotonic_buffer_resource(std::size_t initial_size, memory_resource * upstream = 0) noexcept;
Requires: upstream
shall be the address of a valid memory resource or nullptr
and initial_size
shall be greater than zero.
Effects: If upstream
is not nullptr, sets the internal resource to upstream
, to get_default_resource() otherwise. Sets the internal current_buffer
to nullptr
and next_buffer_size
to at least initial_size
.
monotonic_buffer_resource(void * buffer, std::size_t buffer_size, memory_resource * upstream = 0) noexcept;
Requires: upstream
shall be the address of a valid memory resource or nullptr
, buffer_size
shall be no larger than the number of bytes in buffer.
Effects: If upstream
is not nullptr, sets the internal resource to upstream
, to get_default_resource() otherwise. Sets the internal current_buffer
to buffer
, and next_buffer_size
to buffer_size
(but not less than an implementation-defined size), then increases next_buffer_size
by an implementation-defined growth factor (which need not be integral).
monotonic_buffer_resource(const monotonic_buffer_resource &) = delete;
monotonic_buffer_resource operator=(const monotonic_buffer_resource &) = delete;
~monotonic_buffer_resource();
Effects: Calls this->release()
.
monotonic_buffer_resource
public member functionsvoid release() noexcept;
Effects: upstream_resource()->deallocate()
as necessary to release all allocated memory. [Note: memory is released back to upstream_resource()
even if some blocks that were allocated from this have not been deallocated from this. - end note]
memory_resource * upstream_resource() const noexcept;
Returns: The value of the internal resource.
std::size_t remaining_storage(std::size_t alignment, std::size_t & wasted_due_to_alignment) const noexcept;
Returns: The number of bytes of storage available for the specified alignment and the number of bytes wasted due to the requested alignment.
Note: Non-standard extension.
std::size_t remaining_storage(std::size_t alignment = 1u) const noexcept;
Returns: The number of bytes of storage available for the specified alignment.
Note: Non-standard extension.
const void * current_buffer() const noexcept;
Returns: The address pointing to the start of the current free storage.
Note: Non-standard extension.
std::size_t next_buffer_size() const noexcept;
Returns: The number of bytes that will be requested for the next buffer once the current one is exhausted.
Note: Non-standard extension.
monotonic_buffer_resource
protected member functionsvirtual void * do_allocate(std::size_t bytes, std::size_t alignment);
Returns: A pointer to allocated storage with a size of at least bytes
. The size and alignment of the allocated memory shall meet the requirements for a class derived from
.memory_resource
Effects: If the unused space in the internal current_buffer
can fit a block with the specified bytes and alignment, then allocate the return block from the internal current_buffer
; otherwise sets the internal current_buffer
to upstream_resource()->allocate(n, m)
, where n
is not less than max(bytes, next_buffer_size)
and m
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 internal current_buffer
.
Throws: Nothing unless upstream_resource()->allocate()
throws.
virtual void do_deallocate(void * p, std::size_t bytes, std::size_t alignment) noexcept;
Effects: None
Throws: Nothing
Remarks: Memory used by this resource increases monotonically until its destruction.
virtual bool do_is_equal(const memory_resource & other) const noexcept;
Returns: this == dynamic_cast<const monotonic_buffer_resource*>(&other)
.