Further updates to the new bound function support, plus general cleanup of how it is used

This commit is contained in:
Jason Turner 2009-10-15 15:27:16 +00:00
parent 24e717d532
commit b1d12fdc91
3 changed files with 63 additions and 78 deletions

View File

@ -7,7 +7,7 @@
#include <boost/preprocessor.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#define param(z,n,text) BOOST_PP_CAT(_, BOOST_PP_INC(n))
#define param(z,n,text) BOOST_PP_CAT(text, BOOST_PP_INC(n))
#ifndef BOOST_PP_IS_ITERATING
#ifndef __bind_first_hpp__
@ -35,21 +35,28 @@ namespace chaiscript
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const O &o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
}
template<typename Ret, typename O, 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, const O &o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
}
template<typename Ret,typename O BOOST_PP_COMMA_IF(m) BOOST_PP_ENUM_PARAMS(m, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(m, Param))>
bind_first(Ret (*f)(BOOST_PP_ENUM_PARAMS(m, Param)), const O &o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, ~));
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
}
template<typename Ret,typename O BOOST_PP_COMMA_IF(m) BOOST_PP_ENUM_PARAMS(m, typename Param) >
boost::function<Ret (BOOST_PP_ENUM(n, param, Param))>
bind_first(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(m, Param))> &f, const O &o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
}

View File

@ -4,9 +4,6 @@
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#ifndef BOOST_PP_IS_ITERATING
#ifndef __register_function_hpp__
#define __register_function_hpp__
@ -14,6 +11,8 @@
#include "bind_first.hpp"
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/function_types/components.hpp>
#include <boost/function_types/function_type.hpp>
namespace chaiscript
{
@ -29,81 +28,63 @@ namespace chaiscript
}
template<typename T>
Proxy_Function fun_helper(const boost::function<T> &f)
boost::function<T> mk_boost_fun(const boost::function<T> &f)
{
return Proxy_Function(new Proxy_Function_Impl<T>(f));
return f;
}
template<typename T>
boost::function<
typename boost::function_types::function_type<boost::function_types::components<T> >::type
> mk_boost_fun(T t)
{
return
boost::function<
typename boost::function_types::function_type<boost::function_types::components<T> >::type
>(t);
}
/**
* Automatically create a get_member helper function for an object
* to allow for runtime dispatched access to public data members
* for example, the case of std::pair<>::first and std::pair<>::second
*/
template<typename T, typename Class>
Proxy_Function fun_helper(T Class::* m)
{
return fun_helper(boost::function<T& (Class *)>(boost::bind(&detail::get_member<T, Class>, m, _1)));
}
}
}
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/register_function.hpp>
#include BOOST_PP_ITERATE()
namespace chaiscript
template<typename T>
Proxy_Function fun_helper(const boost::function<T> &f)
{
return Proxy_Function(new Proxy_Function_Impl<T>(f));
}
}
template<typename T>
Proxy_Function fun(const boost::function<T> &f)
{
return detail::fun_helper(f);
}
template<typename T>
Proxy_Function fun(T t)
{
return detail::fun_helper(t);
return detail::fun_helper(detail::mk_boost_fun(t));
}
template<typename T, typename Q>
Proxy_Function bound_fun(T t, Q q)
Proxy_Function fun(T t, const Q &q)
{
return detail::fun_helper(bind_first(t, q));
}
template<typename T, typename Q, typename R>
Proxy_Function fun(T t, const Q &q, const R &r)
{
return detail::fun_helper(bind_first(bind_first(t, q), r));
}
}
# endif
#else
# define n BOOST_PP_ITERATION()
namespace chaiscript
{
namespace detail
{
/**
* Register a global function of n parameters with name
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
Proxy_Function fun_helper(Ret (*f)(BOOST_PP_ENUM_PARAMS(n, Param)))
{
return fun_helper(boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>(f));
}
/**
* Register a class method of n parameters with name
*/
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
Proxy_Function fun_helper(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)))
{
return fun_helper(boost::function<Ret (Class* BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param))>(f));
}
/**
* Register a const class method of n parameters with name
*/
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
Proxy_Function fun_helper(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const)
{
return fun_helper(boost::function<Ret (const Class* BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param))>(f));
}
}
}
#endif

View File

@ -493,30 +493,27 @@ namespace chaiscript
add(Bootstrap::bootstrap());
engine.add(bound_fun(&Eval_Engine::dump_system, boost::ref(engine)), "dump_system");
engine.add(bound_fun(&Eval_Engine::dump_object, boost::ref(engine)), "dump_object");
engine.add(bound_fun(&Eval_Engine::is_type, boost::ref(engine)), "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(&Eval_Engine::dump_system, boost::ref(engine)), "dump_system");
engine.add(fun(&Eval_Engine::dump_object, boost::ref(engine)), "dump_object");
engine.add(fun(&Eval_Engine::is_type, boost::ref(engine)), "is_type");
engine.add(fun(&Eval_Engine::type_name, boost::ref(engine)), "type_name");
engine.add(fun(&Eval_Engine::function_exists, boost::ref(engine)), "function_exists");
engine.add(fun(boost::function<void (const std::string &)>(
boost::bind(static_cast<void (ChaiScript_System<Eval_Engine>::*)(const std::string&)>(
&ChaiScript_System<Eval_Engine>::load_module), boost::ref(*this), _1))),
"load_module");
typedef void (ChaiScript_System<Eval_Engine>::*load_mod_1)(const std::string&);
typedef void (ChaiScript_System<Eval_Engine>::*load_mod_2)(const std::string&, const std::string&);
engine.add(fun(static_cast<load_mod_1>(&ChaiScript_System<Eval_Engine>::load_module)), "load_module");
engine.add(fun(static_cast<load_mod_2>(&ChaiScript_System<Eval_Engine>::load_module)), "load_module");
engine.add(fun(boost::function<void (const std::string &, const std::string &)>(
boost::bind(static_cast<void (ChaiScript_System<Eval_Engine>::*)(const std::string&, const std::string&)>(
&ChaiScript_System<Eval_Engine>::load_module), boost::ref(*this), _1, _2))),
"load_module");
add(vector_type<std::vector<Boxed_Value> >("Vector"));
add(string_type<std::string>("string"));
add(map_type<std::map<std::string, Boxed_Value> >("Map"));
add(pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
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(fun(&ChaiScript_System<Eval_Engine>::use, this), "use");
engine.add(fun(&ChaiScript_System<Eval_Engine>::internal_eval, this), "eval");
do_eval(chaiscript_prelude, "standard prelude");