diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 15f6c00..fe1e924 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -119,7 +119,7 @@ namespace chaiscript class Dispatch_Function : public Proxy_Function_Base { public: - Dispatch_Function(const std::vector > &t_funcs) + Dispatch_Function(const std::vector &t_funcs) : Proxy_Function_Base(build_type_infos(t_funcs)), m_funcs(t_funcs) { @@ -139,39 +139,26 @@ namespace chaiscript virtual std::vector get_contained_functions() const { - typedef std::vector > function_vec; - - function_vec::const_iterator begin = m_funcs.begin(); - const function_vec::const_iterator end = m_funcs.end(); - - std::vector fs; - - while (begin != end) - { - fs.push_back(begin->second); - ++begin; - } - - return fs; + return std::vector(m_funcs.begin(), m_funcs.end()); } virtual int get_arity() const { - typedef std::vector > function_vec; + typedef std::vector function_vec; function_vec::const_iterator begin = m_funcs.begin(); const function_vec::const_iterator end = m_funcs.end(); if (begin != end) { - int arity = begin->second->get_arity(); + int arity = (*begin)->get_arity(); ++begin; while (begin != end) { - if (arity != begin->second->get_arity()) + if (arity != (*begin)->get_arity()) { // The arities in the list do not match, so it's unspecified return -1; @@ -188,14 +175,14 @@ namespace chaiscript virtual bool call_match(const std::vector &vals) const { - typedef std::vector > function_vec; + typedef std::vector function_vec; function_vec::const_iterator begin = m_funcs.begin(); function_vec::const_iterator end = m_funcs.end(); while (begin != end) { - if (begin->second->call_match(vals)) + if ((*begin)->call_match(vals)) { return true; } else { @@ -218,18 +205,18 @@ namespace chaiscript } private: - std::vector > m_funcs; + std::vector m_funcs; - static std::vector build_type_infos(const std::vector > &t_funcs) + static std::vector build_type_infos(const std::vector &t_funcs) { - typedef std::vector > function_vec; + typedef std::vector function_vec; function_vec::const_iterator begin = t_funcs.begin(); const function_vec::const_iterator end = t_funcs.end(); if (begin != end) { - std::vector type_infos = begin->second->get_param_types(); + std::vector type_infos = (*begin)->get_param_types(); ++begin; @@ -237,7 +224,7 @@ namespace chaiscript while (begin != end) { - std::vector param_types = begin->second->get_param_types(); + std::vector param_types = (*begin)->get_param_types(); if (param_types.size() != type_infos.size()) { @@ -316,7 +303,7 @@ namespace chaiscript struct State { - std::multimap m_functions; + std::map > m_functions; std::map m_global_objects; Type_Name_Map m_types; std::set m_reserved_words; @@ -486,23 +473,20 @@ namespace chaiscript } // If all that failed, then check to see if it's a function - std::vector::mapped_type> > funcs = get_function(name); + std::vector funcs = get_function(name); if (funcs.empty()) { throw std::range_error("Object not known: " + name); } else { - if (funcs.size() == 1) { // Return the first item if there is only one, // no reason to take the cast of the extra level of dispatch - return const_var(funcs.begin()->second); + return const_var(*funcs.begin()); + } else { + return Boxed_Value(Const_Proxy_Function(new Dispatch_Function(funcs))); } - - - Boxed_Value f(Const_Proxy_Function(new Dispatch_Function(funcs))); - return f; } } @@ -578,17 +562,25 @@ namespace chaiscript /** * Return a function by name */ - std::vector > + std::vector< Proxy_Function > get_function(const std::string &t_name) const { #ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_mutex); #endif - std::pair::const_iterator, std::multimap::const_iterator> range - = get_functions_int().equal_range(t_name); + const std::map > &funs = get_functions_int(); + + std::map >::const_iterator itr + = funs.find(t_name); + + if (itr != funs.end()) + { + return itr->second; + } else { + return std::vector(); + } - return std::vector::mapped_type> >(range.first, range.second); } /** @@ -600,7 +592,7 @@ namespace chaiscript boost::shared_lock l(m_mutex); #endif - const std::multimap &functions = get_functions_int(); + const std::map > &functions = get_functions_int(); return functions.find(name) != functions.end(); } @@ -612,9 +604,23 @@ namespace chaiscript #ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_mutex); #endif + std::vector > rets; - const std::multimap &functions = get_functions_int(); - return std::vector >(functions.begin(), functions.end()); + const std::map > &functions = get_functions_int(); + + for (std::map >::const_iterator itr = functions.begin(); + itr != functions.end(); + ++itr) + { + for (std::vector::const_iterator itr2 = itr->second.begin(); + itr2 != itr->second.end(); + ++itr2) + { + rets.push_back(std::make_pair(itr->first, *itr2)); + } + } + + return rets; } void add_reserved_word(const std::string &name) @@ -628,7 +634,7 @@ namespace chaiscript Boxed_Value call_function(const std::string &t_name, const std::vector ¶ms) const { - std::vector > functions = get_function(t_name); + std::vector functions = get_function(t_name); return dispatch(functions.begin(), functions.end(), params); } @@ -787,12 +793,12 @@ namespace chaiscript return *(m_stack_holder->stack); } - const std::multimap &get_functions_int() const + const std::map > &get_functions_int() const { return m_state.m_functions; } - std::multimap &get_functions_int() + std::map > &get_functions_int() { return m_state.m_functions; } @@ -818,25 +824,36 @@ namespace chaiscript * true if the function was added, false if a function with the * same signature and name already exists. */ - bool add_function(const Proxy_Function &f, const std::string &t_name) + bool add_function(const Proxy_Function &t_f, const std::string &t_name) { #ifndef CHAISCRIPT_NO_THREADS boost::unique_lock l(m_mutex); #endif - std::pair::const_iterator, std::multimap::const_iterator> range - = m_state.m_functions.equal_range(t_name); + std::map > &funcs = get_functions_int(); + + std::map >::iterator itr + = funcs.find(t_name); - while (range.first != range.second) + if (itr != funcs.end()) { - if ((*f) == *(range.first->second)) + std::vector &vec = itr->second; + for (std::vector::const_iterator itr2 = vec.begin(); + itr2 != vec.end(); + ++itr2) { - return false; + if ((*t_f) == *(*itr2)) + { + return false; + } } - ++range.first; - } - m_state.m_functions.insert(std::make_pair(t_name, f)); + vec.push_back(t_f); + } else { + std::vector vec; + vec.push_back(t_f); + funcs.insert(std::make_pair(t_name, vec)); + } return true; } diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index 746f476..51899d1 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -30,7 +30,7 @@ namespace chaiscript */ template boost::function - functor(const std::vector > &funcs) + functor(const std::vector &funcs) { FunctionType *p=0; return detail::build_function_caller_helper(p, funcs); @@ -53,8 +53,8 @@ namespace chaiscript boost::function functor(Const_Proxy_Function func) { - std::vector > funcs; - funcs.push_back(std::make_pair(std::string(), func)); + std::vector funcs; + funcs.push_back(func); return functor(funcs); } diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 1305c73..ab97d17 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -32,7 +32,7 @@ namespace chaiscript template struct Function_Caller_Ret { - static Ret call(const std::vector > &t_funcs, + static Ret call(const std::vector &t_funcs, const std::vector ¶ms) { return boxed_cast(dispatch(t_funcs, params)); @@ -45,7 +45,7 @@ namespace chaiscript template<> struct Function_Caller_Ret { - static void call(const std::vector > &t_funcs, + static void call(const std::vector &t_funcs, const std::vector ¶ms) { dispatch(t_funcs, params); @@ -70,14 +70,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 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); } /** @@ -85,13 +85,14 @@ 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) { if (funcs.size() == 1) { boost::shared_ptr > pfi = boost::dynamic_pointer_cast > - (funcs[0].second); + (funcs[0]); + if (pfi) { return pfi->internal_function(); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 272198a..e3a994f 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -583,9 +583,9 @@ namespace chaiscript while (begin != end) { try { - if (begin->second->filter(plist)) + if ((*begin)->filter(plist)) { - return (*begin->second)(plist); + return (*(*begin))(plist); } } catch (const bad_boxed_cast &) { //parameter failed to cast, try again