paulxstretch/deps/clap-juce-extensions/clap-libs/clap-helpers/include/clap/helpers/heap.hh
essej 7fe70ed89b git subrepo clone (merge) https://github.com/free-audio/clap-helpers.git deps/clap-juce-extensions/clap-libs/clap-helpers
subrepo:
  subdir:   "deps/clap-juce-extensions/clap-libs/clap-helpers"
  merged:   "2bb43c187"
upstream:
  origin:   "https://github.com/free-audio/clap-helpers.git"
  branch:   "main"
  commit:   "2bb43c187"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
2022-06-14 21:35:21 -04:00

84 lines
2.1 KiB
C++

#pragma once
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <stdexcept>
#include <vector>
namespace clap { namespace helpers {
/** Simple heap allocator which ensures alignment. */
class Heap {
public:
explicit Heap(uint32_t initialSize = 4096) { reserve(initialSize); }
~Heap() { std::free(_base); }
Heap(const Heap &) = delete;
Heap(Heap &&) = delete;
Heap &operator=(const Heap &) = delete;
Heap &operator=(Heap &&) = delete;
void reserve(const size_t heapSize) {
if (heapSize <= _size)
return;
auto *const ptr = static_cast<uint8_t *>(std::realloc(_base, heapSize));
if (!ptr)
throw std::bad_alloc();
_base = ptr;
_size = heapSize;
}
void clear() { _brk = 0; }
void *tryAllocate(uint32_t align, uint32_t size) {
assert(_brk <= _size);
void *ptr = _base + _brk;
size_t space = _size - _brk;
if (!std::align(align, size, ptr, space))
return nullptr;
auto offset = static_cast<uint8_t *>(ptr) - _base;
_brk = offset + size;
std::memset(ptr, 0, size);
return ptr;
}
void *allocate(uint32_t align, uint32_t size) {
assert(_brk <= _size);
if (size + _brk > _size)
reserve(_size * 2);
auto ptr = tryAllocate(align, size);
assert(ptr);
return ptr;
}
void *ptrFromBase(size_t offset) const {
assert(offset <= _brk && "out of range");
return static_cast<uint8_t *>(_base) + offset;
}
size_t offsetFromBase(const void *ptr) const {
assert(ptr >= _base && "ptr before heap's base");
size_t offset = static_cast<const uint8_t *>(ptr) - _base;
assert(offset < _size && "ptr after heap's end");
return offset;
}
size_t size() const { return _size; }
bool empty() const { return _brk == 0; }
private:
size_t _size = 0;
size_t _brk = 0;
uint8_t *_base = nullptr;
};
}} // namespace clap::helpers