diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index fe82b7b3..89fd4fba 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -336,6 +336,32 @@ private: using CsHookCb = ostd::Function; using CsPanicCb = ostd::Function; +template +struct CsAllocator { + using Value = T; + static constexpr bool PropagateOnContainerCopyAssignment = true; + static constexpr bool PropagateOnContainerMoveAssignment = true; + static constexpr bool PropagateOnContainerSwap = true; + + CsAllocator() = delete; + CsAllocator(CsAllocator const &a): p_state(a.p_state) {} + CsAllocator(CsState &cs): p_state(cs) {} + + T *allocate(ostd::Size n, void const * = nullptr); + void deallocate(T *p, ostd::Size n); + + bool operator==(CsAllocator const &o) const { + return &p_state != &o.p_state; + } + + bool operator!=(CsAllocator const &o) const { + return &p_state != &o.p_state; + } + +private: + CsState &p_state; +}; + struct OSTD_EXPORT CsState { CsMap idents; CsVector identmap; @@ -360,6 +386,13 @@ struct OSTD_EXPORT CsState { CsHookCb const &get_call_hook() const; CsHookCb &get_call_hook(); + template + CsHookCb set_call_hook(F &&f) { + return set_call_hook(CsHookCb( + ostd::allocator_arg, CsAllocator(*this), ostd::forward(f) + )); + } + virtual void *alloc(void *ptr, ostd::Size olds, ostd::Size news); void init_libs(int libs = CsLibAll); @@ -368,6 +401,13 @@ struct OSTD_EXPORT CsState { CsPanicCb const &get_panic_func() const; CsPanicCb &get_panic_func(); + template + CsPanicCb set_panic_func(F &&f) { + return set_panic_func(CsPanicCb( + ostd::allocator_arg, CsAllocator(*this), ostd::forward(f) + )); + } + template bool pcall( F func, ostd::String *error = nullptr, @@ -406,10 +446,45 @@ struct OSTD_EXPORT CsState { CsVarCb f = CsVarCb(), int flags = 0 ); + template + CsIvar *new_ivar( + ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v, F &&f, int flags = 0 + ) { + return new_ivar(n, m, x, v, CsVarCb( + ostd::allocator_arg, CsAllocator(*this), ostd::forward(f) + ), flags); + } + template + CsFvar *new_fvar( + ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v, F &&f, + int flags = 0 + ) { + return new_fvar(n, m, x, v, CsVarCb( + ostd::allocator_arg, CsAllocator(*this), ostd::forward(f) + ), flags); + } + template + CsSvar *new_svar( + ostd::ConstCharRange n, CsString v, F &&f, int flags = 0 + ) { + return new_svar(n, ostd::move(v), CsVarCb( + ostd::allocator_arg, CsAllocator(*this), ostd::forward(f) + ), flags); + } + CsCommand *new_command( ostd::ConstCharRange name, ostd::ConstCharRange args, CsCommandCb func ); + template + CsCommand *new_command( + ostd::ConstCharRange name, ostd::ConstCharRange args, F &&f + ) { + return new_command(name, args, CsCommandCb( + ostd::allocator_arg, CsAllocator(*this), ostd::forward(f) + )); + } + CsIdent *get_ident(ostd::ConstCharRange name) { CsIdent **id = idents.at(name); if (!id) { @@ -538,6 +613,16 @@ private: bool p_pushed; }; +template +T *CsAllocator::allocate(ostd::Size n, void const *) { + return static_cast(p_state.alloc(nullptr, 0, n * sizeof(T))); +} + +template +void CsAllocator::deallocate(T *p, ostd::Size n) { + p_state.alloc(p, n * sizeof(T), 0); +} + namespace util { template inline ostd::Size escape_string(R &&writer, ostd::ConstCharRange str) {