diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index b7fdc04..ab95ce9 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -269,21 +269,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) { @@ -379,7 +364,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==), "=="); @@ -472,9 +456,6 @@ namespace chaiscript m->add(fun(&ptr_assign::type>), "="); m->add(fun(&ptr_assign::type>), "="); - m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(std::bind(&call_exists, std::placeholders::_1))), - "call_exists"); - m->add(fun(&Boxed_Value::type_match), "type_match"); return m; diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index b110391..c27134f 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -62,10 +62,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 chaiscript::detail::exception::bad_any_cast &) { @@ -81,7 +81,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 chaiscript::detail::exception::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 ac70b3b..6991ad8 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -13,6 +13,8 @@ namespace chaiscript { + class Dynamic_Cast_Conversions; + namespace detail { // Cast_Helper_Inner helper classes @@ -25,7 +27,7 @@ namespace chaiscript { typedef typename std::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()) { @@ -67,7 +69,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()) { @@ -96,7 +98,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()) { @@ -115,7 +117,7 @@ namespace chaiscript { typedef Result& Result_Type; - static Result &cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions &) { if (ob.is_ref()) { @@ -135,7 +137,7 @@ namespace chaiscript { typedef typename std::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 ob.get().cast >(); } @@ -149,7 +151,7 @@ namespace chaiscript { typedef typename std::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()) { @@ -197,7 +199,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; } @@ -258,9 +260,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 d641cb5..b1d5fc3 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -823,7 +823,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 2b01961..40e3bf6 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -156,7 +156,6 @@ namespace chaiscript ~Module() { - detail::Dynamic_Conversions::get().cleanup(m_conversions.begin(), m_conversions.end()); } private: @@ -227,9 +226,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 { @@ -279,7 +278,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; @@ -288,7 +287,7 @@ namespace chaiscript while (begin != end) { - if ((*begin)->call_match(vals)) + if ((*begin)->call_match(vals, t_conversions)) { return true; } else { @@ -305,9 +304,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: @@ -396,16 +395,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); } /** @@ -778,11 +782,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 @@ -851,6 +860,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 chaiscript::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 */ @@ -1153,7 +1178,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 2b40e8b..60737f6 100644 --- a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp +++ b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp @@ -44,7 +44,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() { @@ -70,7 +70,7 @@ namespace chaiscript }; template - class Dynamic_Conversion_Impl : public Dynamic_Conversion + class Dynamic_Conversion_Impl : public Dynamic_Conversion { public: Dynamic_Conversion_Impl() @@ -78,7 +78,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())) { @@ -88,7 +88,7 @@ namespace chaiscript if (t_derived.is_const()) { std::shared_ptr data - = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived)); + = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived, Dynamic_Cast_Conversions())); if (!data) { throw std::bad_cast(); @@ -97,7 +97,7 @@ namespace chaiscript return Boxed_Value(data); } else { std::shared_ptr data - = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived)); + = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_derived, Dynamic_Cast_Conversions())); if (!data) { @@ -110,11 +110,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(std::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(std::ref(data)); } @@ -124,101 +124,98 @@ namespace chaiscript } } }; - - - class Dynamic_Conversions - { - public: - static inline Dynamic_Conversions &get() - { - static Dynamic_Conversions obj; - return obj; - } - - template - static std::shared_ptr create() - { - std::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 std::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 std::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(); + } + + std::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 std::shared_ptr Dynamic_Cast_Conversion; /// \brief Used to register a base / parent class relationship with ChaiScript. Necessary if you @@ -253,34 +250,9 @@ namespace chaiscript static_assert(std::is_polymorphic::value, "Base class must be polymorphic"); static_assert(std::is_polymorphic::value, "Derived class must be polymorphic"); - return detail::Dynamic_Conversions::create(); + return std::shared_ptr(new detail::Dynamic_Conversion_Impl()); } - 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) - { - return detail::Dynamic_Conversions::get().has_conversion(base, derived); - } - - 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 chaiscript::exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion"); - } catch (const std::bad_cast &) { - throw chaiscript::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 16e15db..7467482 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -66,7 +66,7 @@ namespace chaiscript const Proxy_Function &t_func, const Type_Info &t_ti) : 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(new Type_Info(t_ti)) + m_type_name(t_type_name), m_func(t_func), m_ti(new Type_Info(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)"); @@ -85,11 +85,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; } @@ -113,11 +113,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(); } @@ -194,7 +194,7 @@ 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) + 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)"); @@ -226,13 +226,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); } @@ -248,14 +248,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 4863a7a..10c3826 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 chaiscript::exception::bad_boxed_cast &) {} + try { T t = t_engine.boxed_cast(bv); throw t; } catch (const chaiscript::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 d98698a..0f6b0b0 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -29,10 +29,10 @@ namespace chaiscript */ template std::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); } /** @@ -50,11 +50,11 @@ namespace chaiscript */ template std::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); } /** @@ -63,9 +63,9 @@ namespace chaiscript */ template std::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); } } @@ -78,13 +78,13 @@ namespace chaiscript { typedef std::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); } } }; @@ -97,13 +97,13 @@ namespace chaiscript { typedef std::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); } } }; @@ -116,13 +116,13 @@ namespace chaiscript { typedef std::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 48b76b7..3e650f0 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -26,9 +26,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)); } }; @@ -39,9 +39,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); } }; @@ -51,8 +51,9 @@ namespace chaiscript template struct Build_Function_Caller_Helper { - Build_Function_Caller_Helper(const std::vector &t_funcs) - : m_funcs(t_funcs) + Build_Function_Caller_Helper(const std::vector &t_funcs, const Dynamic_Cast_Conversions &t_conversions) + : m_funcs(t_funcs), + m_conversions(t_conversions) { } @@ -60,19 +61,20 @@ namespace chaiscript { return Function_Caller_Ret::call(m_funcs, { (std::is_reference::value&&!(std::is_same::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)... - } + }, m_conversions ); } std::vector m_funcs; + Dynamic_Cast_Conversions m_conversions; }; template - std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs) + std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs, const Dynamic_Cast_Conversions &t_conversions) { if (funcs.size() == 1) { @@ -88,7 +90,7 @@ namespace chaiscript // we cannot make any other guesses or assumptions really, so continuing } - return std::function(Build_Function_Caller_Helper(funcs)); + return std::function(Build_Function_Caller_Helper(funcs, t_conversions)); } } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 9b36252..fcc8f3e 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -39,9 +39,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; } @@ -52,7 +52,7 @@ namespace chaiscript const 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 { @@ -66,7 +66,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(); @@ -78,7 +78,7 @@ namespace chaiscript { return true; } else { - return compare_first_type(vals[0]); + return compare_first_type(vals[0], t_conversions); } } else { return false; @@ -90,15 +90,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()) ) ) ) @@ -109,7 +109,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) @@ -125,7 +125,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(); @@ -135,11 +135,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()) { @@ -215,10 +215,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() {} @@ -245,12 +245,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 { @@ -263,12 +263,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 &) { @@ -324,7 +324,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())); } @@ -336,14 +336,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 @@ -421,9 +416,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: @@ -460,14 +455,14 @@ namespace chaiscript return static_cast(m_types.size()) - 1; } - 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 @@ -481,9 +476,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: @@ -524,7 +519,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) { @@ -540,17 +535,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 { @@ -596,7 +591,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()) { @@ -609,7 +605,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 @@ -623,7 +619,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); @@ -631,7 +628,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) { @@ -666,7 +663,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 &) { @@ -687,15 +684,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 @@ -708,7 +705,7 @@ namespace chaiscript ++begin; } - return detail::dispatch_with_conversions(orig, end, plist); + return detail::dispatch_with_conversions(orig, end, plist, t_conversions); } /** @@ -718,9 +715,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 470cdc8..abae6cd 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -63,10 +63,10 @@ namespace chaiscript template struct Try_Cast { - static void do_try(const std::vector ¶ms, int generation) + static void do_try(const std::vector ¶ms, int generation, const Dynamic_Cast_Conversions &t_conversions) { - boxed_cast(params[generation]); - Try_Cast::do_try(params, generation+1); + boxed_cast(params[generation], t_conversions); + Try_Cast::do_try(params, generation+1, t_conversions); } }; @@ -74,7 +74,7 @@ namespace chaiscript template<> struct Try_Cast<> { - static void do_try(const std::vector &, int) + static void do_try(const std::vector &, int, const Dynamic_Cast_Conversions &) { } }; @@ -88,10 +88,10 @@ namespace chaiscript */ template bool compare_types_cast(Ret (*)(Params...), - const std::vector ¶ms) + const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) { try { - Try_Cast::do_try(params, 0); + Try_Cast::do_try(params, 0, t_conversions); } catch (const exception::bad_boxed_cast &) { return false; } @@ -105,9 +105,9 @@ namespace chaiscript template static Ret do_call(const std::function &f, - const std::vector ¶ms, InnerParams &&... innerparams) + const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions, InnerParams &&... innerparams) { - return Call_Func::do_call(f, params, std::forward(innerparams)..., params[sizeof...(Params) - count]); + return Call_Func::do_call(f, params, t_conversions, std::forward(innerparams)..., params[sizeof...(Params) - count]); } }; @@ -116,9 +116,9 @@ namespace chaiscript { template static Ret do_call(const std::function &f, - const std::vector &, InnerParams &&... innerparams) + const std::vector &, const Dynamic_Cast_Conversions &t_conversions, InnerParams &&... innerparams) { - return f(boxed_cast(std::forward(innerparams))...); + return f(boxed_cast(std::forward(innerparams), t_conversions)...); } }; @@ -130,11 +130,11 @@ namespace chaiscript */ template Ret call_func(const std::function &f, - const std::vector ¶ms) + const std::vector ¶ms, const Dynamic_Cast_Conversions &t_conversions) { if (params.size() == sizeof...(Params)) { - return Call_Func::do_call(f, params); + return Call_Func::do_call(f, params, t_conversions); } throw exception::arity_error(static_cast(params.size()), sizeof...(Params)); @@ -156,9 +156,9 @@ namespace chaiscript struct Do_Call { template - static Boxed_Value go(const std::function &fun, const std::vector ¶ms) + static Boxed_Value go(const std::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)); } }; @@ -166,9 +166,9 @@ namespace chaiscript struct Do_Call { template - static Boxed_Value go(const std::function &fun, const std::vector ¶ms) + static Boxed_Value go(const std::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 bacc80d..581e8ed 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -338,6 +338,10 @@ namespace chaiscript m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, std::ref(m_engine)), "get_functions"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, std::ref(m_engine)), "get_objects"); + m_engine.add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(std::bind(&chaiscript::detail::Dispatch_Engine::call_exists, std::ref(m_engine), std::placeholders::_1))), + "call_exists"); + m_engine.add(fun &)>(std::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), std::placeholders::_1, std::placeholders::_2, std::ref(m_engine.conversions()))), "call"); + m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name"); @@ -731,7 +735,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; } @@ -754,15 +758,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 @@ -779,7 +791,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; } @@ -795,7 +807,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; } @@ -812,10 +824,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 08b3d48..5b11acc 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -226,7 +226,7 @@ namespace chaiscript Boxed_Value fn = this->children[0]->eval(t_ss); try { chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); - const Boxed_Value &retval = (*boxed_cast(fn))(params); + const Boxed_Value &retval = (*t_ss.boxed_cast(fn))(params, t_ss.conversions()); return retval; } catch(const exception::dispatch_error &e){ @@ -234,7 +234,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); @@ -294,11 +294,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)(params); + return (*fn)(params, 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); @@ -1046,7 +1046,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 bc8c982..9b51832 100644 --- a/samples/example.cpp +++ b/samples/example.cpp @@ -42,9 +42,9 @@ struct System std::map > m_callbacks; void add_callback(const std::string &t_name, - const chaiscript::Proxy_Function &t_func) + const std::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;