#ifndef LIBCUBESCRIPT_STATE_HH #define LIBCUBESCRIPT_STATE_HH #include #include #include #include #include "cs_bcode.hh" #include "cs_ident.hh" namespace cubescript { struct internal_state; struct string_pool; template struct std_allocator { using value_type = T; inline std_allocator(internal_state *s); template std_allocator(std_allocator const &a): istate{a.istate} {} inline T *allocate(std::size_t n); inline void deallocate(T *p, std::size_t n); template bool operator==(std_allocator const &a) { return istate == a.istate; } internal_state *istate; }; struct internal_state { using allocator_type = std_allocator< std::pair >; alloc_func allocf; void *aptr; std::unordered_map< std::string_view, ident *, std::hash, std::equal_to, allocator_type > idents; std::vector> identmap; string_pool *strman; empty_block *empty; ident *id_dummy; builtin_var *ivar_numargs; builtin_var *ivar_dbgalias; command *cmd_ivar; command *cmd_fvar; command *cmd_svar; command *cmd_var_changed; internal_state() = delete; internal_state(alloc_func af, void *data); ~internal_state(); ident *add_ident(ident *id, ident_impl *impl); ident &new_ident(state &cs, std::string_view name, int flags); ident *get_ident(std::string_view name) const; 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, A &&...args) { T *ret = static_cast(alloc(nullptr, 0, len * sizeof(T))); for (size_t i = 0; i < len; ++i) { new (&ret[i]) T{std::forward(args)...}; } 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); } }; struct state_p { state_p(state &cs): csp{&cs} {} thread_state &ts() { return *csp->p_tstate; } state *csp; }; template inline std_allocator::std_allocator(internal_state *s): istate{s} {} template inline T *std_allocator::allocate(std::size_t n) { return static_cast(istate->alloc(nullptr, 0, n * sizeof(T))); } template inline void std_allocator::deallocate(T *p, std::size_t n) { istate->alloc(p, n, 0); } template inline void new_cmd_quiet( state &cs, std::string_view name, std::string_view args, F &&f ) { try { cs.new_command(name, args, std::forward(f)); } catch (error const &) { return; } } } /* namespace cubescript */ #endif