2
0
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:
Dave Abrahams
2002-01-06 14:39:34 +00:00
parent ab22e1b3a9
commit d598d0a4db
4 changed files with 61 additions and 240 deletions

View File

@@ -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);
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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
"""