diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 0e9ba2f..140a2dc 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -75,7 +75,8 @@ namespace chaiscript { public: Dispatch_Function(const std::vector > &t_funcs) - : m_funcs(t_funcs) + : Proxy_Function_Base(std::vector()), + m_funcs(t_funcs) { } @@ -91,11 +92,6 @@ namespace chaiscript return dispatch(m_funcs.begin(), m_funcs.end(), params); } - virtual std::vector get_param_types() const - { - return std::vector(); - } - virtual int get_arity() const { return -1; diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 2e6ab6e..564d970 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -23,27 +23,27 @@ namespace chaiscript template struct Handle_Return { - static Boxed_Value call(const boost::function &f) + static Boxed_Value handle(const Ret &r) { - return Boxed_Value(f()); + return Boxed_Value(r); } }; template struct Handle_Return &> { - static Boxed_Value call(const boost::function & ()> &f) + static Boxed_Value handle(const boost::shared_ptr &r) { - return Boxed_Value(f()); + return Boxed_Value(r); } }; template struct Handle_Return &> { - static Boxed_Value call(const boost::function & ()> &f) + static Boxed_Value handle(const boost::shared_ptr &r) { - return Boxed_Value(f()); + return Boxed_Value(r); } }; @@ -53,9 +53,9 @@ namespace chaiscript template struct Handle_Return { - static Boxed_Value call(const boost::function &f) + static Boxed_Value handle(Ret &r) { - return Boxed_Value(boost::ref(f())); + return Boxed_Value(boost::ref(r)); } }; @@ -65,9 +65,9 @@ namespace chaiscript template<> struct Handle_Return { - static Boxed_Value call(const boost::function &f) + static Boxed_Value handle(const Boxed_Value &r) { - return f(); + return r; } }; @@ -77,9 +77,9 @@ namespace chaiscript template<> struct Handle_Return { - static Boxed_Value call(const boost::function &f) + static Boxed_Value handle(const Boxed_Value &r) { - return f(); + return r; } }; @@ -89,9 +89,8 @@ namespace chaiscript template<> struct Handle_Return { - static Boxed_Value call(const boost::function &f) + static Boxed_Value handle() { - f(); return Boxed_Value(Boxed_Value::Void_Type()); } }; diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index e08dbe4..74a3ae5 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -13,7 +13,6 @@ #include "type_info.hpp" #include #include - #include #include #include "proxy_functions_detail.hpp" @@ -64,7 +63,9 @@ namespace chaiscript public: virtual ~Proxy_Function_Base() {} virtual Boxed_Value operator()(const std::vector ¶ms) = 0; - virtual std::vector get_param_types() const = 0; + + 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; @@ -109,6 +110,32 @@ namespace chaiscript virtual int get_arity() const = 0; virtual std::string annotation() const = 0; + + protected: + Proxy_Function_Base(const std::vector &t_types) + : m_types(t_types) + { + } + + bool compare_types(const std::vector &tis, const std::vector &bvs) const + { + if (tis.size() - 1 != bvs.size()) + { + return false; + } else { + const int size = bvs.size(); + for (int i = 0; i < size; ++i) + { + if (!(tis[i+1].bare_equal(bvs[i].get_type_info()) && tis[i+1].is_const() >= bvs[i].get_type_info().is_const() )) + { + return false; + } + } + } + return true; + } + + std::vector m_types; }; typedef boost::shared_ptr Proxy_Function; @@ -139,8 +166,8 @@ namespace chaiscript int t_arity=-1, const std::string &t_description = "", const Proxy_Function &t_guard = Proxy_Function()) - : m_f(t_f), m_arity(t_arity), m_description(t_description), m_guard(t_guard), - m_types(build_param_type_list(t_arity)) + : Proxy_Function_Base(build_param_type_list(t_arity)), + m_f(t_f), m_arity(t_arity), m_description(t_description), m_guard(t_guard) { } @@ -179,11 +206,6 @@ namespace chaiscript return m_arity; } - virtual std::vector get_param_types() const - { - return m_types; - } - virtual std::string annotation() const { return m_description; @@ -251,7 +273,8 @@ namespace chaiscript public: Bound_Function(const Proxy_Function &t_f, const std::vector &t_args) - : m_f(t_f), m_args(t_args), m_arity(m_f->get_arity()<0?-1:(m_f->get_arity() - m_args.size())) + : Proxy_Function_Base(std::vector()), + m_f(t_f), m_args(t_args), m_arity(m_f->get_arity()<0?-1:(m_f->get_arity() - m_args.size())) { } @@ -310,11 +333,6 @@ namespace chaiscript return args; } - virtual std::vector get_param_types() const - { - return std::vector(); - } - virtual int get_arity() const { return m_arity; @@ -341,7 +359,8 @@ namespace chaiscript { public: Proxy_Function_Impl(const boost::function &f) - : m_f(f), m_dummy_func(0), m_types(build_param_type_list(m_dummy_func)) + : Proxy_Function_Base(build_param_type_list((Func *)(0))), + m_f(f), m_dummy_func(0) { } @@ -359,12 +378,7 @@ namespace chaiscript virtual Boxed_Value operator()(const std::vector ¶ms) { - return call_func(m_f, params); - } - - virtual std::vector get_param_types() const - { - return m_types; + return Do_Call::result_type>::go(m_f, params); } virtual int get_arity() const @@ -375,7 +389,12 @@ namespace chaiscript virtual bool call_match(const std::vector &vals) const { - return compare_types(m_dummy_func, vals); + if (int(vals.size()) != get_arity()) + { + return false; + } + + return compare_types(m_types, vals) || compare_types_cast(m_dummy_func, vals); } virtual std::string annotation() const @@ -386,7 +405,6 @@ namespace chaiscript private: boost::function m_f; Func *m_dummy_func; - std::vector m_types; }; /** diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 969af22..f1f51c9 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -7,11 +7,9 @@ #include #define gettypeinfo(z,n,text) ti.push_back(detail::Get_Type_Info::get()); -#define casthelper(z,n,text) ,chaiscript::boxed_cast< Param ## n >(params[n]) -#define comparetype(z,n,text) && ((detail::Get_Type_Info::get() == params[n].get_type_info())) +#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]); - #ifndef BOOST_PP_IS_ITERATING #ifndef __proxy_functions_detail_hpp__ #define __proxy_functions_detail_hpp__ @@ -45,6 +43,27 @@ namespace chaiscript int got; int expected; }; + + template + struct Do_Call + { + template + static Boxed_Value go(const boost::function &fun, const std::vector ¶ms) + { + return Handle_Return::handle(call_func(fun, params, false)); + } + }; + + template<> + struct Do_Call + { + template + static Boxed_Value go(const boost::function &fun, const std::vector ¶ms) + { + call_func(fun, params, false); + return Handle_Return::handle(); + }; + }; } #define BOOST_PP_ITERATION_LIMITS ( 0, 10 ) @@ -68,7 +87,7 @@ namespace chaiscript std::vector ti; ti.push_back(detail::Get_Type_Info::get()); - BOOST_PP_REPEAT(n, gettypeinfo, ~) + BOOST_PP_REPEAT(n, gettypeinfo, ~) return ti; } @@ -80,14 +99,14 @@ namespace chaiscript * the bad_boxed_cast is passed up to the caller. */ template - Boxed_Value call_func(const boost::function &f, - const std::vector ¶ms) + Ret call_func(const boost::function &f, + const std::vector ¶ms, bool t_test) { if (params.size() != n) { throw arity_error(params.size(), n); } else { - return Handle_Return::call(boost::bind(f BOOST_PP_REPEAT(n, casthelper, ~))); + return f(BOOST_PP_REPEAT(n, casthelper, ~)); } } @@ -97,25 +116,18 @@ namespace chaiscript * registration of two functions with the exact same signatures */ template - bool compare_types(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)), + bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector ¶ms) { - if (params.size() != n) - { + try { + BOOST_PP_REPEAT(n, trycast, ~); + } catch (const bad_boxed_cast &) { return false; - } else { - bool val = true BOOST_PP_REPEAT(n, comparetype, ~); - if (val) return true; - - try { - BOOST_PP_REPEAT(n, trycast, ~); - } catch (const bad_boxed_cast &) { - return false; - } - - return true; } + + return true; } + } #endif diff --git a/src/example.cpp b/src/example.cpp index 317e0cb..9b3f7aa 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -45,7 +45,7 @@ struct System } }; -void take_shared_ptr(const boost::shared_ptr &p) +void take_shared_ptr(const boost::shared_ptr &p) { std::cout << *p << std::endl; } @@ -130,7 +130,7 @@ int main(int argc, char *argv[]) { chai.add(bootstrap::vector_type >("IntVector")); - chai("dump_system()"); +// chai("dump_system()"); chai("take_shared_ptr(\"Hello World as a shared_ptr\");"); }