#ifndef LIBCUBESCRIPT_STD_HH #define LIBCUBESCRIPT_STD_HH #include #include #include #include #include #include #include "cs_state.hh" namespace cubescript { struct state; /* run func, call the second one after finishing */ template inline void call_with_cleanup(F1 &&dof, F2 &&clf) { struct scope_exit { scope_exit(std::decay_t &f): func(&f) {} ~scope_exit() { (*func)(); } std::decay_t *func; }; scope_exit cleanup(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) { std::launder(reinterpret_cast(&stor[i]))->~T(); } } T &operator[](std::size_t i) { return *std::launder(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}} {} 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 resize(std::size_t s, value_type const &v) { buf.resize(s, v); } void append(T const *beg, T const *end) { buf.insert(buf.end(), beg, end); } template reference emplace_back(A &&...args) { return buf.emplace_back(std::forward(args)...); } 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); 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