| Home | Libraries | People | FAQ | More

## Class monotonic_buffer_resource

boost::container::pmr::monotonic_buffer_resource

## Synopsis

    // 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 &);
      monotonic_buffer_resource operator=(const monotonic_buffer_resource &);
      ~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;
    };

## Description

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/destruct

1.     explicit 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.

2.     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`.

3.     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).

4.     monotonic_buffer_resource(const monotonic_buffer_resource &);

5.     monotonic_buffer_resource operator=(const monotonic_buffer_resource &);

6.     ~monotonic_buffer_resource();

   Effects: Calls `this->release()`.

### `monotonic_buffer_resource` public member functions

1.     void 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]

2.     memory_resource * upstream_resource() const noexcept;

   Returns: The value of the internal resource.

3.     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.

4.     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.

5.     const void * current_buffer() const noexcept;

   Returns: The number of bytes of storage available for the specified alignment.

   Note: Non-standard extension.

6.     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 functions

1.     virtual 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.

2.     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.

3.     virtual bool do_is_equal(const memory_resource & other) const noexcept;

   Returns: `this == dynamic_cast<const monotonic_buffer_resource*>(&other)`.

### `monotonic_buffer_resource` public public data members

1.     static const std::size_t initial_next_buffer_size;

   The number of bytes that will be requested by the default in the first call to the upstream allocator

   Note: Non-standard extension.