7fe70ed89b
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"
84 lines
2.1 KiB
C++
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
|