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; };
explicit monotonic_buffer_resource(memory_resource* upstream);
monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
Requires: upstream должен быть адресом допустимого ресурса памяти. initial_size, если указано, должно быть больше нуля.
monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
Requires: upstream должен быть адресом допустимого ресурса памяти. buffer_size не должно быть больше, чем количество байтов в buffer.
~monotonic_buffer_resource();
void release();
Effects: Вызывает по upstream_rsrc->deallocate() мере необходимости для освобождения всей выделенной памяти.
[ Note: Память возвращается обратно, upstream_rsrc даже если некоторые блоки, которые были выделены из this , не были освобождены this. ] — end note
memory_resource* upstream_resource() const;
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.
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
Remarks: Память, используемая этим ресурсом, монотонно увеличивается до тех пор, пока не будет уничтожена.
bool do_is_equal(const memory_resource& other) const noexcept override;