#ifndef LIBCUBESCRIPT_STD_HH #define LIBCUBESCRIPT_STD_HH #include #include #include #include #include #include "cs_state.hh" namespace cubescript { /* run func, call the second one after finishing */ template struct CsScopeExit { template CsScopeExit(FF &&f): func(std::forward(f)) {} ~CsScopeExit() { func(); } std::decay_t func; }; template inline void call_with_cleanup(F1 &&dof, F2 &&clf) { CsScopeExit cleanup(std::forward(clf)); dof(); } /* a simple static array with elements constructed using ctor args */ template struct valarray { template valarray(A &&...args) { for (std::size_t i = 0; i < N; ++i) { new (&stor[i]) T{std::forward(args)...}; } } ~valarray() { for (std::size_t i = 0; i < N; ++i) { reinterpret_cast(&stor[i])->~T(); } } T &operator[](std::size_t i) { return *reinterpret_cast(&stor[i]); } std::aligned_storage_t stor[N]; }; /* a value buffer */ template struct valbuf { valbuf() = delete; valbuf(internal_state *cs): buf{std_allocator{cs}} {} valbuf(state &cs): buf{std_allocator{cs}} {} using size_type = std::size_t; using value_type = T; using reference = T &; using const_reference = T const &; void reserve(std::size_t s) { buf.reserve(s); } void resize(std::size_t s) { buf.resize(s); } void append(T const *beg, T const *end) { buf.insert(buf.end(), beg, end); } void push_back(T const &v) { buf.push_back(v); } void pop_back() { buf.pop_back(); } T &back() { return buf.back(); } T const &back() const { return buf.back(); } std::size_t size() const { return buf.size(); } std::size_t capacity() const { return buf.capacity(); } bool empty() const { return buf.empty(); } void clear() { buf.clear(); } T &operator[](std::size_t i) { return buf[i]; } T const &operator[](std::size_t i) const { return buf[i]; } T *data() { return &buf[0]; } T const *data() const { return &buf[0]; } std::vector> buf; }; /* specialization of value buffer for bytes */ struct charbuf: valbuf { charbuf(internal_state *cs): valbuf{cs} {} charbuf(state &cs): valbuf{cs} {} void append(char const *beg, char const *end) { valbuf::append(beg, end); } void append(std::string_view v) { append(&v[0], &v[v.size()]); } std::string_view str() { return std::string_view{buf.data(), buf.size()}; } std::string_view str_term() { return std::string_view{buf.data(), buf.size() - 1}; } }; } /* namespace cubescript */ #endif