From 2afc09dad488dc8736a41b52b1824a918da291da Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 25 Feb 2013 11:00:14 -0700 Subject: [PATCH] Eradicate global base_class registrations to prevent problems with threading and general memory management issues with knowing how and when to clean them up. --- include/chaiscript/dispatchkit/bootstrap.hpp | 19 -- include/chaiscript/dispatchkit/boxed_cast.hpp | 6 +- .../dispatchkit/boxed_cast_helper.hpp | 20 +- .../chaiscript/dispatchkit/boxed_number.hpp | 2 +- .../chaiscript/dispatchkit/dispatchkit.hpp | 50 +++- .../dispatchkit/dynamic_cast_conversion.hpp | 238 ++++++++---------- .../chaiscript/dispatchkit/dynamic_object.hpp | 36 +-- .../dispatchkit/exception_specification.hpp | 46 ++-- .../chaiscript/dispatchkit/function_call.hpp | 30 +-- .../dispatchkit/function_call_detail.hpp | 17 +- .../dispatchkit/proxy_functions.hpp | 97 ++++--- .../dispatchkit/proxy_functions_detail.hpp | 16 +- .../chaiscript/language/chaiscript_engine.hpp | 29 ++- .../chaiscript/language/chaiscript_eval.hpp | 10 +- samples/example.cpp | 4 +- unittests/eval_catch_exception_test.cpp | 2 +- 16 files changed, 308 insertions(+), 314 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 6fcc11c..25852c6 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -273,21 +273,6 @@ namespace chaiscript std::vector(params.begin() + 1, params.end())))); } - /** - * Returns true if a call can be made that consists of the first parameter - * (the function) with the remaining parameters as its arguments. - */ - static Boxed_Value call_exists(const std::vector ¶ms) - { - if (params.size() < 1) - { - throw exception::arity_error(static_cast(params.size()), 1); - } - - Const_Proxy_Function f = boxed_cast(params[0]); - - return Boxed_Value(f->call_match(std::vector(params.begin() + 1, params.end()))); - } static bool has_guard(const Const_Proxy_Function &t_pf) { @@ -383,7 +368,6 @@ namespace chaiscript m->add(fun(&dispatch::Proxy_Function_Base::get_arity), "get_arity"); m->add(fun(&dispatch::Proxy_Function_Base::annotation), "get_annotation"); - m->add(fun(&dispatch::Proxy_Function_Base::operator()), "call"); m->add(fun(&dispatch::Proxy_Function_Base::operator==), "=="); @@ -476,9 +460,6 @@ namespace chaiscript m->add(fun(&ptr_assign::type>), "="); m->add(fun(&ptr_assign::type>), "="); - m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(boost::bind(&call_exists, _1))), - "call_exists"); - m->add(fun(&type_match), "type_match"); return m; diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index 43a3f19..e172d32 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -68,10 +68,10 @@ namespace chaiscript /// assert(i == 5); /// \endcode template - typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) + typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv, const Dynamic_Cast_Conversions &t_conversions = Dynamic_Cast_Conversions()) { try { - return detail::Cast_Helper::cast(bv); + return detail::Cast_Helper::cast(bv, t_conversions); } catch (const boost::bad_any_cast &) { #ifdef BOOST_MSVC @@ -86,7 +86,7 @@ namespace chaiscript try { // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it // either way, we are not responsible if it doesn't work - return detail::Cast_Helper::cast(detail::boxed_dynamic_cast(bv)); + return detail::Cast_Helper::cast(t_conversions.boxed_dynamic_cast(bv), t_conversions); } catch (const boost::bad_any_cast &) { throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type)); } diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index 44d38e0..8c9ed44 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -17,6 +17,8 @@ namespace chaiscript { + class Dynamic_Cast_Conversions; + namespace detail { // Cast_Helper_Inner helper classes @@ -29,7 +31,7 @@ namespace chaiscript { typedef typename boost::reference_wrapper::type > Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { if (ob.is_ref()) { @@ -71,7 +73,7 @@ namespace chaiscript { typedef const Result * Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { if (ob.is_ref()) { @@ -100,7 +102,7 @@ namespace chaiscript { typedef Result * Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { if (ob.is_ref()) { @@ -119,7 +121,7 @@ namespace chaiscript { typedef typename boost::reference_wrapper Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { if (ob.is_ref()) { @@ -138,7 +140,7 @@ namespace chaiscript { typedef typename boost::shared_ptr Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { return boost::any_cast >(ob.get()); } @@ -152,7 +154,7 @@ namespace chaiscript { typedef typename boost::shared_ptr Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { if (!ob.get_type_info().is_const()) { @@ -200,7 +202,7 @@ namespace chaiscript { typedef const Boxed_Value & Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { return ob; } @@ -261,9 +263,9 @@ namespace chaiscript { typedef typename Cast_Helper_Inner::Result_Type Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &t_conversions) { - return Cast_Helper_Inner::cast(ob); + return Cast_Helper_Inner::cast(ob, t_conversions); } }; } diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 33f515f..07522cd 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -820,7 +820,7 @@ namespace chaiscript { typedef Boxed_Number Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { return Boxed_Number(ob); } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index b6036c3..c67f24a 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -222,9 +222,9 @@ namespace chaiscript public: Dispatch_Function(const std::vector &t_funcs) : Proxy_Function_Base(build_type_infos(t_funcs)), - m_funcs(t_funcs) - { - } + m_funcs(t_funcs) + { + } virtual bool operator==(const dispatch::Proxy_Function_Base &rhs) const { @@ -274,7 +274,7 @@ namespace chaiscript return -1; // unknown arity } - virtual bool call_match(const std::vector &vals) const + virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const { typedef std::vector function_vec; @@ -283,7 +283,7 @@ namespace chaiscript while (begin != end) { - if ((*begin)->call_match(vals)) + if ((*begin)->call_match(vals, t_conversions)) { return true; } else { @@ -300,9 +300,9 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const + virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { - return dispatch::dispatch(m_funcs.begin(), m_funcs.end(), params); + return dispatch::dispatch(m_funcs.begin(), m_funcs.end(), params, t_conversions); } private: @@ -389,16 +389,21 @@ namespace chaiscript ~Dispatch_Engine() { - detail::Dynamic_Conversions::get().cleanup(m_conversions.begin(), m_conversions.end()); } + /// \brief casts an object while applying any Dynamic_Conversion available + template + typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) const + { + return chaiscript::boxed_cast(bv, m_conversions); + } + /** * Add a new conversion for upcasting to a base class */ void add(const Dynamic_Cast_Conversion &d) { - m_conversions.push_back(d); - return detail::Dynamic_Conversions::get().add_conversion(d); + m_conversions.add_conversion(d); } /** @@ -771,11 +776,16 @@ namespace chaiscript m_state.m_reserved_words.insert(name); } + const Dynamic_Cast_Conversions &conversions() const + { + return m_conversions; + } + Boxed_Value call_function(const std::string &t_name, const std::vector ¶ms) const { std::vector functions = get_function(t_name); - return dispatch::dispatch(functions.begin(), functions.end(), params); + return dispatch::dispatch(functions.begin(), functions.end(), params, m_conversions); } Boxed_Value call_function(const std::string &t_name) const @@ -844,6 +854,22 @@ namespace chaiscript std::cout << ") " << std::endl; } + /** + * Returns true if a call can be made that consists of the first parameter + * (the function) with the remaining parameters as its arguments. + */ + Boxed_Value call_exists(const std::vector ¶ms) + { + if (params.size() < 1) + { + throw exception::arity_error(static_cast(params.size()), 1); + } + + Const_Proxy_Function f = this->boxed_cast(params[0]); + + return Boxed_Value(f->call_match(std::vector(params.begin() + 1, params.end()), m_conversions)); + } + /** * Dump all system info to stdout */ @@ -1146,7 +1172,7 @@ namespace chaiscript int call_depth; }; - std::vector m_conversions; + Dynamic_Cast_Conversions m_conversions; chaiscript::detail::threading::Thread_Storage m_stack_holder; diff --git a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp index d6c16e7..7de42bd 100644 --- a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp +++ b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp @@ -47,7 +47,7 @@ namespace chaiscript class Dynamic_Conversion { public: - virtual Boxed_Value convert(const Boxed_Value &derived) = 0; + virtual Boxed_Value convert(const Boxed_Value &derived) const = 0; const Type_Info &base() { @@ -73,7 +73,7 @@ namespace chaiscript }; template - class Dynamic_Conversion_Impl : public Dynamic_Conversion + class Dynamic_Conversion_Impl : public Dynamic_Conversion { public: Dynamic_Conversion_Impl() @@ -81,7 +81,7 @@ namespace chaiscript { } - virtual Boxed_Value convert(const Boxed_Value &t_derived) + virtual Boxed_Value convert(const Boxed_Value &t_derived) const { if (t_derived.get_type_info().bare_equal(user_type())) { @@ -91,7 +91,7 @@ namespace chaiscript if (t_derived.is_const()) { boost::shared_ptr data - = boost::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived)); + = boost::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived, Dynamic_Cast_Conversions())); if (!data) { throw std::bad_cast(); @@ -100,7 +100,7 @@ namespace chaiscript return Boxed_Value(data); } else { boost::shared_ptr data - = boost::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived)); + = boost::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived, Dynamic_Cast_Conversions())); if (!data) { @@ -113,11 +113,11 @@ namespace chaiscript // Pull the reference out of the contained boxed value, which we know is the type we want if (t_derived.is_const()) { - const Derived &d = detail::Cast_Helper::cast(t_derived); + const Derived &d = detail::Cast_Helper::cast(t_derived, Dynamic_Cast_Conversions()); const Base &data = dynamic_cast(d); return Boxed_Value(boost::cref(data)); } else { - Derived &d = detail::Cast_Helper::cast(t_derived); + Derived &d = detail::Cast_Helper::cast(t_derived, Dynamic_Cast_Conversions()); Base &data = dynamic_cast(d); return Boxed_Value(boost::ref(data)); } @@ -127,101 +127,98 @@ namespace chaiscript } } }; - - - class Dynamic_Conversions - { - public: - static inline Dynamic_Conversions &get() - { - static Dynamic_Conversions obj; - return obj; - } - - template - static boost::shared_ptr create() - { - boost::shared_ptr conversion(new Dynamic_Conversion_Impl()); - - /// \todo this is a hack and a kludge. The idea is to make sure that - /// the conversion is registered both in the module's notion of the static conversion object - /// and in the global notion of the static conversion object - /// someday this will almost certainly have to change. Maybe it is time for ChaiScript - /// to become a library? - Dynamic_Conversions::get().add_conversion(conversion); - return conversion; - } - - template - void cleanup(InItr begin, const InItr &end) - { - chaiscript::detail::threading::unique_lock l(m_mutex); - - while (begin != end) - { - if (begin->unique()) - { - m_conversions.erase(begin->get()); - } - - ++begin; - } - } - - void add_conversion(const boost::shared_ptr &conversion) - { - chaiscript::detail::threading::unique_lock l(m_mutex); - - m_conversions.insert(conversion.get()); - } - - bool has_conversion(const Type_Info &base, const Type_Info &derived) const - { - chaiscript::detail::threading::shared_lock l(m_mutex); - - return find(base, derived) != m_conversions.end(); - } - - - Dynamic_Conversion *get_conversion(const Type_Info &base, const Type_Info &derived) const - { - chaiscript::detail::threading::shared_lock l(m_mutex); - - std::set::const_iterator itr = - find(base, derived); - - if (itr != m_conversions.end()) - { - return *itr; - } else { - throw std::out_of_range("No such conversion exists from " + derived.bare_name() + " to " + base.bare_name()); - } - } - - private: - Dynamic_Conversions() {} - - std::set::const_iterator find( - const Type_Info &base, const Type_Info &derived) const - { - for (std::set::const_iterator itr = m_conversions.begin(); - itr != m_conversions.end(); - ++itr) - { - if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived)) - { - return itr; - } - } - - return m_conversions.end(); - } - - mutable chaiscript::detail::threading::shared_mutex m_mutex; - std::set m_conversions; - }; } + class Dynamic_Cast_Conversions + { + public: + Dynamic_Cast_Conversions() + { + } + + Dynamic_Cast_Conversions(const Dynamic_Cast_Conversions &t_other) + : m_conversions(t_other.get_conversions()) + { + } + + void add_conversion(const boost::shared_ptr &conversion) + { + chaiscript::detail::threading::unique_lock l(m_mutex); + m_conversions.insert(conversion); + } + + template + bool dynamic_cast_converts() const + { + return dynamic_cast_converts(user_type(), user_type()); + } + + bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived) const + { + return has_conversion(base, derived); + } + + template + Boxed_Value boxed_dynamic_cast(const Boxed_Value &derived) const + { + try { + return get_conversion(user_type(), derived.get_type_info())->convert(derived); + } catch (const std::out_of_range &) { + throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion"); + } catch (const std::bad_cast &) { + throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation"); + } + } + + bool has_conversion(const Type_Info &base, const Type_Info &derived) const + { + chaiscript::detail::threading::shared_lock l(m_mutex); + return find(base, derived) != m_conversions.end(); + } + + boost::shared_ptr get_conversion(const Type_Info &base, const Type_Info &derived) const + { + chaiscript::detail::threading::shared_lock l(m_mutex); + + std::set >::const_iterator itr = + find(base, derived); + + if (itr != m_conversions.end()) + { + return *itr; + } else { + throw std::out_of_range("No such conversion exists from " + derived.bare_name() + " to " + base.bare_name()); + } + } + + private: + std::set >::const_iterator find( + const Type_Info &base, const Type_Info &derived) const + { + for (std::set >::const_iterator itr = m_conversions.begin(); + itr != m_conversions.end(); + ++itr) + { + if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived)) + { + return itr; + } + } + + return m_conversions.end(); + } + + std::set > get_conversions() const + { + chaiscript::detail::threading::shared_lock l(m_mutex); + + return m_conversions; + } + + mutable chaiscript::detail::threading::shared_mutex m_mutex; + std::set > m_conversions; + }; + typedef boost::shared_ptr Dynamic_Cast_Conversion; /// \brief Used to register a base / parent class relationship with ChaiScript. Necessary if you @@ -248,42 +245,17 @@ namespace chaiscript /// \todo Move share static type registration code into a mechanism that allows it to be properly /// shared by all modules template - Dynamic_Cast_Conversion base_class() - { - //Can only be used with related polymorphic types - //may be expanded some day to support conversions other than child -> parent - BOOST_STATIC_ASSERT((boost::is_base_of::value)); - BOOST_STATIC_ASSERT(boost::is_polymorphic::value); - BOOST_STATIC_ASSERT(boost::is_polymorphic::value); - - return detail::Dynamic_Conversions::create(); - } - - namespace detail - { - template - bool dynamic_cast_converts() - { - return dynamic_cast_converts(user_type(), user_type()); - } - - static bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived) + Dynamic_Cast_Conversion base_class() { - return detail::Dynamic_Conversions::get().has_conversion(base, derived); + //Can only be used with related polymorphic types + //may be expanded some day to support conversions other than child -> parent + BOOST_STATIC_ASSERT((boost::is_base_of::value)); + BOOST_STATIC_ASSERT(boost::is_polymorphic::value); + BOOST_STATIC_ASSERT(boost::is_polymorphic::value); + + return boost::shared_ptr(new detail::Dynamic_Conversion_Impl()); } - template - Boxed_Value boxed_dynamic_cast(const Boxed_Value &derived) - { - try { - return detail::Dynamic_Conversions::get().get_conversion(user_type(), derived.get_type_info())->convert(derived); - } catch (const std::out_of_range &) { - throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion"); - } catch (const std::bad_cast &) { - throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation"); - } - } - } } diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 43a1cad..175ad47 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -57,11 +57,11 @@ namespace chaiscript const Proxy_Function &t_func, const boost::optional &t_ti = boost::optional()) : Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)), - m_type_name(t_type_name), m_func(t_func), m_ti(t_ti) - { - assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) - && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); - } + m_type_name(t_type_name), m_func(t_func), m_ti(t_ti) + { + assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) + && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); + } virtual ~Dynamic_Object_Function() {} @@ -76,11 +76,11 @@ namespace chaiscript } } - virtual bool call_match(const std::vector &vals) const + virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const { if (dynamic_object_typename_match(vals, m_type_name, m_ti)) { - return m_func->call_match(vals); + return m_func->call_match(vals, t_conversions); } else { return false; } @@ -106,11 +106,11 @@ namespace chaiscript protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const + virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { if (dynamic_object_typename_match(params, m_type_name, m_ti)) { - return (*m_func)(params); + return (*m_func)(params, t_conversions); } else { throw exception::guard_error(); } @@ -192,11 +192,11 @@ namespace chaiscript const std::string &t_type_name, const Proxy_Function &t_func) : Proxy_Function_Base(build_type_list(t_func->get_param_types())), - m_type_name(t_type_name), m_func(t_func) - { - assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) - && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); - } + m_type_name(t_type_name), m_func(t_func) + { + assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) + && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); + } static std::vector build_type_list(const std::vector &tl) { @@ -224,13 +224,13 @@ namespace chaiscript } } - virtual bool call_match(const std::vector &vals) const + virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const { std::vector new_vals; new_vals.push_back(Boxed_Value(Dynamic_Object(m_type_name))); new_vals.insert(new_vals.end(), vals.begin(), vals.end()); - return m_func->call_match(new_vals); + return m_func->call_match(new_vals, t_conversions); } @@ -246,14 +246,14 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const + virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { std::vector new_params; chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name)); new_params.push_back(bv); new_params.insert(new_params.end(), params.begin(), params.end()); - (*m_func)(new_params); + (*m_func)(new_params, t_conversions); return bv; } diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index 74841ed..7770d11 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -15,65 +15,65 @@ namespace chaiscript { struct Exception_Handler_Base { - virtual void handle(const Boxed_Value &bv) = 0; + virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0; protected: template - void throw_type(const Boxed_Value &bv) + void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine) { - try { T t = boxed_cast(bv); throw t; } catch (const exception::bad_boxed_cast &) {} + try { T t = t_engine.boxed_cast(bv); throw t; } catch (const exception::bad_boxed_cast &) {} } }; template struct Exception_Handler_Impl1 : Exception_Handler_Base { - virtual void handle(const Boxed_Value &bv) + virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) { - throw_type(bv); + throw_type(bv, t_engine); } }; template struct Exception_Handler_Impl2 : Exception_Handler_Base { - virtual void handle(const Boxed_Value &bv) + virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) { - throw_type(bv); - throw_type(bv); + throw_type(bv, t_engine); + throw_type(bv, t_engine); } }; template struct Exception_Handler_Impl3 : Exception_Handler_Base { - virtual void handle(const Boxed_Value &bv) + virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) { - throw_type(bv); - throw_type(bv); - throw_type(bv); + throw_type(bv, t_engine); + throw_type(bv, t_engine); + throw_type(bv, t_engine); } }; template struct Exception_Handler_Impl4 : Exception_Handler_Base { - virtual void handle(const Boxed_Value &bv) + virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) { - throw_type(bv); - throw_type(bv); - throw_type(bv); - throw_type(bv); + throw_type(bv, t_engine); + throw_type(bv, t_engine); + throw_type(bv, t_engine); + throw_type(bv, t_engine); } }; template struct Exception_Handler_Impl5 : Exception_Handler_Base { - virtual void handle(const Boxed_Value &bv) + virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) { - throw_type(bv); - throw_type(bv); - throw_type(bv); - throw_type(bv); - throw_type(bv); + throw_type(bv, t_engine); + throw_type(bv, t_engine); + throw_type(bv, t_engine); + throw_type(bv, t_engine); + throw_type(bv, t_engine); } }; } diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index 9dea81c..3316c54 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -32,10 +32,10 @@ namespace chaiscript */ template boost::function - functor(const std::vector &funcs) + functor(const std::vector &funcs, const Dynamic_Cast_Conversions &t_conversions) { FunctionType *p=0; - return detail::build_function_caller_helper(p, funcs); + return detail::build_function_caller_helper(p, funcs, t_conversions); } /** @@ -53,11 +53,11 @@ namespace chaiscript */ template boost::function - functor(Const_Proxy_Function func) + functor(Const_Proxy_Function func, const Dynamic_Cast_Conversions &t_conversions) { std::vector funcs; funcs.push_back(func); - return functor(funcs); + return functor(funcs, t_conversions); } /** @@ -66,9 +66,9 @@ namespace chaiscript */ template boost::function - functor(const Boxed_Value &bv) + functor(const Boxed_Value &bv, const Dynamic_Cast_Conversions &t_conversions) { - return functor(boxed_cast(bv)); + return functor(boxed_cast(bv, t_conversions), t_conversions); } } @@ -81,13 +81,13 @@ namespace chaiscript { typedef boost::function Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { - return dispatch::functor(ob); + return dispatch::functor(ob, t_conversions); } else { - return Cast_Helper_Inner &>::cast(ob); + return Cast_Helper_Inner &>::cast(ob, t_conversions); } } }; @@ -100,13 +100,13 @@ namespace chaiscript { typedef boost::function Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { - return dispatch::functor(ob); + return dispatch::functor(ob, t_conversions); } else { - return Cast_Helper_Inner >::cast(ob); + return Cast_Helper_Inner >::cast(ob, t_conversions); } } }; @@ -119,13 +119,13 @@ namespace chaiscript { typedef boost::function Result_Type; - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { - return dispatch::functor(ob); + return dispatch::functor(ob, t_conversions); } else { - return Cast_Helper_Inner >::cast(ob); + return Cast_Helper_Inner >::cast(ob, t_conversions); } } }; diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index d9c7160..f62ea01 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -36,9 +36,9 @@ namespace chaiscript struct Function_Caller_Ret { static Ret call(const std::vector &t_funcs, - const std::vector ¶ms) + const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) { - return boxed_cast(dispatch::dispatch(t_funcs, params)); + return boxed_cast(dispatch::dispatch(t_funcs, params, t_conversions)); } }; @@ -49,9 +49,9 @@ namespace chaiscript struct Function_Caller_Ret { static void call(const std::vector &t_funcs, - const std::vector ¶ms) + const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) { - dispatch::dispatch(t_funcs, params); + dispatch::dispatch(t_funcs, params, t_conversions); } }; } @@ -76,14 +76,14 @@ namespace chaiscript * used internally for unwrapping a function call's types */ template - Ret function_caller(const std::vector &funcs + Ret function_caller(const std::vector &funcs, const Dynamic_Cast_Conversions &t_conversions BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) { std::vector params; BOOST_PP_REPEAT(n, addparam, ~) - return Function_Caller_Ret::call(funcs, params); + return Function_Caller_Ret::call(funcs, params, t_conversions); } /** @@ -91,7 +91,8 @@ namespace chaiscript */ template boost::function - build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector &funcs) + build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector &funcs, + const Dynamic_Cast_Conversions &t_conversions) { if (funcs.size() == 1) { @@ -107,7 +108,7 @@ namespace chaiscript // we cannot make any other guesses or assumptions really, so continuing } - return boost::bind(&function_caller, funcs + return boost::bind(&function_caller, funcs, t_conversions BOOST_PP_ENUM_TRAILING(n, curry, ~)); } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index b8504b1..2df8a23 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -70,9 +70,9 @@ namespace chaiscript { public: virtual ~Proxy_Function_Base() {} - Boxed_Value operator()(const std::vector ¶ms) const + Boxed_Value operator()(const std::vector ¶ms, const chaiscript::Dynamic_Cast_Conversions &t_conversions) const { - Boxed_Value bv = do_call(params); + Boxed_Value bv = do_call(params, t_conversions); return bv; } @@ -83,7 +83,7 @@ namespace chaiscript std::vector get_param_types() const { return m_types; } virtual bool operator==(const Proxy_Function_Base &) const = 0; - virtual bool call_match(const std::vector &vals) const = 0; + virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const = 0; bool has_arithmetic_param() const { @@ -98,7 +98,7 @@ namespace chaiscript //! Return true if the function is a possible match //! to the passed in values - bool filter(const std::vector &vals) const + bool filter(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const { int arity = get_arity(); @@ -110,7 +110,7 @@ namespace chaiscript { return true; } else { - return compare_first_type(vals[0]); + return compare_first_type(vals[0], t_conversions); } } else { return false; @@ -122,15 +122,15 @@ namespace chaiscript virtual std::string annotation() const = 0; - static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv) + static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Dynamic_Cast_Conversions &t_conversions) { if (ti.is_undef() || ti.bare_equal(user_type()) || (!bv.get_type_info().is_undef() && (ti.bare_equal(user_type()) || ti.bare_equal(bv.get_type_info()) - || chaiscript::detail::dynamic_cast_converts(ti, bv.get_type_info()) || bv.get_type_info().bare_equal(user_type >()) + || t_conversions.dynamic_cast_converts(ti, bv.get_type_info()) ) ) ) @@ -141,7 +141,7 @@ namespace chaiscript } } protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const = 0; + virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const = 0; Proxy_Function_Base(const std::vector &t_types) : m_types(t_types), m_has_arithmetic_param(false) @@ -157,7 +157,7 @@ namespace chaiscript } - virtual bool compare_first_type(const Boxed_Value &bv) const + virtual bool compare_first_type(const Boxed_Value &bv, const Dynamic_Cast_Conversions &t_conversions) const { const std::vector &types = get_param_types(); @@ -167,11 +167,11 @@ namespace chaiscript } const Type_Info &ti = types[1]; - return compare_type_to_param(ti, bv); + return compare_type_to_param(ti, bv, t_conversions); } - bool compare_types(const std::vector &tis, const std::vector &bvs) const + static bool compare_types(const std::vector &tis, const std::vector &bvs) { if (tis.size() - 1 != bvs.size()) { @@ -247,10 +247,10 @@ namespace chaiscript && !this->m_guard && !prhs->m_guard); } - virtual bool call_match(const std::vector &vals) const + virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const { return (m_arity < 0 || vals.size() == size_t(m_arity)) - && test_guard(vals); + && test_guard(vals, t_conversions); } virtual ~Dynamic_Proxy_Function() {} @@ -277,12 +277,12 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const + virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { if (m_arity < 0 || params.size() == size_t(m_arity)) { - if (test_guard(params)) + if (test_guard(params, t_conversions)) { return m_f(params); } else { @@ -295,12 +295,12 @@ namespace chaiscript } private: - bool test_guard(const std::vector ¶ms) const + bool test_guard(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { if (m_guard) { try { - return boxed_cast((*m_guard)(params)); + return boxed_cast((*m_guard)(params, t_conversions)); } catch (const exception::arity_error &) { return false; } catch (const exception::bad_boxed_cast &) { @@ -356,7 +356,7 @@ namespace chaiscript Bound_Function(const Const_Proxy_Function &t_f, const std::vector &t_args) : Proxy_Function_Base(build_param_type_info(t_f, t_args)), - m_f(t_f), m_args(t_args), m_arity(t_f->get_arity()<0?-1:static_cast(get_param_types().size())-1) + m_f(t_f), m_args(t_args), m_arity(t_f->get_arity()<0?-1:static_cast(get_param_types().size())-1) { assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast(m_args.size())); } @@ -368,14 +368,9 @@ namespace chaiscript virtual ~Bound_Function() {} - virtual bool call_match(const std::vector &vals) const + virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const { - return m_f->call_match(build_param_list(vals)); - } - - virtual Boxed_Value operator()(const std::vector ¶ms) const - { - return (*m_f)(build_param_list(params)); + return m_f->call_match(build_param_list(vals), t_conversions); } virtual std::vector get_contained_functions() const @@ -452,9 +447,9 @@ namespace chaiscript return retval; } - virtual Boxed_Value do_call(const std::vector ¶ms) const + virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { - return (*m_f)(build_param_list(params)); + return (*m_f)(build_param_list(params), t_conversions); } private: @@ -475,8 +470,8 @@ namespace chaiscript Proxy_Function_Impl(const boost::function &f) : Proxy_Function_Base(detail::build_param_type_list(static_cast(0))), m_f(f), m_dummy_func(0) - { - } + { + } virtual ~Proxy_Function_Impl() {} @@ -493,14 +488,14 @@ namespace chaiscript } - virtual bool call_match(const std::vector &vals) const + virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &t_conversions) const { if (int(vals.size()) != get_arity()) { return false; } - return compare_types(m_types, vals) || detail::compare_types_cast(m_dummy_func, vals); + return compare_types(m_types, vals) || detail::compare_types_cast(m_dummy_func, vals, t_conversions); } virtual std::string annotation() const @@ -514,9 +509,9 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const + virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { - return detail::Do_Call::result_type>::go(m_f, params); + return detail::Do_Call::result_type>::go(m_f, params, t_conversions); } private: @@ -534,8 +529,8 @@ namespace chaiscript Attribute_Access(T Class::* t_attr) : Proxy_Function_Base(param_types()), m_attr(t_attr) - { - } + { + } virtual ~Attribute_Access() {} @@ -556,7 +551,7 @@ namespace chaiscript return 1; } - virtual bool call_match(const std::vector &vals) const + virtual bool call_match(const std::vector &vals, const Dynamic_Cast_Conversions &) const { if (vals.size() != 1) { @@ -572,17 +567,17 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const + virtual Boxed_Value do_call(const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) const { if (params.size() == 1) { const Boxed_Value &bv = params[0]; if (bv.is_const()) { - const Class *o = boxed_cast(bv); + const Class *o = boxed_cast(bv, t_conversions); return detail::Handle_Return::type>::handle(o->*m_attr); } else { - Class *o = boxed_cast(bv); + Class *o = boxed_cast(bv, t_conversions); return detail::Handle_Return::type>::handle(o->*m_attr); } } else { @@ -630,7 +625,8 @@ namespace chaiscript namespace detail { template - bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector &plist) + bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector &plist, + const Dynamic_Cast_Conversions &t_conversions) { if (t_func->get_arity() != plist.size()) { @@ -643,7 +639,7 @@ namespace chaiscript for (int i = 0; i < plist.size(); ++i) { - if (Proxy_Function_Base::compare_type_to_param(types[i+1], plist[i]) + if (Proxy_Function_Base::compare_type_to_param(types[i+1], plist[i], t_conversions) || (types[i+1].is_arithmetic() && plist[i].get_type_info().is_arithmetic())) { // types continue to match @@ -657,7 +653,8 @@ namespace chaiscript } template - Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const std::vector &plist) + Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const std::vector &plist, + const Dynamic_Cast_Conversions &t_conversions) { InItr orig(begin); @@ -665,7 +662,7 @@ namespace chaiscript while (begin != end) { - if (types_match_except_for_arithmetic(*begin, plist)) + if (types_match_except_for_arithmetic(*begin, plist, t_conversions)) { if (matching_func == end) { @@ -700,7 +697,7 @@ namespace chaiscript } try { - return (*(*matching_func))(newplist); + return (*(*matching_func))(newplist, t_conversions); } catch (const exception::bad_boxed_cast &) { //parameter failed to cast } catch (const exception::arity_error &) { @@ -721,15 +718,15 @@ namespace chaiscript */ template Boxed_Value dispatch(InItr begin, const InItr &end, - const std::vector &plist) + const std::vector &plist, const Dynamic_Cast_Conversions &t_conversions) { InItr orig(begin); while (begin != end) { try { - if ((*begin)->filter(plist)) + if ((*begin)->filter(plist, t_conversions)) { - return (*(*begin))(plist); + return (*(*begin))(plist, t_conversions); } } catch (const exception::bad_boxed_cast &) { //parameter failed to cast, try again @@ -742,7 +739,7 @@ namespace chaiscript ++begin; } - return detail::dispatch_with_conversions(orig, end, plist); + return detail::dispatch_with_conversions(orig, end, plist, t_conversions); } /** @@ -752,9 +749,9 @@ namespace chaiscript */ template Boxed_Value dispatch(const Funcs &funcs, - const std::vector &plist) + const std::vector &plist, const Dynamic_Cast_Conversions &t_conversions) { - return dispatch::dispatch(funcs.begin(), funcs.end(), plist); + return dispatch::dispatch(funcs.begin(), funcs.end(), plist, t_conversions); } } } diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index a853e1d..3c5f480 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -7,8 +7,8 @@ #include #define gettypeinfo(z,n,text) ti.push_back(chaiscript::detail::Get_Type_Info::get()); -#define casthelper(z,n,text) BOOST_PP_COMMA_IF(n) chaiscript::boxed_cast< Param ## n >(params[n]) -#define trycast(z,n,text) chaiscript::boxed_cast(params[n]); +#define casthelper(z,n,text) BOOST_PP_COMMA_IF(n) chaiscript::boxed_cast< Param ## n >(params[n], t_conversions) +#define trycast(z,n,text) chaiscript::boxed_cast(params[n], t_conversions); #ifndef BOOST_PP_IS_ITERATING #ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ @@ -88,7 +88,7 @@ namespace chaiscript */ template Ret call_func(const boost::function &f, - const std::vector ¶ms) + const std::vector ¶ms, const Dynamic_Cast_Conversions & BOOST_PP_IF(n, t_conversions, )) { if (params.size() != n) { @@ -105,7 +105,7 @@ namespace chaiscript */ template bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)), - const std::vector & BOOST_PP_IF(n, params, )) + const std::vector & BOOST_PP_IF(n, params, ), const Dynamic_Cast_Conversions &t_conversions) { try { BOOST_PP_REPEAT(n, trycast, ~); @@ -140,9 +140,9 @@ namespace chaiscript struct Do_Call { template - static Boxed_Value go(const boost::function &fun, const std::vector ¶ms) + static Boxed_Value go(const boost::function &fun, const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) { - return Handle_Return::handle(call_func(fun, params)); + return Handle_Return::handle(call_func(fun, params, t_conversions)); } }; @@ -150,9 +150,9 @@ namespace chaiscript struct Do_Call { template - static Boxed_Value go(const boost::function &fun, const std::vector ¶ms) + static Boxed_Value go(const boost::function &fun, const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) { - call_func(fun, params); + call_func(fun, params, t_conversions); return Handle_Return::handle(); } }; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index e526c8d..b21cfd2 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -334,6 +334,13 @@ namespace chaiscript m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, boost::ref(m_engine)), "get_functions"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, boost::ref(m_engine)), "get_objects"); + + m_engine.add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(boost::bind(&chaiscript::detail::Dispatch_Engine::call_exists, boost::ref(m_engine), _1))), + "call_exists"); + m_engine.add(fun &)>(boost::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), _1, _2, boost::ref(m_engine.conversions()))), "call"); + + + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, boost::ref(m_engine)), "name"); @@ -665,7 +672,7 @@ namespace chaiscript return do_eval(t_script); } catch (Boxed_Value &bv) { if (t_handler) { - t_handler->handle(bv); + t_handler->handle(bv, m_engine); } throw bv; } @@ -688,15 +695,23 @@ namespace chaiscript T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__") { try { - return boxed_cast(do_eval(t_input, t_filename)); + return m_engine.boxed_cast(do_eval(t_input, t_filename)); } catch (Boxed_Value &bv) { if (t_handler) { - t_handler->handle(bv); + t_handler->handle(bv, m_engine); } throw bv; } } + /// \brief casts an object while applying any Dynamic_Conversion available + template + typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) const + { + return m_engine.boxed_cast(bv); + } + + /// \brief Evaluates a string. /// /// \param[in] t_input Script to execute @@ -713,7 +728,7 @@ namespace chaiscript return do_eval(t_input, t_filename); } catch (Boxed_Value &bv) { if (t_handler) { - t_handler->handle(bv); + t_handler->handle(bv, m_engine); } throw bv; } @@ -729,7 +744,7 @@ namespace chaiscript return do_eval(load_file(t_filename), t_filename); } catch (Boxed_Value &bv) { if (t_handler) { - t_handler->handle(bv); + t_handler->handle(bv, m_engine); } throw bv; } @@ -746,10 +761,10 @@ namespace chaiscript template T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { try { - return boxed_cast(do_eval(load_file(t_filename), t_filename)); + return m_engine.boxed_cast(do_eval(load_file(t_filename), t_filename)); } catch (Boxed_Value &bv) { if (t_handler) { - t_handler->handle(bv); + t_handler->handle(bv, m_engine); } throw bv; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 79fde89..0df7bf2 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -225,7 +225,7 @@ namespace chaiscript try { chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); - const Boxed_Value &retval = (*boxed_cast(fn))(plb); + const Boxed_Value &retval = (*t_ss.boxed_cast(fn))(plb, t_ss.conversions()); return retval; } catch(const exception::dispatch_error &e){ @@ -233,7 +233,7 @@ namespace chaiscript } catch(const exception::bad_boxed_cast &){ try { - Const_Proxy_Function f = boxed_cast(fn); + Const_Proxy_Function f = t_ss.boxed_cast(fn); // handle the case where there is only 1 function to try to call and dispatch fails on it std::vector funcs; funcs.push_back(f); @@ -293,11 +293,11 @@ namespace chaiscript try { bv = this->children[0]->eval(t_ss); try { - fn = boxed_cast(bv); + fn = t_ss.boxed_cast(bv); } catch (const exception::bad_boxed_cast &) { throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function."); } - return (*fn)(plb); + return (*fn)(plb, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, t_ss); @@ -1026,7 +1026,7 @@ namespace chaiscript std::map retval; for (size_t i = 0; i < this->children[0]->children.size(); ++i) { Boxed_Value bv = t_ss.call_function("clone", this->children[0]->children[i]->children[1]->eval(t_ss)); - retval[boxed_cast(this->children[0]->children[i]->children[0]->eval(t_ss))] + retval[t_ss.boxed_cast(this->children[0]->children[i]->children[0]->eval(t_ss))] = bv; } return const_var(retval); diff --git a/samples/example.cpp b/samples/example.cpp index ff670e7..0164638 100644 --- a/samples/example.cpp +++ b/samples/example.cpp @@ -43,9 +43,9 @@ struct System std::map > m_callbacks; void add_callback(const std::string &t_name, - const chaiscript::Proxy_Function &t_func) + const boost::function &t_func) { - m_callbacks[t_name] = chaiscript::dispatch::functor(t_func); + m_callbacks[t_name] = t_func; } diff --git a/unittests/eval_catch_exception_test.cpp b/unittests/eval_catch_exception_test.cpp index 21510d7..8cde186 100644 --- a/unittests/eval_catch_exception_test.cpp +++ b/unittests/eval_catch_exception_test.cpp @@ -9,7 +9,7 @@ int test_generic() try { chai.eval("throw(runtime_error(\"error\"));"); } catch (const chaiscript::Boxed_Value &bv) { - const std::exception &e = chaiscript::boxed_cast(bv); + const std::exception &e = chai.boxed_cast(bv); if (e.what() == std::string("error")) { return EXIT_SUCCESS;