23 General utilities library [utilities]

23.12 Memory resources [mem.res]

23.12.6 Class monotonic_­buffer_­resource [mem.res.monotonic.buffer]

A monotonic_­buffer_­resource - это ресурс памяти специального назначения, предназначенный для очень быстрого выделения памяти в ситуациях, когда память используется для создания нескольких объектов, а затем освобождается сразу после уничтожения объекта ресурса памяти. Обладает следующими качествами:

  • Обращение к не deallocate имеет никакого эффекта, поэтому объем потребляемой памяти монотонно увеличивается до тех пор, пока ресурс не будет уничтожен.

  • Программа может предоставить начальный буфер, который распределитель использует для удовлетворения запросов памяти.

  • Когда исходный буфер (если он есть) исчерпан, он получает дополнительные буферы из upstream ресурса памяти, предоставленного при построении. Каждый дополнительный буфер больше предыдущего в геометрической прогрессии.

  • Он предназначен для доступа из одного потока управления за раз. В частности, вызовы allocate и deallocate не синхронизируются друг с другом.

  • Он освобождает выделенную память при уничтожении, даже если deallocate не был вызван для некоторых из выделенных блоков.

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;
};

23.12.6.1 monotonic_­buffer_­resource constructor and destructor [mem.res.monotonic.buffer.ctor]

explicit monotonic_buffer_resource(memory_resource* upstream); monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);

Requires: upstream должен быть адресом допустимого ресурса памяти. initial_­size, если указано, должно быть больше нуля.

Effects: Устанавливает upstream_­rsrc на upstream и current_­buffer на nullptr. Если initial_­size указано, устанавливается next_­buffer_­size как минимум initial_­size; в противном случае устанавливает next_­buffer_­size к реализации определенных размеров.

monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);

Requires: upstream должен быть адресом допустимого ресурса памяти. buffer_­size не должно быть больше, чем количество байтов в buffer.

Effects: Устанавливается upstream_­rsrc в upstream, current_­buffer в bufferи next_­buffer_­size в buffer_­size (но не менее 1), затем увеличивается next_­buffer_­size на коэффициент роста, определяемый реализацией (который не обязательно должен быть целым).

~monotonic_buffer_resource();

Effects: Звонки release().

23.12.6.2 monotonic_­buffer_­resource members [mem.res.monotonic.buffer.mem]

void release();

Effects: Вызывает по upstream_­rsrc->deallocate() мере необходимости для освобождения всей выделенной памяти.

[ Note: Память возвращается обратно, upstream_­rsrc даже если некоторые блоки, которые были выделены из this , не были освобождены this. ] end note

memory_resource* upstream_resource() const;

Returns: Ценность upstream_­rsrc.

void* do_allocate(size_t bytes, size_t alignment) override;

Returns: Указатель на выделенное хранилище ([basic.stc.dynamic.deallocation]) размером не менее bytes. Размер и выравнивание выделенной памяти должны соответствовать требованиям для класса, производного от memory_­resource.

Effects: Если неиспользуемое пространство в current_­buffer может уместиться в блоке с указанными bytes и alignment, то выделите возвращаемый блок из current_­buffer; в противном случае устанавливается current_­buffer значение upstream_­rsrc->allocate(n, m), где n не меньше max(bytes, next_­buffer_­size) и m не меньше alignment, и увеличивается next_­buffer_­size на коэффициент роста, определяемый реализацией (который не обязательно должен быть целым), затем выделять блок возврата из вновь выделенного current_­buffer.

Throws: Ничего, разве что upstream_­rsrc->allocate() кидает.

void do_deallocate(void* p, size_t bytes, size_t alignment) override;

Effects: Никто.

Throws: Ничего такого.

Remarks: Память, используемая этим ресурсом, монотонно увеличивается до тех пор, пока не будет уничтожена.

bool do_is_equal(const memory_resource& other) const noexcept override;

Returns: this == dynamic_­cast<const monotonic_­buffer_­resource*>(&other).