[C++-sig] [python] python + phoenix
troy d. straszheim
troy at resophonic.com
Thu Oct 15 03:59:42 CEST 2009
Ravi wrote:
>
> I'd rather have something along the lines of
> .def< mpl::vector<void,T*,double> >("f1",f1)
I have something working. There is still a bunch of stuff to iron out
yet. I went with
def("name", as<Signature>(callable));
where Signature is the signature with which callable will be called,
e.g.
struct times_seven
{
template <typename T> struct result;
template <typename Self, typename T>
struct result<Self(T&)> // annoying: reference
{
typedef T type;
};
template <typename T>
T operator()(const T& t)
{
return t * 7;
}
};
BOOST_PYTHON_MODULE( function_objects3_ext )
{
def("times_seven", as<int(int)>(times_seven()));
}
the T& in the struct result is something I haven't yet sorted out, has
something to do with how I am constructing fusion sequences from the
converted python objects before calling fusion::invoke. Anyhow, it
works:
>>> times_seven(7)
49
I thought that one might try to remove the necessity of having the
return type in the Signature and/or implementing the result_of
protocol, but maybe it is nice that they don't have to match:
def("times_seven", as<double(int)>(times_seven()));
>>> times_seven(7)
49.0
boost::function still works, and doesn't require as<>:
boost::function<int(int, int)> myplus = std::plus<int>();
def("myplus", myplus);
and old-school function objects:
def("otherplus", std::plus<int>())
I was surprised to find that it all plays nice with boost::phoenix:
def("plus", as<int(int, int)>(arg1 + arg2));
def("throw_if_gt_5",
as<void(int)>(if_(arg1 > 5)
[ throw_(std::runtime_error("too big!!")) ]
.else_
[ std::cout << val("okay") ]));
And boost::phoenix plays nice with shared_ptr, which plays nice with
boost::python:
struct X { int x; }; typedef boost::shared_ptr<X> XPtr;
class_<X, XPtr>("X")
.def_readwrite("x", &X::x)
.def("add7", as<void(X*)> (arg1->*&X::x += 7))
.def("add8", as<void(XPtr)>(arg1->*&X::x += 8))
.def("add9", as<void(X&)> (bind(&X::x, arg1) += 9))
;
the other little thing is overload resolution, for which I propose a
little helper function "unload" (underload? deload? resolve? I dunno):
void foo(int);
void foo(double);
def("foo", unload<void(int)>(foo));
Which is safer than
def("foo", (void(*)(int)) foo);
and just as safe as, and less verbose than
void(*fooint)(int) = foo;
def("foo", fooint);
So that's where I'm at... what do you make of that interface?
-t
More information about the Cplusplus-sig
mailing list