2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-26 18:52:26 +00:00

initial checkin

[SVN r12075]
This commit is contained in:
Dave Abrahams
2001-12-16 18:18:58 +00:00
parent a4747eb10a
commit 946ed17ae1
17 changed files with 1527 additions and 0 deletions

18
src/converter/body.cpp Normal file
View File

@@ -0,0 +1,18 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/body.hpp>
namespace boost { namespace python { namespace converter {
// default implementation is a no-op. Most handles will not hold any
// data that needs to be managed. Unwrap objects which convert
// by-value are an exception. Fortunately, the concrete body subclass
// has that knowledge.
void body::destroy_handle(handle*) const
{
}
}}} // namespace boost::python::converter

35
src/converter/handle.cpp Normal file
View File

@@ -0,0 +1,35 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/handle.hpp>
#include <boost/python/converter/body.hpp>
namespace boost { namespace python { namespace converter {
bool handle::convertible() const
{
for (handle const* p = this; p != 0; p = p->m_next)
{
if (p->m_body == 0)
return false;
}
return true;
}
void handle::destroy()
{
// Recurse down the chain releasing from tail to head
if (m_next != 0)
m_next->destroy();
// Our body knows how to destroy us. If we never got a body,
// there's nothing to do.
if (m_body)
m_body->destroy_handle(this);
}
// void handle::dummy::nonnull() {}
}}} // namespace boost::python::converter

170
src/converter/registry.cpp Normal file
View File

@@ -0,0 +1,170 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
# include <boost/python/converter/unwrapper.hpp>
# include <boost/python/converter/wrapper.hpp>
# include <map>
# include <list>
# include <algorithm>
# include <stdexcept>
# ifdef BOOST_PYTHON_TRACE
# include <iostream>
# endif
namespace boost { namespace python { namespace converter {
namespace // <unnamed>
{
typedef std::map<type_id_t, registry::entry, type_id_before> registry_t;
registry_t& entries()
{
static registry_t registry;
return registry;
}
} // namespace <unnamed>
namespace registry
{
entry* find(type_id_t type)
{
return &entries()[type];
}
entry::entry()
: m_wrapper(0)
{
}
namespace // <unnamed>
{
// A UnaryFunction type which deletes its argument
struct delete_item
{
template <class T>
void operator()(T* x) const
{
delete x;
}
};
// A UnaryFunction type which returns true iff its argument is a
// unwrapper which can convert the given Python object.
struct convertible
{
convertible(PyObject* p)
: m_p(p)
{}
bool operator()(unwrapper_base* converter) const
{
return converter->convertible(m_p);
}
PyObject* m_p;
};
}
entry::~entry()
{
}
unwrapper_base* entry::unwrapper(PyObject* p) const
{
unwrappers::const_iterator q =
std::find_if(m_unwrappers.begin(), m_unwrappers.end(), convertible(p));
return q == m_unwrappers.end() ? 0 : *q;
}
wrapper_base* entry::wrapper() const
{
return m_wrapper;
}
entry::unwrappers::iterator entry::find(unwrapper_base const& x)
{
return std::find(m_unwrappers.begin(), m_unwrappers.end(), &x);
}
void entry::insert(unwrapper_base& x)
{
unwrappers::iterator p = this->find(x);
assert(p == m_unwrappers.end());
if (p != m_unwrappers.end())
{
throw std::runtime_error(
"trying to register unrapper which is already registered");
}
m_unwrappers.push_back(&x);
}
void entry::remove(unwrapper_base& x)
{
unwrappers::iterator p = find(x);
// Be sure we're not removing a converter which hasn't been
// registered.
assert(p != m_unwrappers.end());
if (p == m_unwrappers.end())
{
throw std::runtime_error(
"trying to unregister unwrapper which is not registered");
}
m_unwrappers.erase(p);
}
void entry::insert(wrapper_base& x)
{
assert(m_wrapper == 0); // we have a problem otherwise
if (m_wrapper != 0)
{
throw std::runtime_error(
"trying to register wrapper for a type which already has a registered wrapper");
}
m_wrapper = &x;
}
void entry::remove(wrapper_base& x)
{
assert(m_wrapper == &x);
if (m_wrapper != &x)
{
throw std::runtime_error(
"trying to unregister a wrapper which is not registered");
}
m_wrapper = 0;
}
void insert(wrapper_base& w)
{
# ifdef BOOST_PYTHON_TRACE
std::cout << "inserting wrapper for " << w.key() << std::endl;
# endif
find(w.key())->insert(w);
}
void insert(unwrapper_base& u)
{
# ifdef BOOST_PYTHON_TRACE
std::cout << "inserting unwrapper for " << u.key() << std::endl;
# endif
find(u.key())->insert(u);
}
void remove(wrapper_base& w)
{
find(w.key())->remove(w);
}
void remove(unwrapper_base& u)
{
find(u.key())->remove(u);
}
} // namespace registry
}}} // namespace boost::python::converter

67
src/converter/type_id.cpp Normal file
View File

@@ -0,0 +1,67 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/type_id.hpp>
#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT
# include <ostream>
#else
# include <ostream.h>
#endif
namespace boost { namespace python { namespace converter {
#if 1
bool type_id_before::operator()(type_id_t const& x, type_id_t const& y) const
{
return x < y;
}
BOOST_PYTHON_EXPORT std::ostream& operator<<(std::ostream& os, type_id_t const& x)
{
# ifdef BOOST_PYTHON_TYPE_ID_NAME
os << x.m_base_type;e
# else
os << x.m_base_type->name();
# endif
// VC6 mistakenly distinguishes typeid(X) from typeid(X const)
// from typeid(X&)... so the name is already correct. I have it
// from Jason Shirk that VC7.0 has the same bug but it will be
// fixed in 7.1
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
if (x.m_decoration & type_id_t::const_)
os << " const";
if (x.m_decoration & type_id_t::volatile_)
os << " volatile";
if (x.m_decoration & type_id_t::reference)
os << "&";
# endif
return os;
}
#else
bool type_id_before::operator()(type_id_t const& x, type_id_t const& y) const
{
for (;;)
{
if (*y == 0)
{
return 0;
}
else if (*x == 0)
{
return 1;
}
else if (*x != *y)
{
return *x < *y;
}
++x;
++y;
}
}
#endif
}}} // namespace boost::python::converter

35
src/converter/unwrap.cpp Normal file
View File

@@ -0,0 +1,35 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/unwrap.hpp>
namespace boost { namespace python { namespace converter {
namespace
{
struct pyobject_unwrapper : unwrapper_base
{
pyobject_unwrapper();
bool convertible(PyObject*) const;
};
pyobject_unwrapper static_unwrapper;
pyobject_unwrapper::pyobject_unwrapper()
: unwrapper_base(type_id<PyObject*>())
{
}
bool pyobject_unwrapper::convertible(PyObject*) const
{
return true;
}
}
BOOST_PYTHON_EXPORT unwrapper_base*
unwrap_more_<PyObject*>::m_unwrapper = &static_unwrapper;
}}} // namespace boost::python::converter

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/unwrapper.hpp>
#include <boost/python/converter/registry.hpp>
#include <boost/type_traits/same_traits.hpp>
namespace boost { namespace python { namespace converter {
unwrapper_base::unwrapper_base(type_id_t key)
: body(key)
{
registry::insert(*this);
}
unwrapper_base::~unwrapper_base()
{
registry::remove(*this);
}
}}} // namespace boost::python::converter

29
src/converter/wrapper.cpp Normal file
View File

@@ -0,0 +1,29 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/converter/registry.hpp>
#include <boost/python/converter/wrapper.hpp>
namespace boost { namespace python { namespace converter {
wrapper_base::wrapper_base(type_id_t type)
: body(type)
{
// static assertions for target<T>. These would go in a header,
// but Metrowerks only respects BOOST_STATIC_ASSERT if it is in an
// instantiated function
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#else
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
registry::insert(*this);
}
wrapper_base::~wrapper_base()
{
registry::remove(*this);
}
}}} // namespace boost::python::converter

82
src/gen_call.py Normal file
View File

@@ -0,0 +1,82 @@
# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears
# in all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
#
# This work was funded in part by Lawrence Berkeley National Labs
from gen_function import *
import string
header = '''// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//
// This work was funded in part by Lawrence Berkeley National Labs
//
// This file generated for %d-argument member functions and %d-argument free
// functions by gen_call.py
#ifndef CALL_DWA20011214_HPP
# define CALL_DWA20011214_HPP
# include <boost/python/detail/returning.hpp>
namespace boost { namespace python {
'''
_cv_qualifiers = ('', ' const', ' volatile', ' const volatile')
def gen_call(member_function_args, free_function_args = None):
if free_function_args is None:
free_function_args = member_function_args + 1
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)
{
return detail::returning<R>::call(f, args, keywords);
}
''', free_function_args)
+
'''// Member functions
'''
+ reduce(lambda x,y: x+y
, map(lambda cv:
gen_functions(
'''template <class R, class A0%(, class A%+%)>
PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords)
{
return detail::returning<R>::call(f, args, keywords);
}
'''
, member_function_args, cv)
, _cv_qualifiers))
+
'''
}} // namespace boost::python
#endif // CALL_DWA20011214_HPP
''')
if __name__ == '__main__':
import sys
if len(sys.argv) == 1:
member_function_args = 5
free_function_args = 6
else:
member_function_args = int(sys.argv[1])
if len(sys.argv) > 2:
free_function_args = int(sys.argv[2])
else:
free_function_args = member_function_args
print gen_call(member_function_args, free_function_args)

191
src/gen_returning.py Normal file
View File

@@ -0,0 +1,191 @@
# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears
# in all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
#
# This work was funded in part by Lawrence Berkeley National Labs
from gen_function import *
import string
header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// This work was funded in part by Lawrence Berkeley National Labs
//
// This file generated for %d-argument member functions and %d-argument free
// functions by gen_returning.py
'''
body_sections = (
'''
#ifndef RETURNING_DWA20011201_HPP
# define RETURNING_DWA20011201_HPP
//# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/config.hpp>
# include <boost/python/convert.hpp>
# include <boost/python/detail/none.hpp>
namespace boost { namespace python { namespace detail {
// Calling C++ from Python
template <class R>
struct returning
{
''',
'''
''',
''' // Free functions
''',
'''};
template <>
struct returning<void>
{
typedef void R;
''',
'''
''',
'''
// Free functions
''',
'''};
}}} // namespace boost::python::detail
#endif // RETURNING_DWA20011201_HPP
''')
#'
member_function = ''' template <class A0%(, class A%+%)>
static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args, PyObject* /* keywords */ )
{
// check that each of the arguments is convertible
unwrap<A0%1&> c0(PyTuple_GET_ITEM(args, 0));
%( unwrap_more<A%+> c%+(PyTuple_GET_ITEM(args, %+), c%n);
%)
%[r%: // find the result converter
wrap_more<R> r(c%n);
%] if (!c0) return 0;
%[r%:return r( %]((*c0).*pmf)(%(*c%+%:, %))%[r%: )%];%[v%:
return detail::none();%]
};
'''
free_function = '''%{ template <%(class A%n%:, %)>
%} static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject*%{ args%}, PyObject* /* keywords */ )
{%{
// check that each of the arguments is convertible
%}%( unwrap%{_more%}<A%n> c%n(PyTuple_GET_ITEM(args, %n)%{, c%-%});
%)%[r%:
// find the result converter
wrap%{_more%}<R> r%{(c%-)%};%]%{
if (!c0) return 0;%}
%[r%:return r( %](*pf)(%(*c%n%:, %))%[r%: )%];%[v%:
return detail::none();%]
};
'''
def _returns_value(key, n, args, value):
if key == 'r':
return value
# pass the value through gen_function again for recursive expansion
# return apply(gen_function, (value, n) + args
# , {'fill': _returns_value})
else:
assert key == 'v'
return ''
def _returns_void(key, n, args, value):
if key == 'v':
return value
else:
assert key == 'r'
# return the empty string, ignoring the value
return ''
_cv_qualifiers = ('', ' const', ' volatile', ' const volatile')
_prefix = {
# ' const': '''
# // missing cv-qualified -> cv-unqualified member pointer conversions
# # if defined(__MWERKS__) && __MWERKS__ <=0x2406 || defined(BOOST_MSVC) && BOOST_MSVC <= 1200 || defined(__BORLANDC__)
# ''',
' const volatile': '''
// missing const volatile type traits
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
'''};
def gen_returning(member_function_args, free_function_args = None):
if free_function_args is None:
free_function_args = member_function_args + 1
return_none = ''';
return detail::none();'''
return (header % (member_function_args, free_function_args)
+ body_sections[0]
#
# functions returning results
#
+ reduce(lambda x,y: x+y
, map(lambda cv:
_prefix.get(cv,'')
+ gen_functions(member_function,
member_function_args, cv,
fill = _returns_value) + '\n'
, _cv_qualifiers))
+ '''# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
'''
## endif // missing cv-qualified -> cv-unqualified member pointer conversions
#'''
# free functions
+ gen_functions(free_function, free_function_args, fill = _returns_value)
+ body_sections[3]
#
# functions returning void
#
+ reduce(lambda x,y: x+y
, map(lambda cv:
_prefix.get(cv,'')
+ gen_functions(member_function,
member_function_args, cv, fill =
_returns_void) + '\n'
, _cv_qualifiers))
+ '''# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
'''
## endif // missing cv-qualified -> cv-unqualified member pointer conversions
#'''
# free functions
+ gen_functions(free_function, free_function_args, fill = _returns_void)
+ body_sections[6]
)
if __name__ == '__main__':
import sys
if len(sys.argv) == 1:
member_function_args = 5
free_function_args = 6
else:
member_function_args = int(sys.argv[1])
if len(sys.argv) > 2:
free_function_args = int(sys.argv[2])
else:
free_function_args = member_function_args
print gen_returning(member_function_args, free_function_args)

117
src/object/class.cpp Normal file
View File

@@ -0,0 +1,117 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/export.hpp>
#include <boost/python/detail/wrap_python.hpp>
#include <boost/python/object/class.hpp>
namespace boost { namespace python { namespace object {
holder_base::holder_base(converter::type_id_t id)
: m_type(id)
, m_next(0)
{
}
holder_base::~holder_base()
{
}
BOOST_PYTHON_EXPORT PyTypeObject class_metatype = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"Boost.Python.class",
PyType_Type.tp_basicsize,
0,
0, /* 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 */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* 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 */
&PyType_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0,
// PyType_GenericNew /* tp_new */
};
BOOST_PYTHON_EXPORT PyTypeObject class_type = {
PyObject_HEAD_INIT(&class_metatype)
0,
"Boost.Python.instance",
sizeof(instance),
0,
0, /* 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 */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* 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 */
&PyBaseObject_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew
};
void holder_base::install(PyObject* self)
{
assert(self->ob_type->ob_type == &class_metatype);
m_next = ((instance*)self)->objects;
((instance*)self)->objects = this;
}
}}} // namespace boost::python::object

95
src/object/function.cpp Normal file
View File

@@ -0,0 +1,95 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/object/function.hpp>
namespace boost { namespace python { namespace object {
function::function(py_function implementation)
: m_fn(implementation)
{
PyObject* p = this;
PyObject_INIT(p, &function_type);
}
function::~function()
{
}
PyObject* function::call(PyObject* args, PyObject* keywords) const
{
return m_fn(args, keywords);
}
extern "C"
{
// Stolen from Python's funcobject.c
static PyObject *
function_descr_get(PyObject *func, PyObject *obj, PyObject *type)
{
if (obj == Py_None)
obj = NULL;
return PyMethod_New(func, obj, type);
}
static void
function_dealloc(PyObject* p)
{
delete static_cast<function*>(p);
}
static PyObject *
function_call(PyObject *func, PyObject *arg, PyObject *kw)
{
return static_cast<function*>(func)->call(arg, kw);
}
}
PyTypeObject function_type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"Boost.Python.function",
sizeof(function),
0,
(destructor)function_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, //(reprfunc)func_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
function_call, /* tp_call */
0, /* tp_str */
0, // PyObject_GenericGetAttr, /* tp_getattro */
0, // PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */
0, /* tp_doc */
0, // (traverseproc)func_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, //offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, // func_memberlist, /* tp_members */
0, //func_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
function_descr_get, /* tp_descr_get */
0, /* tp_descr_set */
0, //offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0,
0 /* tp_new */
};
}}} // namespace boost::python::object

39
test/complicated.hpp Normal file
View File

@@ -0,0 +1,39 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef COMPLICATED_DWA20011215_HPP
# define COMPLICATED_DWA20011215_HPP
# include <iostream>
# include "simple_type.hpp"
struct complicated
{
complicated(simple const&, int = 0);
~complicated();
int get_n() const;
char* s;
int n;
};
inline complicated::complicated(simple const&s, int n)
: s(s.s), n(n)
{
std::cout << "constructing complicated: " << this->s << ", " << n << std::endl;
}
inline complicated::~complicated()
{
std::cout << "destroying complicated: " << this->s << ", " << n << std::endl;
}
inline int complicated::get_n() const
{
return n;
}
#endif // COMPLICATED_DWA20011215_HPP

286
test/m1.cpp Normal file
View File

@@ -0,0 +1,286 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "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/module.hpp>
#include <boost/python/convert.hpp>
#include <boost/python/object/value_holder.hpp>
#include <boost/python/object/class.hpp>
#include <boost/python/make_function.hpp>
#include <boost/mpl/type_list.hpp>
#include <string.h>
extern "C" void
dealloc(PyObject* self)
{
PyObject_Del(self);
}
struct NoddyObject : PyObject
{
int x;
};
PyTypeObject NoddyType = {
PyObject_HEAD_INIT(NULL)
0,
"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 */
};
struct SimpleObject : PyObject
{
simple x;
};
PyTypeObject SimpleType = {
PyObject_HEAD_INIT(NULL)
0,
"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 */
};
extern "C" PyObject*
new_noddy(PyObject* self, PyObject* args)
{
NoddyObject* noddy;
if (!PyArg_ParseTuple(args,":new_noddy"))
return NULL;
noddy = PyObject_New(NoddyObject, &NoddyType);
noddy->x = 42;
return (PyObject*)noddy;
}
extern "C" PyObject*
new_simple(PyObject* self, PyObject* args)
{
SimpleObject* simple;
if (!PyArg_ParseTuple(args,":new_simple"))
return NULL;
simple = PyObject_New(SimpleObject, &SimpleType);
simple->x.s = "hello, world";
return (PyObject*)simple;
}
static PyMethodDef methods[] = {
{ "new_noddy", new_noddy, METH_VARARGS },
{ "new_simple", new_simple, METH_VARARGS },
{NULL, NULL}
};
struct int_wrapper
: boost::python::converter::wrapper<int const&>
{
PyObject* convert(int const& x) const
{
return PyInt_FromLong(x);
}
};
struct simple_wrapper
: boost::python::converter::wrapper<simple const&>
{
PyObject* convert(simple const& x) const
{
SimpleObject* p = PyObject_New(SimpleObject, &SimpleType);
p->x = x;
return p;
}
};
struct simple_ref_wrapper
: boost::python::converter::wrapper<simple&>
{
PyObject* convert(simple& x) const
{
SimpleObject* p = PyObject_New(SimpleObject, &SimpleType);
p->x = x;
return p;
}
};
struct native_int_unwrapper
: boost::python::converter::unwrapper<int>
{
bool convertible(PyObject* p) const
{
return PyInt_Check(p);
}
int convert(PyObject* p, void*&) const
{
return PyInt_AsLong(p);
}
};
struct noddy_int_unwrapper
: boost::python::converter::unwrapper<int>
{
bool convertible(PyObject* p) const
{
return p->ob_type == &NoddyType;
}
int convert(PyObject* p, void*&) const
{
return static_cast<NoddyObject*>(p)->x;
}
};
struct noddy_int_ref_unwrapper
: boost::python::converter::unwrapper<int&>
{
bool convertible(PyObject* p) const
{
return p->ob_type == &NoddyType;
}
int& convert(PyObject* p, void*&) const
{
return static_cast<NoddyObject*>(p)->x;
}
};
struct simple_ref_unwrapper
: boost::python::converter::unwrapper<simple&>
{
bool convertible(PyObject* p) const
{
return p->ob_type == &SimpleType;
}
simple& convert(PyObject* p, void*&) const
{
return static_cast<SimpleObject*>(p)->x;
}
};
struct simple_const_ref_unwrapper
: boost::python::converter::unwrapper<simple const&>
{
bool convertible(PyObject* p) const
{
return p->ob_type == &SimpleType;
}
simple const& convert(PyObject* p, void*&) const
{
return static_cast<SimpleObject*>(p)->x;
}
};
int f(simple const& s)
{
return strlen(s.s);
}
simple const& g(simple const& x)
{
return x;
}
BOOST_PYTHON_MODULE_INIT(m1)
{
PyObject* m1 = Py_InitModule(const_cast<char*>("m1"), methods);
static int_wrapper wrap_int;
static simple_wrapper wrap_simple;
static native_int_unwrapper unwrap_int1;
static noddy_int_unwrapper unwrap_int2;
static noddy_int_ref_unwrapper unwrap_int3;
static simple_ref_unwrapper unwrap_simple;
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// These compilers will need additional converters
static simple_const_ref_unwrapper unwrap_simple_const_ref;
static simple_ref_wrapper wrap_simple_ref;
#endif
// Not quite right
if (PyType_Ready(&boost::python::object::class_metatype) < 0)
return;
if (PyType_Ready(&boost::python::object::class_type) < 0)
return;
Py_INCREF(&boost::python::object::class_type);
PyObject* d = PyModule_GetDict(m1);
if (d == NULL)
return;
if (PyDict_SetItemString(
d, "xclass", (PyObject *)&boost::python::object::class_metatype) < 0)
return;
if (PyDict_SetItemString(
d, "xinst", (PyObject *)&boost::python::object::class_type) < 0)
return;
if (PyDict_SetItemString(
d, "f", boost::python::make_function(f)) < 0)
return;
if (PyDict_SetItemString(
d, "g", boost::python::make_function(g)) < 0)
return;
if (PyDict_SetItemString(
d, "get_n", boost::python::make_function(&complicated::get_n)) < 0)
return;
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;
if (PyDict_SetItemString(
d, "init2"
, boost::python::make_constructor<
complicated
, boost::mpl::type_list<simple const&>
, boost::python::object::value_holder_generator>()
) < 0)
return;
}
#include "module_tail.cpp"

197
test/m2.cpp Normal file
View File

@@ -0,0 +1,197 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/convert.hpp>
#include <boost/python/module.hpp>
#include "simple_type.hpp"
using boost::python::wrap;
using boost::python::unwrap;
extern "C" {
PyObject*
unwrap_simple(PyObject* self, PyObject* args)
{
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);
};
PyObject*
unwrap_simple_ref(PyObject* self, PyObject* args)
{
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);
};
PyObject*
unwrap_simple_const_ref(PyObject* self, PyObject* args)
{
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);
};
PyObject*
unwrap_int(PyObject* self, PyObject* args)
{
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);
};
PyObject*
unwrap_int_ref(PyObject* self, PyObject* args)
{
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);
};
PyObject*
unwrap_int_const_ref(PyObject* self, PyObject* args)
{
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);
};
// -------------------
}
template <class T> struct xxxx;
template <class T>
PyObject*
rewrap(PyObject* self, PyObject* args, xxxx<T>* = 0)
{
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"
{
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 }
};
BOOST_PYTHON_MODULE_INIT(m2)
{
Py_InitModule(const_cast<char*>("m2"), initial_methods);
}
#include "module_tail.cpp"

39
test/module_tail.cpp Normal file
View File

@@ -0,0 +1,39 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#if defined(_WIN32)
# ifdef __MWERKS__
# pragma ANSI_strict off
# endif
# include <windows.h>
# ifdef __MWERKS__
# pragma ANSI_strict reset
# endif
extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved );
# ifdef BOOST_MSVC
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
{
throw;
}
# endif
BOOL WINAPI DllMain(
HINSTANCE, //hDllInst
DWORD fdwReason,
LPVOID // lpvReserved
)
{
# ifdef BOOST_MSVC
_set_se_translator(structured_exception_translator);
# endif
(void)fdwReason; // warning suppression.
return 1;
}
#endif // _WIN32

90
test/newtest.py Normal file
View File

@@ -0,0 +1,90 @@
"""
>>> from m1 import *
>>> from m2 import *
>>> n = new_noddy()
>>> s = new_simple()
>>> unwrap_int(n)
42
>>> unwrap_int_ref(n)
42
>>> unwrap_int_const_ref(n)
42
>>> unwrap_simple(s)
'hello, world'
>>> unwrap_simple_ref(s)
'hello, world'
>>> unwrap_simple_const_ref(s)
'hello, world'
>>> unwrap_int(5)
5
Can't get a 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'
>>> wrap_int(n)
42
try: wrap_int_ref(n)
... except: pass
... else: print 'no exception'
>>> wrap_int_const_ref(n)
42
>>> unwrap_simple_ref(wrap_simple(s))
'hello, world'
>>> unwrap_simple_ref(wrap_simple_ref(s))
'hello, world'
>>> unwrap_simple_ref(wrap_simple_const_ref(s))
'hello, world'
>>> f(s)
12
>>> unwrap_simple(g(s))
'hello, world'
>>> f(g(s))
12
>>> C = xclass('C', (xinst,), {'__init__': init1, 'get_n': get_n})
>>> c = C(s, 99)
>>> c.get_n()
99
>>> D = xclass('D', (xinst,), {'__init__': init2, 'get_n': get_n})
>>> d = D(s)
>>> d.get_n()
0
"""
def run(args = None):
import m1,m2
import string
import re
import sys
if args is not None:
sys.argv = args
import sys
import doctest
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

14
test/simple_type.hpp Normal file
View File

@@ -0,0 +1,14 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef SIMPLE_TYPE_DWA2001128_HPP
# define SIMPLE_TYPE_DWA2001128_HPP
struct simple
{
char* s;
};
#endif // SIMPLE_TYPE_DWA2001128_HPP