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_ref), "is_var_reference");
m->add(fun(&Boxed_Value::is_pointer), "is_var_pointer"); m->add(fun(&Boxed_Value::is_pointer), "is_var_pointer");
m->add(fun(&Boxed_Value::is_type), "is_type"); 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(fun(&Boxed_Value::get_type_info), "get_type_info");
m->add(user_type<Type_Info>(), "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); 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::empty), "empty");
m->add(fun(&Bidir_Type::pop_front), "pop_front"); m->add(fun(&Bidir_Type::pop_front), "pop_front");

View File

@@ -205,10 +205,25 @@ namespace chaiscript
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *) static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
{ {
return ob; return ob;
} }
}; };
/**
* 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 * 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_data_ptr = rhs.m_data_ptr;
m_const_data_ptr = rhs.m_const_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; return *this;
} }
Data(const Data &) = delete;
~Data() ~Data()
{ {
} }
@@ -63,6 +70,7 @@ namespace chaiscript
void *m_data_ptr; void *m_data_ptr;
const void *m_const_data_ptr; const void *m_const_data_ptr;
bool m_is_ref; bool m_is_ref;
std::unique_ptr<std::map<std::string, Boxed_Value>> m_attrs;
}; };
struct Object_Data struct Object_Data
@@ -231,6 +239,25 @@ namespace chaiscript
return m_data->m_const_data_ptr; 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 /// \returns true if the two Boxed_Values share the same internal type
static bool type_match(Boxed_Value l, Boxed_Value r) static bool type_match(Boxed_Value l, Boxed_Value r)
{ {

View File

@@ -41,8 +41,10 @@ def new(x) {
} }
def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), 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;
} }
@@ -147,10 +149,16 @@ def reverse(container) {
# Return a range from a range # 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) 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 # The retro attribute that contains the underlying range
attr retro::m_range; attr retro::m_range;

View File

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