Add support for function binding and cut down on some includes
This commit is contained in:
parent
96f3033a42
commit
46859b1918
@ -431,6 +431,19 @@ namespace dispatchkit
|
||||
register_function(s, &multiply<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>, "*");
|
||||
}
|
||||
|
||||
static Boxed_Value bind_function(const std::vector<Boxed_Value> ¶ms)
|
||||
{
|
||||
if (params.size() < 2)
|
||||
{
|
||||
throw arity_error(params.size(), 2);
|
||||
}
|
||||
|
||||
boost::shared_ptr<Proxy_Function> f = boxed_cast<boost::shared_ptr<Proxy_Function> >(params[0]);
|
||||
|
||||
return Boxed_Value(boost::shared_ptr<Proxy_Function>(new Bound_Function(f,
|
||||
std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
|
||||
}
|
||||
|
||||
static void bootstrap(Dispatch_Engine &s)
|
||||
{
|
||||
s.register_type<void>("void");
|
||||
@ -441,6 +454,7 @@ namespace dispatchkit
|
||||
add_basic_constructors<std::string>(s, "string");
|
||||
add_oper_assign<std::string>(s);
|
||||
|
||||
|
||||
register_function(s, &to_string<const std::string &>, "to_string");
|
||||
register_function(s, &to_string<bool>, "to_string");
|
||||
register_function(s, &unknown_assign, "=");
|
||||
@ -466,6 +480,9 @@ namespace dispatchkit
|
||||
s.register_function(boost::function<void ()>(boost::bind(&dump_system, boost::ref(s))), "dump_system");
|
||||
s.register_function(boost::function<void (Boxed_Value)>(boost::bind(&dump_object, _1)), "dump_object");
|
||||
|
||||
s.register_function(boost::shared_ptr<Proxy_Function>(new Dynamic_Proxy_Function(boost::bind(&bind_function, _1))),
|
||||
"bind");
|
||||
|
||||
register_function(s, &bool_and<bool, bool>, "&&");
|
||||
register_function(s, &bool_or<bool, bool>, "||");
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
|
||||
namespace dispatchkit
|
||||
{
|
||||
|
@ -158,6 +158,69 @@ namespace dispatchkit
|
||||
int m_arity;
|
||||
};
|
||||
|
||||
class Bound_Function : public Proxy_Function
|
||||
{
|
||||
public:
|
||||
Bound_Function(const boost::shared_ptr<Proxy_Function> &t_f,
|
||||
const std::vector<Boxed_Value> &t_args)
|
||||
: m_f(t_f), m_args(t_args)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const Proxy_Function &f) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual ~Bound_Function() {}
|
||||
|
||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms)
|
||||
{
|
||||
typedef std::vector<Boxed_Value>::const_iterator pitr;
|
||||
|
||||
pitr parg = params.begin();
|
||||
pitr barg = m_args.begin();
|
||||
|
||||
std::vector<Boxed_Value> args;
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (barg != m_args.end() && !barg->is_unknown())
|
||||
{
|
||||
args.push_back(*barg);
|
||||
++barg;
|
||||
}
|
||||
|
||||
if (parg != params.end())
|
||||
{
|
||||
args.push_back(*parg);
|
||||
++parg;
|
||||
}
|
||||
|
||||
if (barg != m_args.end() && barg->is_unknown())
|
||||
{
|
||||
++barg;
|
||||
}
|
||||
|
||||
if (parg == params.end() && barg == m_args.end())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (*m_f)(args);
|
||||
}
|
||||
|
||||
virtual std::vector<Type_Info> get_param_types()
|
||||
{
|
||||
return std::vector<Type_Info>();
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<Proxy_Function> m_f;
|
||||
std::vector<Boxed_Value> m_args;
|
||||
};
|
||||
|
||||
template<typename Func>
|
||||
class Proxy_Function_Impl : public Proxy_Function
|
||||
{
|
||||
|
@ -1,7 +1,13 @@
|
||||
#ifndef __type_info_hpp__
|
||||
#define __type_info_hpp__
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
namespace dispatchkit
|
||||
|
30
samples/bind.chai
Normal file
30
samples/bind.chai
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
//This is a cheater function. The entire point of it is to return a variable
|
||||
// with an unspecified type.
|
||||
// The bind function will substitute any unknown object with those passed in
|
||||
def _()
|
||||
{
|
||||
var i;
|
||||
return i;
|
||||
}
|
||||
|
||||
def add(x, y)
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
|
||||
var b = bind(add, 2, _());
|
||||
var c = bind(b, 3);
|
||||
|
||||
print(b(4));
|
||||
print(c());
|
||||
|
||||
|
||||
def concat(a,b,c,d)
|
||||
{
|
||||
return to_string(a) + to_string(b) + to_string(c) + to_string(d);
|
||||
}
|
||||
|
||||
var d = bind(concat, _(), " Hello ", _(), " World ");
|
||||
print(d(1, 3));
|
||||
print(d(1, 3, 4));
|
Loading…
x
Reference in New Issue
Block a user