16 template <
typename T = std::
byte> T *alloc(
size_t n = 1) {
17 return static_cast<T *
>(
ffi_guard{::MemoryContextAlloc}(_memory_context(),
sizeof(T) * n));
19 template <
typename T =
void>
void free(T *ptr) {
ffi_guard{::pfree}(ptr); }
21 void reset() {
ffi_guard{::MemoryContextReset}(_memory_context()); }
24 return _memory_context() == c._memory_context();
27 return _memory_context() != c._memory_context();
30 operator ::MemoryContext() {
return _memory_context(); }
32 ::MemoryContextCallback *register_reset_callback(::MemoryContextCallbackFunction func,
34 auto cb = alloc<::MemoryContextCallback>(
sizeof(::MemoryContextCallback));
37 ffi_guard{::MemoryContextRegisterResetCallback}(_memory_context(), cb);
41 void delete_context() {
ffi_guard{::MemoryContextDelete}(_memory_context()); }
49 virtual ::MemoryContext _memory_context() = 0;
51 template <
typename T>
requires requires(T t) { t(); }
54 : _ctx(::CurrentMemoryContext), _thunk(thunk) {
55 ::CurrentMemoryContext = ctx;
59 auto operator()() {
return _thunk(); }
79 ::MemoryContext context;
82 ::MemoryContext _memory_context()
override {
return context; }
90 explicit memory_context(::MemoryContext context) : context(context) {}
96 if (ptr ==
nullptr || ptr != (
void *)MAXALIGN(ptr)) {
97 throw std::runtime_error(
"invalid pointer");
102 template <
typename C>
requires std::derived_from<C, abstract_memory_context>
106 ::MemoryContext context;
108 ::MemoryContext _memory_context()
noexcept override {
return context; }
115 ::MemoryContext _memory_context()
override { return ::CurrentMemoryContext; }
119 using owned_memory_context::owned_memory_context;
122 ::CurrentMemoryContext,
nullptr, ALLOCSET_DEFAULT_SIZES)) {}
125 ffi_guard{::AllocSetContextCreateInternal}(ctx,
nullptr, ALLOCSET_DEFAULT_SIZES)) {}
129 ffi_guard{::AllocSetContextCreateInternal}(ctx,
nullptr, ALLOCSET_DEFAULT_SIZES)) {}
134template <
typename C>
requires std::derived_from<C, abstract_memory_context>
137 : ctx(context.ctx), counter(context.counter), cb(context.cb) {
142 : ctx(ctx), counter(0),
143 cb(std::shared_ptr<::MemoryContextCallback>(
144 this->register_reset_callback(
151 : ctx(std::move(other.ctx)), counter(std::move(other.counter)), cb(std::move(other.cb)) {
157 : ctx(std::move(other.ctx)), counter(std::move(other.counter)), cb(std::move(other.cb)) {
165 counter = other.counter;
172 if (cb.use_count() == 1) {
173 cb->func = [](
void *) {};
178 uint64_t resets()
const {
return counter; }
179 C &get_memory_context() {
return ctx; }
182 template <
typename T>
requires std::integral<T>
183 struct shared_counter {
185 constexpr explicit shared_counter(T init = 0) noexcept :
value(init) {}
187 shared_counter &operator=(T v)
noexcept {
192 shared_counter &operator++()
noexcept {
197 T operator++(
int)
noexcept {
203 constexpr operator T()
const noexcept {
return value; }
206 shared_counter<uint64_t> counter;
207 std::shared_ptr<::MemoryContextCallback> cb;
210 ::MemoryContext _memory_context()
override {
return ctx._memory_context(); }
215 std::derived_from<T, abstract_memory_context> && std::default_initializable<T>;
219 : previous(::CurrentMemoryContext), ctx(ctx.operator ::MemoryContext()) {
220 ::CurrentMemoryContext = ctx;
223 : previous(::CurrentMemoryContext), ctx(ctx.operator ::MemoryContext()) {
224 ::CurrentMemoryContext = ctx;
230 ::MemoryContext previous;
235 using value_type = T;
238 : context(std::move(ctx)), explicit_deallocation(explicit_deallocation) {}
241 : context(c.context) {}
243 [[nodiscard]] T *allocate(std::size_t n) {
245 return context.template alloc<T>(n);
247 throw std::bad_alloc();
251 void deallocate(T *p, std::size_t n)
noexcept {
252 if (explicit_deallocation || context == top_memory_context()) {
264 bool explicit_deallocation;
268 const char *what()
const noexcept override {
269 return "pointer belongs to a MemoryContext that has been reset or deleted";
Definition: exception.hpp:7
Definition: memory.hpp:214
Definition: memory.hpp:52
Definition: memory.hpp:14
auto operator()(auto thunk)
Definition: memory.hpp:46
Definition: memory.hpp:118
Definition: memory.hpp:111
Definition: memory.hpp:234
Definition: memory.hpp:217
Definition: memory.hpp:85
Definition: memory.hpp:67
Definition: memory.hpp:267
Definition: memory.hpp:135