// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "simple_type.hpp"
#include "complicated.hpp"
// Declare some straightforward extension types
extern "C" void
dealloc(PyObject* self)
{
PyObject_Del(self);
}
// Noddy is a type we got from one of the Python sample files
struct NoddyObject : PyObject
{
int x;
};
PyTypeObject NoddyType = {
PyVarObject_HEAD_INIT(NULL, 0)
const_cast("Noddy"),
sizeof(NoddyObject),
0,
dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
#if PYTHON_API_VERSION >= 1012
0 /* tp_del */
#endif
};
// Create a Noddy containing 42
PyObject* new_noddy()
{
NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType);
noddy->x = 42;
return (PyObject*)noddy;
}
// Simple is a wrapper around a struct simple, which just contains a char*
struct SimpleObject
{
PyObject_HEAD
simple x;
};
struct extract_simple_object
{
static simple& execute(SimpleObject& o) { return o.x; }
};
PyTypeObject SimpleType = {
PyVarObject_HEAD_INIT(NULL, 0)
const_cast("Simple"),
sizeof(SimpleObject),
0,
dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
#if PYTHON_API_VERSION >= 1012
0 /* tp_del */
#endif
};
// Create a Simple containing "hello, world"
PyObject* new_simple()
{
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
simple->x.s = const_cast("hello, world");
return (PyObject*)simple;
}
//
// Declare some wrappers/unwrappers to test the low-level conversion
// mechanism.
//
using boost::python::to_python_converter;
// Wrap a simple by copying it into a Simple
struct simple_to_python
: to_python_converter
//, boost::python::converter::wrap_pytype<&SimpleType>
{
static PyObject* convert(simple const& x)
{
SimpleObject* p = PyObject_New(SimpleObject, &SimpleType);
p->x = x;
return (PyObject*)p;
}
static PyTypeObject const *get_pytype(){return &SimpleType; }
};
struct int_from_noddy
{
static int& execute(NoddyObject& p)
{
return p.x;
}
};
//
// Some C++ functions to expose to Python
//
// Returns the length of s's held string
int f(simple const& s)
{
return strlen(s.s);
}
int f_mutable_ref(simple& s)
{
return strlen(s.s);
}
int f_mutable_ptr(simple* s)
{
return strlen(s->s);
}
int f_const_ptr(simple const* s)
{
return strlen(s->s);
}
int f2(SimpleObject const& s)
{
return strlen(s.x.s);
}
// A trivial passthru function for simple objects
simple const& g(simple const& x)
{
return x;
}
struct A
{
A() : x(0) {}
virtual ~A() {}
char const* name() { return "A"; }
int x;
};
struct B : A
{
B() : x(1) {}
static char const* name(B*) { return "B"; }
int x;
};
struct C : A
{
C() : x(2) {}
char const* name() { return "C"; }
virtual ~C() {}
int x;
};
struct D : B, C
{
D() : x(3) {}
char const* name() { return "D"; }
int x;
};
A take_a(A const& a) { return a; }
B take_b(B& b) { return b; }
C take_c(C* c) { return *c; }
D take_d(D* const& d) { return *d; }
D take_d_shared_ptr(boost::shared_ptr d) { return *d; }
boost::shared_ptr d_factory() { return boost::shared_ptr(new D); }
struct Unregistered {};
Unregistered make_unregistered(int) { return Unregistered(); }
Unregistered* make_unregistered2(int) { return new Unregistered; }
BOOST_PYTHON_MODULE(m1)
{
using namespace boost::python;
using boost::shared_ptr;
simple_to_python();
lvalue_from_pytype();
lvalue_from_pytype<
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters
extract_member
#else
extract_simple_object
#endif
, &SimpleType
>();
lvalue_from_pytype,&SimpleType>();
def("new_noddy", new_noddy);
def("new_simple", new_simple);
def("make_unregistered", make_unregistered);
def("make_unregistered2", make_unregistered2, return_value_policy());
// Expose f() in all its variations
def("f", f);
def("f_mutable_ref", f_mutable_ref);
def("f_mutable_ptr", f_mutable_ptr);
def("f_const_ptr", f_const_ptr);
def("f2", f2);
// Expose g()
def("g", g , return_value_policy()
);
def("take_a", take_a);
def("take_b", take_b);
def("take_c", take_c);
def("take_d", take_d);
def("take_d_shared_ptr", take_d_shared_ptr);
def("d_factory", d_factory);
class_ >("A")
.def("name", &A::name)
;
// sequence points don't ensure that "A" is constructed before "B"
// or "C" below if we make them part of the same chain
class_ >("B")
.def("name", &B::name)
;
class_ >("C")
.def("name", &C::name)
;
class_ >("D")
.def("name", &D::name)
;
class_("complicated",
init())
.def(init())
.def("get_n", &complicated::get_n)
;
}
#include "module_tail.cpp"