only store trivial types in any_value (manage strrefs manually)
parent
d358dd83e7
commit
3ed7b59d0b
|
@ -60,9 +60,7 @@ struct LIBCUBESCRIPT_EXPORT string_ref {
|
|||
return std::string_view{*this}.length();
|
||||
}
|
||||
|
||||
char const *data() const {
|
||||
return std::string_view{*this}.data();
|
||||
}
|
||||
char const *data() const;
|
||||
|
||||
std::string_view view() const {
|
||||
return std::string_view{*this};
|
||||
|
@ -75,8 +73,7 @@ struct LIBCUBESCRIPT_EXPORT string_ref {
|
|||
bool operator==(string_ref const &s) const;
|
||||
|
||||
private:
|
||||
/* for internal use only */
|
||||
string_ref(char const *p, internal_state *cs);
|
||||
string_ref(char const *p);
|
||||
|
||||
char const *p_str;
|
||||
};
|
||||
|
@ -124,12 +121,7 @@ struct LIBCUBESCRIPT_EXPORT any_value {
|
|||
ident &force_ident(state &cs);
|
||||
|
||||
private:
|
||||
std::aligned_union_t<1,
|
||||
integer_type,
|
||||
float_type,
|
||||
void *,
|
||||
string_ref
|
||||
> p_stor;
|
||||
std::aligned_union_t<1, integer_type, float_type, void *> p_stor;
|
||||
value_type p_type;
|
||||
};
|
||||
|
||||
|
|
|
@ -54,12 +54,12 @@ string_ref string_pool::steal(char *ptr) {
|
|||
if (st) {
|
||||
/* the buffer is superfluous now */
|
||||
cstate->alloc(ss, ss->length + sizeof(string_ref_state) + 1, 0);
|
||||
return string_ref{reinterpret_cast<char const *>(st + 1), cstate};
|
||||
return string_ref{reinterpret_cast<char const *>(st + 1)};
|
||||
}
|
||||
}
|
||||
ss->refcount = 0; /* string_ref will increment it */
|
||||
counts.emplace(sr, ss);
|
||||
return string_ref{ptr, cstate};
|
||||
return string_ref{ptr};
|
||||
}
|
||||
|
||||
void string_pool::unref(char const *ptr) {
|
||||
|
@ -108,9 +108,19 @@ char *string_pool::alloc_buf(std::size_t len) const {
|
|||
return strp;
|
||||
}
|
||||
|
||||
/* strref implementation */
|
||||
char const *str_managed_ref(char const *str) {
|
||||
return get_ref_state(str)->state->strman->ref(str);
|
||||
}
|
||||
|
||||
/* strref */
|
||||
void str_managed_unref(char const *str) {
|
||||
get_ref_state(str)->state->strman->unref(str);
|
||||
}
|
||||
|
||||
std::string_view str_managed_view(char const *str) {
|
||||
return get_ref_state(str)->state->strman->get(str);
|
||||
}
|
||||
|
||||
/* strref implementation */
|
||||
|
||||
LIBCUBESCRIPT_EXPORT string_ref::string_ref(
|
||||
internal_state *cs, std::string_view str
|
||||
|
@ -129,24 +139,25 @@ LIBCUBESCRIPT_EXPORT string_ref::string_ref(string_ref const &ref):
|
|||
}
|
||||
|
||||
/* this can be used by friends to do quick string_ref creation */
|
||||
LIBCUBESCRIPT_EXPORT string_ref::string_ref(
|
||||
char const *p, internal_state *cs
|
||||
) {
|
||||
p_str = cs->strman->ref(p);
|
||||
LIBCUBESCRIPT_EXPORT string_ref::string_ref(char const *p) {
|
||||
p_str = str_managed_ref(p);
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT string_ref::~string_ref() {
|
||||
get_ref_state(p_str)->state->strman->unref(p_str);
|
||||
str_managed_unref(p_str);
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT string_ref &string_ref::operator=(string_ref const &ref) {
|
||||
p_str = ref.p_str;
|
||||
get_ref_state(p_str)->state->strman->ref(p_str);
|
||||
p_str = str_managed_ref(ref.p_str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT char const *string_ref::data() const {
|
||||
return p_str;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT string_ref::operator std::string_view() const {
|
||||
return get_ref_state(p_str)->state->strman->get(p_str);
|
||||
return str_managed_view(p_str);
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT bool string_ref::operator==(string_ref const &s) const {
|
||||
|
|
|
@ -13,6 +13,10 @@ namespace cubescript {
|
|||
|
||||
struct string_ref_state;
|
||||
|
||||
char const *str_managed_ref(char const *str);
|
||||
void str_managed_unref(char const *str);
|
||||
std::string_view str_managed_view(char const *str);
|
||||
|
||||
/* string manager
|
||||
*
|
||||
* the purpose of this is to handle interning of strings; each string within
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "cs_std.hh"
|
||||
#include "cs_parser.hh"
|
||||
#include "cs_state.hh"
|
||||
#include "cs_strman.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
|
@ -66,7 +67,7 @@ template<typename T>
|
|||
static inline void csv_cleanup(value_type tv, T *stor) {
|
||||
switch (tv) {
|
||||
case value_type::STRING:
|
||||
csv_get<string_ref>(stor).~string_ref();
|
||||
str_managed_unref(csv_get<char const *>(stor));
|
||||
break;
|
||||
case value_type::CODE: {
|
||||
bcode_unref(csv_get<uint32_t *>(stor));
|
||||
|
@ -105,9 +106,8 @@ any_value &any_value::operator=(any_value const &v) {
|
|||
break;
|
||||
case value_type::STRING:
|
||||
p_type = value_type::STRING;
|
||||
new (&csv_get<string_ref>(&p_stor)) string_ref{
|
||||
csv_get<string_ref>(&v.p_stor)
|
||||
};
|
||||
p_stor = v.p_stor;
|
||||
str_managed_ref(csv_get<char const *>(&p_stor));
|
||||
break;
|
||||
case value_type::CODE:
|
||||
set_code(v.get_code());
|
||||
|
@ -142,13 +142,13 @@ void any_value::set_float(float_type val) {
|
|||
|
||||
void any_value::set_string(std::string_view val, state &cs) {
|
||||
csv_cleanup(p_type, &p_stor);
|
||||
new (&csv_get<string_ref>(&p_stor)) string_ref{cs, val};
|
||||
csv_get<char const *>(&p_stor) = state_p{cs}.ts().istate->strman->add(val);
|
||||
p_type = value_type::STRING;
|
||||
}
|
||||
|
||||
void any_value::set_string(string_ref const &val) {
|
||||
csv_cleanup(p_type, &p_stor);
|
||||
new (&csv_get<string_ref>(&p_stor)) string_ref{val};
|
||||
csv_get<char const *>(&p_stor) = str_managed_ref(val.p_str);
|
||||
p_type = value_type::STRING;
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ float_type any_value::force_float() {
|
|||
rf = float_type(csv_get<integer_type>(&p_stor));
|
||||
break;
|
||||
case value_type::STRING:
|
||||
rf = parse_float(csv_get<string_ref>(&p_stor));
|
||||
rf = parse_float(str_managed_view(csv_get<char const *>(&p_stor)));
|
||||
break;
|
||||
case value_type::FLOAT:
|
||||
return csv_get<float_type>(&p_stor);
|
||||
|
@ -215,7 +215,7 @@ integer_type any_value::force_integer() {
|
|||
ri = integer_type(std::floor(csv_get<float_type>(&p_stor)));
|
||||
break;
|
||||
case value_type::STRING:
|
||||
ri = parse_int(csv_get<string_ref>(&p_stor));
|
||||
ri = parse_int(str_managed_view(csv_get<char const *>(&p_stor)));
|
||||
break;
|
||||
case value_type::INTEGER:
|
||||
return csv_get<integer_type>(&p_stor);
|
||||
|
@ -237,13 +237,13 @@ std::string_view any_value::force_string(state &cs) {
|
|||
str = intstr(csv_get<integer_type>(&p_stor), rs);
|
||||
break;
|
||||
case value_type::STRING:
|
||||
return csv_get<string_ref>(&p_stor);
|
||||
return str_managed_view(csv_get<char const *>(&p_stor));
|
||||
default:
|
||||
str = rs.str();
|
||||
break;
|
||||
}
|
||||
set_string(str, cs);
|
||||
return csv_get<string_ref>(&p_stor);
|
||||
return str_managed_view(csv_get<char const *>(&p_stor));
|
||||
}
|
||||
|
||||
bcode_ref any_value::force_code(state &cs) {
|
||||
|
@ -281,7 +281,7 @@ integer_type any_value::get_integer() const {
|
|||
case value_type::INTEGER:
|
||||
return csv_get<integer_type>(&p_stor);
|
||||
case value_type::STRING:
|
||||
return parse_int(csv_get<string_ref>(&p_stor));
|
||||
return parse_int(str_managed_view(csv_get<char const *>(&p_stor)));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -295,7 +295,9 @@ float_type any_value::get_float() const {
|
|||
case value_type::INTEGER:
|
||||
return float_type(csv_get<integer_type>(&p_stor));
|
||||
case value_type::STRING:
|
||||
return parse_float(csv_get<string_ref>(&p_stor));
|
||||
return parse_float(
|
||||
str_managed_view(csv_get<char const *>(&p_stor))
|
||||
);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -319,7 +321,7 @@ ident *any_value::get_ident() const {
|
|||
string_ref any_value::get_string(state &cs) const {
|
||||
switch (get_type()) {
|
||||
case value_type::STRING:
|
||||
return csv_get<string_ref>(&p_stor);
|
||||
return string_ref{csv_get<char const *>(&p_stor)};
|
||||
case value_type::INTEGER: {
|
||||
charbuf rs{cs};
|
||||
return string_ref{
|
||||
|
@ -357,7 +359,9 @@ bool any_value::get_bool() const {
|
|||
case value_type::INTEGER:
|
||||
return csv_get<integer_type>(&p_stor) != 0;
|
||||
case value_type::STRING: {
|
||||
std::string_view s = csv_get<string_ref>(&p_stor);
|
||||
std::string_view s = str_managed_view(
|
||||
csv_get<char const *>(&p_stor)
|
||||
);
|
||||
if (s.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue