From b53432cf28d7c47179b5bc8b2dbf80e6cce7282e Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 23 Jun 2015 13:02:43 -0600 Subject: [PATCH] Remove remaining uses of std::function --- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- .../dispatchkit/proxy_functions.hpp | 120 ++++++++++++------ .../chaiscript/language/chaiscript_engine.hpp | 6 +- .../chaiscript/language/chaiscript_eval.hpp | 72 ++++++----- 4 files changed, 124 insertions(+), 76 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 8f2b3c7..d832db1 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -520,7 +520,7 @@ namespace chaiscript m->add(fun(&print), "print_string"); m->add(fun(&println), "println_string"); - m->add(chaiscript::make_shared(&bind_function), "bind"); + m->add(dispatch::make_dynamic_proxy_function(&bind_function), "bind"); m->add(fun(&shared_ptr_unconst_clone), "clone"); m->add(fun(&ptr_assign::type>), "="); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index ee3029f..1e761fe 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -302,7 +302,6 @@ namespace chaiscript { public: Dynamic_Proxy_Function( - std::function &)> t_f, int t_arity=-1, AST_NodePtr t_parsenode = AST_NodePtr(), Param_Types t_param_types = Param_Types(), @@ -310,8 +309,7 @@ namespace chaiscript Proxy_Function t_guard = Proxy_Function()) : Proxy_Function_Base(build_param_type_list(t_param_types), t_arity), m_param_types(std::move(t_param_types)), - m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)), m_description(std::move(t_description)), - m_f(std::move(t_f)) + m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)), m_description(std::move(t_description)) { } @@ -350,6 +348,75 @@ namespace chaiscript return m_description; } + + protected: + bool test_guard(const std::vector ¶ms, const Type_Conversions &t_conversions) const + { + if (m_guard) + { + try { + return boxed_cast((*m_guard)(params, t_conversions)); + } catch (const exception::arity_error &) { + return false; + } catch (const exception::bad_boxed_cast &) { + return false; + } + } else { + return true; + } + } + + private: + static std::vector build_param_type_list(const Param_Types &t_types) + { + // For the return type + std::vector types{chaiscript::detail::Get_Type_Info::get()}; + + for (const auto &t : t_types.types()) + { + if (t.second.is_undef()) { + types.push_back(chaiscript::detail::Get_Type_Info::get()); + } else { + types.push_back(t.second); + } + } + + return types; + } + + Param_Types m_param_types; + Proxy_Function m_guard; + AST_NodePtr m_parsenode; + std::string m_description; + }; + + + + template + class Dynamic_Proxy_Function_Impl : public Dynamic_Proxy_Function + { + public: + Dynamic_Proxy_Function_Impl( + Callable t_f, + int t_arity=-1, + AST_NodePtr t_parsenode = AST_NodePtr(), + Param_Types t_param_types = Param_Types(), + std::string t_description = "", + Proxy_Function t_guard = Proxy_Function()) + : Dynamic_Proxy_Function( + t_arity, + std::move(t_parsenode), + std::move(t_param_types), + std::move(t_description), + std::move(t_guard) + ), + m_f(std::move(t_f)) + { + } + + virtual ~Dynamic_Proxy_Function_Impl() {} + + protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { @@ -368,48 +435,17 @@ namespace chaiscript } private: - bool test_guard(const std::vector ¶ms, const Type_Conversions &t_conversions) const - { - if (m_guard) - { - try { - return boxed_cast((*m_guard)(params, t_conversions)); - } catch (const exception::arity_error &) { - return false; - } catch (const exception::bad_boxed_cast &) { - return false; - } - } else { - return true; - } - } - static std::vector build_param_type_list(const Param_Types &t_types) - { - std::vector types; - - // For the return type - types.push_back(chaiscript::detail::Get_Type_Info::get()); - - for (const auto &t : t_types.types()) - { - if (t.second.is_undef()) { - types.push_back(chaiscript::detail::Get_Type_Info::get()); - } else { - types.push_back(t.second); - } - } - - return types; - } - - Param_Types m_param_types; - Proxy_Function m_guard; - AST_NodePtr m_parsenode; - std::string m_description; - std::function &)> m_f; + Callable m_f; }; + template + Proxy_Function make_dynamic_proxy_function(Callable &&c, Arg&& ... a) + { + return chaiscript::make_shared>( + std::forward(c), std::forward(a)...); + } + /// An object used by Bound_Function to represent "_" parameters /// of a binding. This allows for unbound parameters during bind. struct Placeholder_Object diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 8d97aaa..a6a604a 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -363,10 +363,12 @@ namespace chaiscript m_engine.add(fun([this](){ return m_engine.get_function_objects(); }), "get_functions"); m_engine.add(fun([this](){ return m_engine.get_scripting_objects(); }), "get_objects"); - m_engine.add(chaiscript::make_shared( + m_engine.add( + dispatch::make_dynamic_proxy_function( [this](const std::vector &t_params) { return m_engine.call_exists(t_params); - }), "call_exists"); + }) + , "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"); // diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 9efbcbc..e56e0f2 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -739,12 +739,15 @@ namespace chaiscript const auto &lambda_node = this->children.back(); - return Boxed_Value(chaiscript::make_shared( - [&t_ss, lambda_node, param_names, captures](const std::vector &t_params) - { - return detail::eval_function(t_ss, lambda_node, param_names, t_params, captures); - }, - static_cast(numparams), lambda_node, param_types)); + return Boxed_Value( + dispatch::make_dynamic_proxy_function( + [&t_ss, lambda_node, param_names, captures](const std::vector &t_params) + { + return detail::eval_function(t_ss, lambda_node, param_names, t_params, captures); + }, + static_cast(numparams), lambda_node, param_types + ) + ); } private: @@ -801,25 +804,28 @@ namespace chaiscript } } - std::shared_ptr guard; + std::shared_ptr guard; if (guardnode) { - guard = std::make_shared - ([&t_ss, guardnode, t_param_names](const std::vector &t_params) - { - return detail::eval_function(t_ss, guardnode, t_param_names, t_params); - }, static_cast(numparams), guardnode); + guard = dispatch::make_dynamic_proxy_function( + [&t_ss, guardnode, t_param_names](const std::vector &t_params) + { + return detail::eval_function(t_ss, guardnode, t_param_names, t_params); + }, + static_cast(numparams), guardnode); } try { const std::string & l_function_name = this->children[0]->text; const std::string & l_annotation = this->annotation?this->annotation->text:""; const auto & func_node = this->children.back(); - t_ss.add(chaiscript::make_shared - ([&t_ss, guardnode, func_node, t_param_names](const std::vector &t_params) - { - return detail::eval_function(t_ss, func_node, t_param_names, t_params); - }, static_cast(numparams), this->children.back(), - param_types, l_annotation, guard), l_function_name); + t_ss.add( + dispatch::make_dynamic_proxy_function( + [&t_ss, guardnode, func_node, t_param_names](const std::vector &t_params) + { + return detail::eval_function(t_ss, func_node, t_param_names, t_params); + }, + static_cast(numparams), this->children.back(), + param_types, l_annotation, guard), l_function_name); } catch (const exception::reserved_word_error &e) { throw exception::eval_error("Reserved word used as function name '" + e.word() + "'"); @@ -1399,12 +1405,13 @@ namespace chaiscript const size_t numparams = t_param_names.size(); - std::shared_ptr guard; + std::shared_ptr guard; if (guardnode) { - guard = std::make_shared - ([&t_ss, t_param_names, guardnode](const std::vector &t_params) { - return chaiscript::eval::detail::eval_function(t_ss, guardnode, t_param_names, t_params, std::map()); - }, static_cast(numparams), guardnode); + guard = dispatch::make_dynamic_proxy_function( + [&t_ss, t_param_names, guardnode](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(t_ss, guardnode, t_param_names, t_params, std::map()); + }, + static_cast(numparams), guardnode); } try { @@ -1415,12 +1422,15 @@ namespace chaiscript if (function_name == class_name) { param_types.push_front(class_name, Type_Info()); - t_ss.add(std::make_shared(class_name, - std::make_shared( - [&t_ss, t_param_names, node](const std::vector &t_params) { - return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map()); - }, - static_cast(numparams), node, param_types, l_annotation, guard)), + t_ss.add( + std::make_shared(class_name, + dispatch::make_dynamic_proxy_function( + [&t_ss, t_param_names, node](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map()); + }, + static_cast(numparams), node, param_types, l_annotation, guard + ) + ), function_name); } else { @@ -1429,8 +1439,8 @@ namespace chaiscript auto type = t_ss.get_type(class_name, false); param_types.push_front(class_name, type); - t_ss.add(std::make_shared(class_name, - std::make_shared( + t_ss.add(std::make_shared(class_name, + dispatch::make_dynamic_proxy_function( [&t_ss, t_param_names, node](const std::vector &t_params) { return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map()); },