mirror of
https://github.com/boostorg/python.git
synced 2026-01-25 06:22:15 +00:00
added inlines
[SVN r12232]
This commit is contained in:
@@ -36,7 +36,7 @@ def gen_call(member_function_args, free_function_args = None):
|
||||
return (header % (member_function_args, free_function_args)
|
||||
+ gen_functions(
|
||||
'''template <class R%(, class A%n%)>
|
||||
PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords)
|
||||
inline PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords)
|
||||
, map(lambda cv:
|
||||
gen_functions(
|
||||
'''template <class R, class A0%(, class A%+%)>
|
||||
PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords)
|
||||
inline PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return detail::returning<R>::call(f, args, keywords);
|
||||
}
|
||||
|
||||
99
test/m1.cpp
99
test/m1.cpp
@@ -4,15 +4,13 @@
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// Seems to be neccessary to suppress an ICE with MSVC
|
||||
#include <boost/mpl/comparison/less.hpp>
|
||||
|
||||
#include "simple_type.hpp"
|
||||
#include "complicated.hpp"
|
||||
#include <boost/python/converter/wrapper.hpp>
|
||||
#include <boost/python/converter/unwrapper.hpp>
|
||||
#include <boost/python/detail/config.hpp>
|
||||
#include <boost/python/convert.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/object/value_holder.hpp>
|
||||
#include <boost/python/object/class.hpp>
|
||||
#include <boost/python/converter/class.hpp>
|
||||
@@ -53,17 +51,10 @@ PyTypeObject NoddyType = {
|
||||
};
|
||||
|
||||
// Create a Noddy containing 42
|
||||
extern "C" PyObject*
|
||||
new_noddy(PyObject* self, PyObject* args)
|
||||
PyObject* new_noddy()
|
||||
{
|
||||
NoddyObject* noddy;
|
||||
|
||||
if (!PyArg_ParseTuple(args,":new_noddy"))
|
||||
return NULL;
|
||||
|
||||
noddy = PyObject_New(NoddyObject, &NoddyType);
|
||||
NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType);
|
||||
noddy->x = 42;
|
||||
|
||||
return (PyObject*)noddy;
|
||||
}
|
||||
|
||||
@@ -92,27 +83,13 @@ PyTypeObject SimpleType = {
|
||||
};
|
||||
|
||||
// Create a Simple containing "hello, world"
|
||||
extern "C" PyObject*
|
||||
new_simple(PyObject* self, PyObject* args)
|
||||
PyObject* new_simple()
|
||||
{
|
||||
SimpleObject* simple;
|
||||
|
||||
if (!PyArg_ParseTuple(args,":new_simple"))
|
||||
return NULL;
|
||||
|
||||
simple = PyObject_New(SimpleObject, &SimpleType);
|
||||
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
|
||||
simple->x.s = "hello, world";
|
||||
|
||||
return (PyObject*)simple;
|
||||
}
|
||||
|
||||
// Initial method table for the module
|
||||
static PyMethodDef methods[] = {
|
||||
{ "new_noddy", new_noddy, METH_VARARGS },
|
||||
{ "new_simple", new_simple, METH_VARARGS },
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
//
|
||||
// Declare some wrappers/unwrappers to test the low-level conversion
|
||||
// mechanism. See boost/python/converter/source.hpp,target.hpp for a
|
||||
@@ -252,7 +229,7 @@ simple const& g(simple const& x)
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(m1)
|
||||
{
|
||||
PyObject* m1 = Py_InitModule(const_cast<char*>("m1"), methods);
|
||||
boost::python::module m1("m1");
|
||||
|
||||
// Create the converters; they are self-registering/unregistering.
|
||||
static int_wrapper wrap_int;
|
||||
@@ -262,63 +239,45 @@ BOOST_PYTHON_MODULE_INIT(m1)
|
||||
static noddy_int_ref_unwrapper unwrap_int3;
|
||||
static simple_ref_unwrapper unwrap_simple;
|
||||
static simple_const_ref_unwrapper unwrap_simple_const_ref;
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// These compilers will need additional converters
|
||||
static simple_ref_wrapper wrap_simple_ref;
|
||||
#endif
|
||||
|
||||
// This unwrapper extracts pointers and references to the "complicated" class.
|
||||
static boost::python::converter::class_unwrapper<complicated> unwrap_complicated;
|
||||
|
||||
PyObject* d = PyModule_GetDict(m1);
|
||||
if (d == NULL)
|
||||
return;
|
||||
|
||||
// Insert the extension metaclass object
|
||||
if (PyDict_SetItemString(
|
||||
d, "xclass", (PyObject *)boost::python::object::class_metatype()) < 0)
|
||||
return;
|
||||
|
||||
m1.add(boost::python::objects::class_metatype(), "xclass");
|
||||
|
||||
// Insert the base class for all extension classes
|
||||
if (PyDict_SetItemString(
|
||||
d, "xinst", (PyObject *)boost::python::object::class_type()) < 0)
|
||||
return;
|
||||
m1.add(boost::python::objects::class_type(), "xinst");
|
||||
|
||||
m1.def(new_noddy, "new_noddy");
|
||||
m1.def(new_simple, "new_simple");
|
||||
|
||||
// Expose f()
|
||||
if (PyDict_SetItemString(
|
||||
d, "f", boost::python::make_function(f)) < 0)
|
||||
return;
|
||||
m1.def(f, "f");
|
||||
|
||||
// Expose g()
|
||||
if (PyDict_SetItemString(
|
||||
d, "g", boost::python::make_function(g)) < 0)
|
||||
return;
|
||||
m1.def(g, "g");
|
||||
|
||||
// Expose complicated's get_n() member function. See newtest.py
|
||||
// for how it's used to build an extension class.
|
||||
if (PyDict_SetItemString(
|
||||
d, "get_n", boost::python::make_function(&complicated::get_n)) < 0)
|
||||
return;
|
||||
m1.def(&complicated::get_n, "get_n");
|
||||
|
||||
// Expose complicated::complicated(simple const&, int) as init1
|
||||
if (PyDict_SetItemString(
|
||||
d, "init1"
|
||||
, boost::python::make_constructor<
|
||||
complicated
|
||||
, boost::mpl::type_list<simple const&,int>
|
||||
, boost::python::object::value_holder_generator>()
|
||||
) < 0)
|
||||
return;
|
||||
|
||||
// Expose complicated::complicated(simple const&) as init2
|
||||
if (PyDict_SetItemString(
|
||||
d, "init2"
|
||||
, boost::python::make_constructor<
|
||||
complicated
|
||||
, boost::mpl::type_list<simple const&>
|
||||
, boost::python::object::value_holder_generator>()
|
||||
) < 0)
|
||||
return;
|
||||
boost::python::objects::function* init = boost::python::make_constructor<
|
||||
complicated
|
||||
, boost::mpl::type_list<simple const&,int>
|
||||
, boost::python::objects::value_holder_generator>();
|
||||
|
||||
boost::python::ref manager(init);
|
||||
|
||||
init->add_overload(
|
||||
boost::python::make_constructor<
|
||||
complicated
|
||||
, boost::mpl::type_list<simple const&>
|
||||
, boost::python::objects::value_holder_generator>());
|
||||
|
||||
m1.add(manager, "init1");
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
177
test/m2.cpp
177
test/m2.cpp
@@ -7,10 +7,6 @@
|
||||
// This module exercises the converters exposed in m1 at a low level
|
||||
// by exposing raw Python extension functions that use wrap<> and
|
||||
// unwrap<> objects.
|
||||
|
||||
// Seems to be neccessary to suppress an ICE with MSVC
|
||||
#include <boost/mpl/comparison/less.hpp>
|
||||
|
||||
#include <boost/python/convert.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include "simple_type.hpp"
|
||||
@@ -22,106 +18,40 @@ extern "C"
|
||||
{
|
||||
// Get a simple (by value) from the argument, and return the
|
||||
// string it holds.
|
||||
PyObject*
|
||||
unwrap_simple(PyObject* self, PyObject* args)
|
||||
PyObject* unwrap_simple(simple x)
|
||||
{
|
||||
PyObject* p;
|
||||
if (!PyArg_ParseTuple(args, "O", &p))
|
||||
return 0;
|
||||
|
||||
boost::python::unwrap<simple> in(p);
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
simple x = *in;
|
||||
|
||||
return PyString_FromString(x.s);
|
||||
}
|
||||
|
||||
// Likewise, but demands that its possible to get a non-const
|
||||
// reference to the simple.
|
||||
PyObject*
|
||||
unwrap_simple_ref(PyObject* self, PyObject* args)
|
||||
PyObject* unwrap_simple_ref(simple& x)
|
||||
{
|
||||
PyObject* p;
|
||||
if (!PyArg_ParseTuple(args, "O", &p))
|
||||
return 0;
|
||||
|
||||
unwrap<simple&> in(p);
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
simple& x = *in;
|
||||
|
||||
return PyString_FromString(x.s);
|
||||
}
|
||||
|
||||
// Likewise, with a const reference to the simple object.
|
||||
PyObject*
|
||||
unwrap_simple_const_ref(PyObject* self, PyObject* args)
|
||||
PyObject* unwrap_simple_const_ref(simple const& x)
|
||||
{
|
||||
PyObject* p;
|
||||
if (!PyArg_ParseTuple(args, "O", &p))
|
||||
return 0;
|
||||
|
||||
unwrap<simple const&> in(p);
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
simple const& x = *in;
|
||||
|
||||
return PyString_FromString(x.s);
|
||||
}
|
||||
|
||||
// Get an int (by value) from the argument, and convert it to a
|
||||
// Python Int.
|
||||
PyObject*
|
||||
unwrap_int(PyObject* self, PyObject* args)
|
||||
PyObject* unwrap_int(int x)
|
||||
{
|
||||
PyObject* p;
|
||||
if (!PyArg_ParseTuple(args, "O", &p))
|
||||
return 0;
|
||||
|
||||
unwrap<int> in(p);
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
int x = *in;
|
||||
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
// Get a non-const reference to an int from the argument
|
||||
PyObject*
|
||||
unwrap_int_ref(PyObject* self, PyObject* args)
|
||||
PyObject* unwrap_int_ref(int& x)
|
||||
{
|
||||
PyObject* p;
|
||||
if (!PyArg_ParseTuple(args, "O", &p))
|
||||
return 0;
|
||||
|
||||
unwrap<int&> in(p);
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
int& x = *in;
|
||||
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
// Get a const reference to an int from the argument.
|
||||
PyObject*
|
||||
unwrap_int_const_ref(PyObject* self, PyObject* args)
|
||||
PyObject* unwrap_int_const_ref(int const& x)
|
||||
{
|
||||
PyObject* p;
|
||||
if (!PyArg_ParseTuple(args, "O", &p))
|
||||
return 0;
|
||||
|
||||
unwrap<int&> in(p);
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
int const& x = *in;
|
||||
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
@@ -134,89 +64,28 @@ template <class T> struct xxxx;
|
||||
// rewrap<T> extracts a T from the argument, then converts the T back
|
||||
// to a PyObject* and returns it.
|
||||
template <class T>
|
||||
PyObject*
|
||||
rewrap(PyObject* self, PyObject* args, xxxx<T>* = 0)
|
||||
struct rewrap
|
||||
{
|
||||
PyObject* p;
|
||||
if (!PyArg_ParseTuple(args, "O", &p))
|
||||
return 0;
|
||||
|
||||
boost::python::unwrap<T> in(p);
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
boost::python::wrap<T> out;
|
||||
if (!out)
|
||||
return 0;
|
||||
|
||||
T x = *in;
|
||||
return out(x);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
//
|
||||
// Use rewrap<T> to test simple, simple&, simple const&, int,
|
||||
// int&, int const&
|
||||
//
|
||||
PyObject*
|
||||
wrap_simple(PyObject* self, PyObject* args)
|
||||
{
|
||||
return rewrap<simple>(self, args);
|
||||
}
|
||||
|
||||
PyObject*
|
||||
wrap_simple_ref(PyObject* self, PyObject* args)
|
||||
{
|
||||
return rewrap<simple&>(self, args);
|
||||
}
|
||||
|
||||
PyObject*
|
||||
wrap_simple_const_ref(PyObject* self, PyObject* args)
|
||||
{
|
||||
return rewrap<simple const&>(self, args);
|
||||
}
|
||||
|
||||
PyObject*
|
||||
wrap_int(PyObject* self, PyObject* args)
|
||||
{
|
||||
return rewrap<int>(self, args);
|
||||
}
|
||||
|
||||
PyObject*
|
||||
wrap_int_ref(PyObject* self, PyObject* args)
|
||||
{
|
||||
return rewrap<int&>(self, args);
|
||||
}
|
||||
|
||||
PyObject*
|
||||
wrap_int_const_ref(PyObject* self, PyObject* args)
|
||||
{
|
||||
return rewrap<int const&>(self, args);
|
||||
}
|
||||
}
|
||||
|
||||
PyMethodDef initial_methods[] =
|
||||
{
|
||||
{ "unwrap_int", unwrap_int, METH_VARARGS, 0 },
|
||||
{ "unwrap_int_ref", unwrap_int_ref, METH_VARARGS, 0 },
|
||||
{ "unwrap_int_const_ref", unwrap_int_const_ref, METH_VARARGS, 0 },
|
||||
{ "unwrap_simple", unwrap_simple, METH_VARARGS, 0 },
|
||||
{ "unwrap_simple_ref", unwrap_simple_ref, METH_VARARGS, 0 },
|
||||
{ "unwrap_simple_const_ref", unwrap_simple_const_ref, METH_VARARGS, 0 },
|
||||
|
||||
{ "wrap_int", wrap_int, METH_VARARGS, 0 },
|
||||
{ "wrap_int_ref", wrap_int_ref, METH_VARARGS, 0 },
|
||||
{ "wrap_int_const_ref", wrap_int_const_ref, METH_VARARGS, 0 },
|
||||
{ "wrap_simple", wrap_simple, METH_VARARGS, 0 },
|
||||
{ "wrap_simple_ref", wrap_simple_ref, METH_VARARGS, 0 },
|
||||
{ "wrap_simple_const_ref", wrap_simple_const_ref, METH_VARARGS, 0 },
|
||||
{ 0, 0, 0, 0 }
|
||||
static T f(T x) { return x; }
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(m2)
|
||||
{
|
||||
Py_InitModule(const_cast<char*>("m2"), initial_methods);
|
||||
boost::python::module m2("m2");
|
||||
|
||||
m2.def(unwrap_int, "unwrap_int");
|
||||
m2.def(unwrap_int_ref, "unwrap_int_ref");
|
||||
m2.def(unwrap_int_const_ref, "unwrap_int_const_ref");
|
||||
m2.def(unwrap_simple, "unwrap_simple");
|
||||
m2.def(unwrap_simple_ref, "unwrap_simple_ref");
|
||||
m2.def(unwrap_simple_const_ref, "unwrap_simple_const_ref");
|
||||
|
||||
m2.def(&rewrap<int>::f, "wrap_int");
|
||||
m2.def(&rewrap<int&>::f, "wrap_int_ref");
|
||||
m2.def(&rewrap<int const&>::f, "wrap_int_const_ref");
|
||||
m2.def(&rewrap<simple>::f, "wrap_simple");
|
||||
m2.def(&rewrap<simple&>::f, "wrap_simple_ref");
|
||||
m2.def(&rewrap<simple const&>::f, "wrap_simple_const_ref");
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
@@ -20,16 +20,14 @@
|
||||
>>> unwrap_int(5)
|
||||
5
|
||||
|
||||
Can't get a reference to a built-in integer object
|
||||
Can't get a non-const reference to a built-in integer object
|
||||
>>> try:
|
||||
... unwrap_int_ref(7)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
>>> try:
|
||||
... unwrap_int_const_ref(9)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
>>> unwrap_int_const_ref(9)
|
||||
9
|
||||
|
||||
>>> wrap_int(n)
|
||||
42
|
||||
@@ -63,16 +61,11 @@ Create an extension class which wraps "complicated" (init1 and get_n)
|
||||
are a complicated constructor and member function, respectively.
|
||||
|
||||
>>> C = xclass('C', (xinst,), {'__init__': init1, 'get_n': get_n})
|
||||
>>> c = C(s, 99)
|
||||
>>> c.get_n()
|
||||
>>> c1 = C(s, 99)
|
||||
>>> c1.get_n()
|
||||
99
|
||||
|
||||
Create another extension class which wraps "complicated" (init2 is a
|
||||
different constructor -- no overloading yet).
|
||||
|
||||
>>> D = xclass('D', (xinst,), {'__init__': init2, 'get_n': get_n})
|
||||
>>> d = D(s)
|
||||
>>> d.get_n()
|
||||
>>> c2 = C(s)
|
||||
>>> c2.get_n()
|
||||
0
|
||||
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user