[C++-sig] [python] Function objects in place of member functions
troy d. straszheim
troy at resophonic.com
Mon Oct 12 01:44:29 CEST 2009
Ravi wrote:
[snip]
>
> In order to use a function object in place of a free function, one must
> specialize/overload
> boost::python::detail::get_signature
> which, for some reason, does not account for function objects. Here's a very
> simple example that works:
>
[snip]
>
> However, note that the overload of get_signature precedes the inclusion of the
> boost.python headers, which is extremely inconvenient. However, if the headers
> are moved to their proper location as in the following,
>
[snip]
>
> Why is the overloaded get_signature not picked up when it is declared *after*
> the inclusion of the headers?
>
I'm not sure why it isn't picked up. I've been working in this area,
replacing most of detail/caller.hpp and detail/invoke.hpp with
boost.fusion, seen here:
http://gitorious.org/~straszheim/boost/straszheim/blobs/python/boost/python/detail/caller.hpp
In the process, I overhauled get_signature to use boost::function_types,
and to be a metafunction, not a function:
http://gitorious.org/~straszheim/boost/straszheim/blobs/python/boost/python/signature.hpp
The overall effect is a lot less preprocessor stuff to look around.
I have function objects (given a specialization of get_signature), and
boost::function (only up to 3 arguments ATM) working,
here's the test (which passes):
/////////////////////////////////////
#include <boost/mpl/vector.hpp>
#include <boost/function.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
namespace mpl = boost::mpl;
struct X { int y; };
struct FnObject
{
typedef int result_type;
int operator()(X *x, int z) const
{
return z + x->y;
}
};
int f1(X* x) { return x->y ; }
int f2(X* x, int i) { return x->y * i; }
int f3(X* x, int i, int j) { return x->y * i + j; }
namespace boost {
namespace python {
namespace detail {
template<>
struct get_signature<FnObject, X>
{
typedef mpl::vector<int, X*, int> type;
};
}
}
}
using namespace boost::python;
BOOST_PYTHON_MODULE( function_objects_ext )
{
FnObject fobj;
boost::function<int(X*, int)> bf0(fobj);
boost::function<int(X*)> bf1(f1);
boost::function<int(X*, int)> bf2(f2);
boost::function<int(X*, int, double)> bf3(f3);
boost::python::class_<X>( "X" )
.def( "fobj", fobj)
.def( "bf0", bf0)
.def( "bf1", bf1)
.def( "bf2", bf2)
.def( "bf3", bf3)
.def_readwrite( "y", &X::y )
;
}
/////////////////////////////
>>> from function_objects_ext import *
>>> x = X()
>>> x.y = 13
>>> x.fobj(12)
25
>>> x.bf1()
13
>>> x.bf2(2)
26
>>> x.bf3(2, -27)
-1
/////////////////////////////
I'm fairly new to the internals of boost.python, and only just now got
this working... Do you see problems with this, specifically the
conversion of get_signature from function to metafunction?
-t
More information about the Cplusplus-sig
mailing list