Add bound_fun helper and put it to use cleaning up the engine bootstrapping

This commit is contained in:
Jason Turner
2009-10-14 02:34:09 +00:00
parent 12e909d9aa
commit 480761c1f7
5 changed files with 99 additions and 20 deletions

View File

@@ -0,0 +1,79 @@
// This file is distributed under the BSD License.
// See "license.txt" for details.
// Copyright 2009, Jonathan Turner (jturner@minnow-lang.org)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#define param(z,n,text) BOOST_PP_CAT(_, BOOST_PP_INC(n))
#ifndef BOOST_PP_IS_ITERATING
#ifndef __bind_first_hpp__
#define __bind_first_hpp__
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#define BOOST_PP_ITERATION_LIMITS ( 0, 8 )
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/bind_first.hpp>
#include BOOST_PP_ITERATE()
# endif
#else
# define n BOOST_PP_ITERATION()
namespace chaiscript
{
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), boost::reference_wrapper<Class> &o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
}
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)) const, boost::reference_wrapper<Class> &o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
}
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), Class *o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
}
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const, Class *o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
}
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), boost::shared_ptr<Class> o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
}
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const, boost::shared_ptr<Class> o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
}
}
#endif

View File

@@ -575,7 +575,7 @@ namespace chaiscript
/** /**
* return true if the Boxed_Value matches the registered type by name * return true if the Boxed_Value matches the registered type by name
*/ */
bool is_type(const std::string &user_typename, Boxed_Value r) const bool is_type(Boxed_Value r, const std::string &user_typename) const
{ {
try { try {
if (get_type(user_typename).bare_equal(r.get_type_info())) if (get_type(user_typename).bare_equal(r.get_type_info()))

View File

@@ -11,6 +11,7 @@
#define __register_function_hpp__ #define __register_function_hpp__
#include "dispatchkit.hpp" #include "dispatchkit.hpp"
#include "bind_first.hpp"
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
@@ -57,6 +58,12 @@ namespace chaiscript
{ {
return detail::fun_helper(t); return detail::fun_helper(t);
} }
template<typename T, typename Q>
Proxy_Function bound_fun(T t, Q q)
{
return detail::fun_helper(bind_first(t, q));
}
} }

View File

@@ -300,8 +300,8 @@ namespace chaiscript
/** /**
* Evaluates the given boxed string, used during eval() inside of a script * Evaluates the given boxed string, used during eval() inside of a script
*/ */
const Boxed_Value internal_eval(const std::vector<Boxed_Value> &vals) { const Boxed_Value internal_eval(const std::string &e) {
return do_eval(boxed_cast<std::string>(vals.at(0)), "__EVAL__", true); return do_eval(e, "__EVAL__", true);
} }
void use(const std::string &filename) void use(const std::string &filename)
@@ -491,18 +491,13 @@ namespace chaiscript
engine.add_reserved_word("false"); engine.add_reserved_word("false");
engine.add_reserved_word("_"); engine.add_reserved_word("_");
add(Bootstrap::bootstrap()); add(Bootstrap::bootstrap());
engine.add(fun(boost::function<void ()>(boost::bind(&Eval_Engine::dump_system, boost::ref(engine)))), "dump_system"); engine.add(bound_fun(&Eval_Engine::dump_system, boost::ref(engine)), "dump_system");
engine.add(fun(boost::function<void (Boxed_Value)>(boost::bind(&Eval_Engine::dump_object, boost::ref(engine), _1))), "dump_object"); engine.add(bound_fun(&Eval_Engine::dump_object, boost::ref(engine)), "dump_object");
engine.add(fun(boost::function<bool (Boxed_Value, const std::string &)>(boost::bind(&Eval_Engine::is_type, boost::ref(engine), _2, _1))), engine.add(bound_fun(&Eval_Engine::is_type, boost::ref(engine)), "is_type");
"is_type"); engine.add(bound_fun(&Eval_Engine::type_name, boost::ref(engine)), "type_name");
engine.add(bound_fun(&Eval_Engine::function_exists, boost::ref(engine)), "function_exists");
engine.add(fun(boost::function<std::string (Boxed_Value)>(boost::bind(&Eval_Engine::type_name, boost::ref(engine), _1))),
"type_name");
engine.add(fun(boost::function<bool (const std::string &)>(boost::bind(&Eval_Engine::function_exists, boost::ref(engine), _1))),
"function_exists");
engine.add(fun(boost::function<void (const std::string &)>( engine.add(fun(boost::function<void (const std::string &)>(
@@ -520,13 +515,8 @@ namespace chaiscript
add(map_type<std::map<std::string, Boxed_Value> >("Map")); add(map_type<std::map<std::string, Boxed_Value> >("Map"));
add(pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair")); add(pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
engine.add(fun(boost::function<void (const std::string &)>(boost::bind(&ChaiScript_System<Eval_Engine>::use, this, _1))), "use"); engine.add(bound_fun(&ChaiScript_System<Eval_Engine>::use, this), "use");
engine.add(bound_fun(&ChaiScript_System<Eval_Engine>::internal_eval, this), "eval");
engine.add(Proxy_Function(
new Dynamic_Proxy_Function(boost::bind(&ChaiScript_System<Eval_Engine>::internal_eval, boost::ref(*this), _1), 1)), "eval");
do_eval(chaiscript_prelude, "standard prelude"); do_eval(chaiscript_prelude, "standard prelude");

View File

@@ -71,6 +71,9 @@ int main(int argc, char *argv[]) {
System system; System system;
chai.add(var(&system), "system"); chai.add(var(&system), "system");
//Add a bound callback method
chai.add(bound_fun(&System::add_callback, system), "add_callback_bound");
//Register the two methods of the System structure. //Register the two methods of the System structure.
chai.add(fun(&System::add_callback), "add_callback"); chai.add(fun(&System::add_callback), "add_callback");
chai.add(fun(&System::do_callbacks), "do_callbacks"); chai.add(fun(&System::do_callbacks), "do_callbacks");