#ifndef LIBCUBESCRIPT_STATE_HH #define LIBCUBESCRIPT_STATE_HH #include #include #include #include "cs_bcode.hh" namespace cscript { struct cs_state; struct cs_shared_state; struct cs_strman; template struct cs_allocator { using value_type = T; inline cs_allocator(cs_shared_state *s); inline cs_allocator(cs_state &cs); template cs_allocator(cs_allocator const &a): state{a.state} {}; inline T *allocate(std::size_t n); inline void deallocate(T *p, std::size_t n); template bool operator==(cs_allocator const &a) { return state == a.state; } cs_shared_state *state; }; struct cs_shared_state { using allocator_type = cs_allocator< std::pair >; cs_alloc_cb allocf; void *aptr; std::unordered_map< std::string_view, cs_ident *, std::hash, std::equal_to, allocator_type > idents; std::vector> identmap; cs_vprint_cb varprintf; cs_strman *strman; empty_block *empty; cs_shared_state() = delete; cs_shared_state(cs_alloc_cb af, void *data); ~cs_shared_state(); void *alloc(void *ptr, size_t os, size_t ns); template T *create(A &&...args) { T *ret = static_cast(alloc(nullptr, 0, sizeof(T))); new (ret) T(std::forward(args)...); return ret; } template T *create_array(size_t len) { T *ret = static_cast(alloc(nullptr, 0, len * sizeof(T))); for (size_t i = 0; i < len; ++i) { new (&ret[i]) T(); } return ret; } template void destroy(T *v) noexcept { v->~T(); alloc(v, sizeof(T), 0); } template void destroy_array(T *v, size_t len) noexcept { v->~T(); alloc(v, len * sizeof(T), 0); } }; inline cs_shared_state *cs_get_sstate(cs_state &cs) { return cs.p_state; } template inline cs_allocator::cs_allocator(cs_shared_state *s): state{s} {} template inline cs_allocator::cs_allocator(cs_state &s): state{cs_get_sstate(s)} {} template inline T *cs_allocator::allocate(std::size_t n) { return static_cast(state->alloc(nullptr, 0, n * sizeof(T))); } template inline void cs_allocator::deallocate(T *p, std::size_t n) { state->alloc(p, n, 0); } } /* namespace cscript */ #endif