2016-08-15 01:19:59 +00:00
|
|
|
#ifndef LIBCUBESCRIPT_CS_UTIL_HH
|
|
|
|
#define LIBCUBESCRIPT_CS_UTIL_HH
|
|
|
|
|
2017-02-09 19:59:14 +00:00
|
|
|
#include <type_traits>
|
2017-04-23 13:34:45 +00:00
|
|
|
#include <unordered_map>
|
2017-02-09 19:59:14 +00:00
|
|
|
|
2016-08-15 01:19:59 +00:00
|
|
|
#include <ostd/string.hh>
|
|
|
|
|
|
|
|
namespace cscript {
|
|
|
|
|
2016-11-11 21:19:51 +00:00
|
|
|
template<typename K, typename V>
|
2018-04-27 21:53:55 +00:00
|
|
|
using cs_map = std::unordered_map<K, V>;
|
2016-11-11 21:19:51 +00:00
|
|
|
|
|
|
|
template<typename T>
|
2018-04-27 21:53:55 +00:00
|
|
|
using cs_vector = std::vector<T>;
|
2016-11-11 21:19:51 +00:00
|
|
|
|
2017-02-13 17:10:40 +00:00
|
|
|
cs_int cs_parse_int(
|
2017-02-16 18:07:22 +00:00
|
|
|
ostd::string_range input, ostd::string_range *end = nullptr
|
2016-08-15 01:19:59 +00:00
|
|
|
);
|
|
|
|
|
2017-02-13 17:10:40 +00:00
|
|
|
cs_float cs_parse_float(
|
2017-02-16 18:07:22 +00:00
|
|
|
ostd::string_range input, ostd::string_range *end = nullptr
|
2016-08-15 01:19:59 +00:00
|
|
|
);
|
|
|
|
|
2016-09-08 21:42:14 +00:00
|
|
|
template<typename F>
|
|
|
|
struct CsScopeExit {
|
|
|
|
template<typename FF>
|
2017-01-25 00:57:33 +00:00
|
|
|
CsScopeExit(FF &&f): func(std::forward<FF>(f)) {}
|
2016-09-08 21:42:14 +00:00
|
|
|
~CsScopeExit() {
|
|
|
|
func();
|
|
|
|
}
|
2017-02-09 19:59:14 +00:00
|
|
|
std::decay_t<F> func;
|
2016-09-08 21:42:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template<typename F1, typename F2>
|
|
|
|
inline void cs_do_and_cleanup(F1 &&dof, F2 &&clf) {
|
2017-01-25 00:57:33 +00:00
|
|
|
CsScopeExit<F2> cleanup(std::forward<F2>(clf));
|
2016-09-08 21:42:14 +00:00
|
|
|
dof();
|
|
|
|
}
|
|
|
|
|
2021-03-15 23:44:25 +00:00
|
|
|
struct cs_shared_state;
|
|
|
|
|
|
|
|
/* string manager
|
|
|
|
*
|
|
|
|
* the purpose of this is to handle interning of strings; each string within
|
|
|
|
* a libcs state is represented (and allocated) exactly once, and reference
|
|
|
|
* counted; that both helps save resources, and potentially provide a means
|
|
|
|
* to reliably represent returned strings in places that is compatible with
|
|
|
|
* multiple threads and eliminate the chance of dangling pointers
|
|
|
|
*
|
|
|
|
* strings are allocated in a manner where the refcount and length are stored
|
|
|
|
* as a part of the string's memory, so it can be easily accessed using just
|
|
|
|
* the pointer to the string, but also this is transparent for usage
|
|
|
|
*
|
|
|
|
* this is not thread-safe yet, and later on it should be made that,
|
|
|
|
* for now we don't bother...
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct cs_strref_state {
|
|
|
|
size_t length;
|
|
|
|
size_t refcount;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct cs_strman {
|
|
|
|
cs_strman() = delete;
|
|
|
|
cs_strman(cs_shared_state *cs): cstate{cs} {}
|
|
|
|
~cs_strman() {}
|
|
|
|
|
|
|
|
cs_strman(cs_strman const &) = delete;
|
|
|
|
cs_strman(cs_strman &&) = delete;
|
|
|
|
|
|
|
|
cs_strman &operator=(cs_strman const &) = delete;
|
|
|
|
cs_strman &operator=(cs_strman &&) = delete;
|
|
|
|
|
|
|
|
/* adds a string into the manager using any source, and returns a managed
|
|
|
|
* version; this is "slow" as it has to hash the string and potentially
|
|
|
|
* allocate fresh memory for it, but is perfectly safe at any time
|
|
|
|
*/
|
|
|
|
char const *add(ostd::string_range str);
|
|
|
|
|
|
|
|
/* this simply increments the reference count of an existing managed
|
|
|
|
* string, this is only safe when you know the pointer you are passing
|
|
|
|
* is already managed the system
|
|
|
|
*/
|
|
|
|
char const *ref(char const *ptr);
|
|
|
|
|
|
|
|
/* decrements the reference count and removes it from the system if
|
|
|
|
* that reaches zero; likewise, only safe with pointers that are managed
|
|
|
|
*/
|
|
|
|
void unref(char const *ptr);
|
|
|
|
|
|
|
|
/* just finds a managed pointer with the same contents
|
|
|
|
* as the input, if not found then a null pointer is returned
|
|
|
|
*/
|
|
|
|
char const *find(ostd::string_range str) const;
|
|
|
|
|
|
|
|
/* a quick helper to make a proper ostd string range out of a ptr */
|
|
|
|
ostd::string_range get(char const *ptr) const;
|
|
|
|
|
|
|
|
cs_shared_state *cstate;
|
|
|
|
/* FIXME: use main allocator */
|
|
|
|
std::unordered_map<ostd::string_range, cs_strref_state *> counts{};
|
|
|
|
};
|
|
|
|
|
2016-08-15 01:19:59 +00:00
|
|
|
} /* namespace cscript */
|
|
|
|
|
|
|
|
#endif /* LIBCUBESCRIPT_CS_UTIL_HH */
|