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