Add strong reference to range objects #132

This commit is contained in:
Jason Turner
2014-08-30 13:36:36 -06:00
parent 3fe80d70c6
commit a71903f185
6 changed files with 61 additions and 9 deletions

View File

@@ -447,6 +447,8 @@ namespace chaiscript
m->add(fun(&Boxed_Value::is_ref), "is_var_reference");
m->add(fun(&Boxed_Value::is_pointer), "is_var_pointer");
m->add(fun(&Boxed_Value::is_type), "is_type");
m->add(fun(&Boxed_Value::get_attr), "get_var_attr");
m->add(fun(&Boxed_Value::copy_attrs), "copy_var_attrs");
m->add(fun(&Boxed_Value::get_type_info), "get_type_info");
m->add(user_type<Type_Info>(), "Type_Info");

View File

@@ -185,7 +185,7 @@ namespace chaiscript
copy_constructor<Bidir_Type>(type + "_Range", m);
m->add(constructor<Bidir_Type (typename Bidir_Type::container_type &)>(), "range");
m->add(constructor<Bidir_Type (typename Bidir_Type::container_type &)>(), "range_internal");
m->add(fun(&Bidir_Type::empty), "empty");
m->add(fun(&Bidir_Type::pop_front), "pop_front");

View File

@@ -209,6 +209,21 @@ namespace chaiscript
}
};
/**
* Cast_Helper_Inner for casting to a Boxed_Value & type
*/
template<>
struct Cast_Helper_Inner<Boxed_Value &>
{
typedef Boxed_Value& Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
{
return const_cast<Boxed_Value &>(ob);
}
};
/**
* Cast_Helper_Inner for casting to a const Boxed_Value & type
*/

View File

@@ -51,9 +51,16 @@ namespace chaiscript
m_data_ptr = rhs.m_data_ptr;
m_const_data_ptr = rhs.m_const_data_ptr;
if (rhs.m_attrs)
{
m_attrs = std::unique_ptr<std::map<std::string, Boxed_Value>>(new std::map<std::string, Boxed_Value>(*rhs.m_attrs));
}
return *this;
}
Data(const Data &) = delete;
~Data()
{
}
@@ -63,6 +70,7 @@ namespace chaiscript
void *m_data_ptr;
const void *m_const_data_ptr;
bool m_is_ref;
std::unique_ptr<std::map<std::string, Boxed_Value>> m_attrs;
};
struct Object_Data
@@ -231,6 +239,25 @@ namespace chaiscript
return m_data->m_const_data_ptr;
}
Boxed_Value get_attr(const std::string &t_name)
{
if (!m_data->m_attrs)
{
m_data->m_attrs = std::unique_ptr<std::map<std::string, Boxed_Value>>(new std::map<std::string, Boxed_Value>());
}
return (*m_data->m_attrs)[t_name];
}
void copy_attrs(const Boxed_Value &t_obj)
{
if (t_obj.m_data->m_attrs)
{
m_data->m_attrs = std::unique_ptr<std::map<std::string, Boxed_Value>>(new std::map<std::string, Boxed_Value>(*t_obj.m_data->m_attrs));
}
}
/// \returns true if the two Boxed_Values share the same internal type
static bool type_match(Boxed_Value l, Boxed_Value r)
{

View File

@@ -42,7 +42,9 @@ def new(x) {
def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x)
{
eval(type_name(x))(x);
var c := eval(type_name(x))(x);
c.copy_var_attrs(x);
return c;
}
@@ -148,9 +150,15 @@ def reverse(container) {
# Return a range from a range
def range(r) : call_exists(empty, r) && call_exists(pop_front, r) && call_exists(pop_back, r) && call_exists(back, r) && call_exists(front, r)
{
return clone(r);
clone(r);
}
def range(r) : call_exists(range_internal, r)
{
var ri := range_internal(r);
ri.get_var_attr("internal_obj") := r;
return ri;
}
# The retro attribute that contains the underlying range
attr retro::m_range;

View File

@@ -17,15 +17,15 @@
#else
char *mystrdup (const char *s) {
size_t len = strlen(s) + 1; // Space for length plus nul
char *d = static_cast<char*>(malloc (len));
size_t len = strlen(s); // Space for length plus nul
char *d = static_cast<char*>(malloc (len+1));
if (d == nullptr) return nullptr; // No memory
#ifdef CHAISCRIPT_MSVC
strcpy_s(d, len, s); // Copy the characters
#else
strncpy(d,s,len); // Copy the characters
d[len] = '\0';
#endif
d[len] = '\0';
return d; // Return the new string
}