From c4e3328bb1ab1894b044e17e9efea2be1ffe65a7 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 10 Jun 2009 04:57:42 +0000 Subject: [PATCH] Support reassignment of undefined Boxed_Values --- boxedcpp/bootstrap.hpp | 32 ++++++++++++ boxedcpp/boxed_value.hpp | 99 +++++++++++++++++++++++++++++++----- boxedcpp/proxy_functions.hpp | 2 +- boxedcpp/type_info.hpp | 25 ++++++++- wesley/main.cpp | 2 +- 5 files changed, 144 insertions(+), 16 deletions(-) diff --git a/boxedcpp/bootstrap.hpp b/boxedcpp/bootstrap.hpp index 4dc6c86..2e5b8fb 100644 --- a/boxedcpp/bootstrap.hpp +++ b/boxedcpp/bootstrap.hpp @@ -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 std::string to_string(Input i) @@ -435,6 +466,7 @@ void bootstrap(BoxedCPP_System &s) register_function(s, &to_string, "to_string"); register_function(s, &to_string, "to_string"); + register_function(s, &unknown_assign, "="); bootstrap_pod_type(s, "double"); bootstrap_pod_type(s, "int"); diff --git a/boxedcpp/boxed_value.hpp b/boxedcpp/boxed_value.hpp index fe9f6f4..4ecbcd2 100644 --- a/boxedcpp/boxed_value.hpp +++ b/boxedcpp/boxed_value.hpp @@ -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 explicit Boxed_Value(boost::shared_ptr obj) - : m_type_info(Get_Type_Info()()), m_obj(obj), m_is_ref(false) + : m_data(new Data( + Get_Type_Info()(), + boost::any(obj), + false) + ) { } template explicit Boxed_Value(boost::reference_wrapper obj) - : m_type_info(Get_Type_Info()()), m_obj(obj), m_is_ref(true) + : m_data(new Data( + Get_Type_Info()(), + boost::any(obj), + true) + ) { } template explicit Boxed_Value(const T& t) - : m_type_info(Get_Type_Info()()), m_obj(boost::shared_ptr(new T(t))), m_is_ref(false) + : m_data(new Data( + Get_Type_Info()(), + boost::any(boost::shared_ptr(new T(t))), + false) + ) { } + Boxed_Value(Boxed_Value::Void_Type) + : m_data(new Data( + Get_Type_Info()(), + 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()()), 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 m_data; }; @@ -140,6 +215,7 @@ struct Cast_Helper } }; + 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 diff --git a/boxedcpp/proxy_functions.hpp b/boxedcpp/proxy_functions.hpp index 7d36d25..0dc56fa 100644 --- a/boxedcpp/proxy_functions.hpp +++ b/boxedcpp/proxy_functions.hpp @@ -59,7 +59,7 @@ struct Handle_Return Boxed_Value operator()(const boost::function &f) { f(); - return Boxed_Value(); + return Boxed_Value(Boxed_Value::Void_Type()); } }; diff --git a/boxedcpp/type_info.hpp b/boxedcpp/type_info.hpp index 6135cdc..5d2db8d 100644 --- a/boxedcpp/type_info.hpp +++ b/boxedcpp/type_info.hpp @@ -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 struct Get_Type_Info diff --git a/wesley/main.cpp b/wesley/main.cpp index 88fc1e0..f6bab7c 100644 --- a/wesley/main.cpp +++ b/wesley/main.cpp @@ -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: ";