Support reassignment of undefined Boxed_Values

This commit is contained in:
Jason Turner 2009-06-10 04:57:42 +00:00
parent 53c3e2ee25
commit c4e3328bb1
5 changed files with 144 additions and 16 deletions

View File

@ -394,6 +394,37 @@ void add_opers_arithmetic(BoxedCPP_System &s)
}
class bad_boxed_value_cast : public std::bad_cast
{
public:
bad_boxed_value_cast(const std::string &val) throw()
: m_val(val)
{
}
virtual ~bad_boxed_value_cast() throw()
{
}
virtual const char * what() const throw()
{
return m_val.c_str();
}
private:
std::string m_val;
};
Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs)
{
if (lhs.is_unknown())
{
return (lhs.assign(rhs));
} else {
throw bad_boxed_value_cast("boxed_value has a set type alread");
}
}
//Built in to_string operator
template<typename Input>
std::string to_string(Input i)
@ -435,6 +466,7 @@ void bootstrap(BoxedCPP_System &s)
register_function(s, &to_string<const std::string &>, "to_string");
register_function(s, &to_string<bool>, "to_string");
register_function(s, &unknown_assign, "=");
bootstrap_pod_type<double>(s, "double");
bootstrap_pod_type<int>(s, "int");

View File

@ -9,54 +9,129 @@
class Boxed_Value
{
private:
struct Data
{
Data(const Type_Info &ti,
const boost::any &to,
bool tr)
: m_type_info(ti), m_obj(to), m_is_ref(tr)
{
}
Data &operator=(const Data &rhs)
{
m_type_info = rhs.m_type_info;
m_obj = rhs.m_obj;
m_is_ref = rhs.m_is_ref;
return *this;
}
Type_Info m_type_info;
boost::any m_obj;
bool m_is_ref;
};
public:
struct Void_Type
{
};
template<typename T>
explicit Boxed_Value(boost::shared_ptr<T> obj)
: m_type_info(Get_Type_Info<T>()()), m_obj(obj), m_is_ref(false)
: m_data(new Data(
Get_Type_Info<T>()(),
boost::any(obj),
false)
)
{
}
template<typename T>
explicit Boxed_Value(boost::reference_wrapper<T> obj)
: m_type_info(Get_Type_Info<T>()()), m_obj(obj), m_is_ref(true)
: m_data(new Data(
Get_Type_Info<T>()(),
boost::any(obj),
true)
)
{
}
template<typename T>
explicit Boxed_Value(const T& t)
: m_type_info(Get_Type_Info<T>()()), m_obj(boost::shared_ptr<T>(new T(t))), m_is_ref(false)
: m_data(new Data(
Get_Type_Info<T>()(),
boost::any(boost::shared_ptr<T>(new T(t))),
false)
)
{
}
Boxed_Value(Boxed_Value::Void_Type)
: m_data(new Data(
Get_Type_Info<void>()(),
boost::any(),
false)
)
{
}
Boxed_Value(const Boxed_Value &t_so)
: m_type_info(t_so.m_type_info), m_obj(t_so.m_obj), m_is_ref(t_so.m_is_ref)
: m_data(t_so.m_data)
{
}
Boxed_Value()
: m_type_info(Get_Type_Info<void>()()), m_is_ref(false)
: m_data(new Data(
Type_Info(),
boost::any(),
false)
)
{
}
Boxed_Value assign(const Boxed_Value &rhs)
{
(*m_data) = (*rhs.m_data);
return *this;
}
Boxed_Value &operator=(const Boxed_Value &rhs)
{
m_data = rhs.m_data;
/*
std::cout << "operator= called" << std::endl;
m_data->m_obj = rhs.m_data->m_obj;
m_data->m_type_info = rhs.m_data->m_type_info;
m_data->m_is_ref = rhs.m_data->m_is_ref;
(*m_data) = (*rhs.m_data);
*/
return *this;
}
const Type_Info &get_type_info() const
{
return m_type_info;
return m_data->m_type_info;
}
bool is_unknown() const
{
return m_data->m_type_info.m_is_unknown;
}
boost::any get() const
{
return m_obj;
return m_data->m_obj;
}
bool is_ref() const
{
return m_is_ref;
return m_data->m_is_ref;
}
private:
Type_Info m_type_info;
boost::any m_obj;
bool m_is_ref;
boost::shared_ptr<Data> m_data;
};
@ -140,6 +215,7 @@ struct Cast_Helper<Boxed_Value>
}
};
struct Boxed_POD_Value
{
Boxed_POD_Value(const Boxed_Value &v)
@ -205,7 +281,6 @@ struct Boxed_POD_Value
throw boost::bad_any_cast();
}
}
bool operator==(const Boxed_POD_Value &r) const

View File

@ -59,7 +59,7 @@ struct Handle_Return<void>
Boxed_Value operator()(const boost::function<void ()> &f)
{
f();
return Boxed_Value();
return Boxed_Value(Boxed_Value::Void_Type());
}
};

View File

@ -8,17 +8,38 @@ struct Type_Info
Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
const std::type_info *t_ti, const std::type_info *t_bareti)
: m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer),
m_type_info(t_ti), m_bare_type_info(t_bareti)
m_type_info(t_ti), m_bare_type_info(t_bareti),
m_is_unknown(false)
{
}
Type_Info()
: m_is_const(false), m_is_reference(false), m_is_pointer(false),
m_is_void(false), m_type_info(0), m_bare_type_info(0),
m_is_unknown(true)
{
}
Type_Info &operator=(const Type_Info &ti)
{
m_is_const = ti.m_is_const;
m_is_reference = ti.m_is_reference;
m_is_pointer = ti.m_is_pointer;
m_is_void = ti.m_is_void;
m_type_info = ti.m_type_info;
m_bare_type_info = ti.m_bare_type_info;
m_is_unknown = ti.m_is_unknown;
return *this;
}
bool m_is_const;
bool m_is_reference;
bool m_is_pointer;
bool m_is_void;
const std::type_info *m_type_info;
const std::type_info *m_bare_type_info;
};
bool m_is_unknown;
};
template<typename T>
struct Get_Type_Info

View File

@ -698,7 +698,7 @@ int main(int argc, char *argv[]) {
catch (const ReturnValue &rv) {
val = rv.retval;
}
if (*(val.get_type_info().m_bare_type_info) != typeid(void)) {
if (val.get_type_info().m_bare_type_info && *(val.get_type_info().m_bare_type_info) != typeid(void)) {
try {
Boxed_Value printeval = dispatch(ss.get_function("to_string"), Param_List_Builder() << val);
std::cout << "result: ";