2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-23 05:42:30 +00:00

This commit was manufactured by cvs2svn to create branch 'mpl_v2'.

[SVN r13495]
This commit is contained in:
nobody
2002-04-15 16:30:54 +00:00
parent 8eab74ea81
commit fd16f736f3
235 changed files with 0 additions and 33389 deletions

View File

@@ -1,106 +0,0 @@
subproject libs/python/test ;
# bring in the rules for python
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
local PYTHON_V1_PROPERTIES = $(PYTHON_PROPERTIES) ;
local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ;
#
rule bpl-test ( name ? : files * )
{
files ?= $(name).py $(name).cpp ;
local modules ;
local py ;
for local f in $(files)
{
if $(f:S) = .py
{
if $(py)
{
EXIT too many python drivers specified: "$(py)" "$(f)" ;
}
py = $(f) ;
}
}
name ?= $(py:S=) ;
for local f in $(files)
{
if $(f:S) != .py
{
local m = $(f:S=) ;
if $(m) = $(py:S=)
{
m = $(name) ;
if $(m) = $(py:S=)
{
m = $(m)_ext ;
}
}
extension $(m) : $(f) <dll>../bpl ;
modules += $(m) ;
}
}
boost-python-runtest $(name) : $(py) <pyd>$(modules) ;
}
bpl-test try : newtest.py m1.cpp m2.cpp ;
bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ;
bpl-test test_pointer_adoption ;
bpl-test callbacks ;
bpl-test virtual_functions ;
bpl-test back_reference ;
bpl-test implicit ;
bpl-test data_members ;
bpl-test bienstman1 ;
bpl-test bienstman2 ;
bpl-test bienstman3 ;
if $(TEST_BIENSTMAN_NON_BUGS)
{
bpl-test bienstman4 ;
bpl-test bienstman5 ;
}
# --- unit tests of library components ---
unit-test indirect_traits_test
: indirect_traits_test.cpp : <include>$(BOOST_ROOT) ;
unit-test destroy_test
: destroy_test.cpp : <include>$(BOOST_ROOT) ;
unit-test pointer_type_id_test
: pointer_type_id_test.cpp : <include>$(BOOST_ROOT) ;
unit-test member_function_cast
: member_function_cast.cpp : <include>$(BOOST_ROOT) ;
unit-test bases
: bases.cpp : <include>$(BOOST_ROOT) ;
unit-test if_else
: if_else.cpp : <include>$(BOOST_ROOT) ;
unit-test pointee
: pointee.cpp : <include>$(BOOST_ROOT) ;
unit-test select_holder
: select_holder.cpp
: <include>$(BOOST_ROOT) <define>BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES)
;
unit-test select_from_python_test
: select_from_python_test.cpp
../src/converter/type_id.cpp
# ../src/converter/registry.cpp # MWerks needs this for some reason
: <include>$(BOOST_ROOT) <define>BOOST_PYTHON_STATIC_LIB
$(PYTHON_V1_PROPERTIES)
;

View File

@@ -1,99 +0,0 @@
// Copyright David Abrahams 2002. 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/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/has_back_reference.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>
#include <memory>
#include <cassert>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
// This test shows that a class can be wrapped "as itself" but also
// acquire a back-reference iff has_back_reference<> is appropriately
// specialized.
using namespace boost::python;
struct X
{
explicit X(int x) : x(x), magic(7654321) { ++counter; }
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int x) { assert(magic == 7654321); this->x = x; }
int value() const { assert(magic == 7654321); return x; }
static int count() { return counter; }
private:
void operator=(X const&);
private:
int x;
long magic;
static int counter;
};
int X::counter;
struct Y : X
{
Y(PyObject* self, int x) : X(x) {};
Y(PyObject* self, Y const& rhs) : X(rhs), self(self) {};
private:
Y(Y const&);
PyObject* self;
};
struct Z : X
{
Z(PyObject* self, int x) : X(x) {};
Z(PyObject* self, Z const& rhs) : X(rhs), self(self) {};
private:
Z(Z const&);
PyObject* self;
};
Y const& copy_Y(Y const& y) { return y; }
Z const& copy_Z(Z const& z) { return z; }
namespace boost { namespace python
{
template <>
struct has_back_reference<Y>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <>
struct has_back_reference<Z>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
}}
BOOST_PYTHON_MODULE_INIT(back_reference_ext)
{
module("back_reference_ext")
.def("copy_Y", copy_Y, return_value_policy<copy_const_reference>())
.def("copy_Z", copy_Z, return_value_policy<copy_const_reference>())
.def("x_instances", &X::count)
.add(
class_<Y>("Y")
.def_init(args<int>())
.def("value", &Y::value)
.def("set", &Y::set)
)
.add(
class_<Z,std::auto_ptr<Z> >("Z")
.def_init(args<int>())
.def("value", &Z::value)
.def("set", &Z::set)
)
;
}
#include "module_tail.cpp"

View File

@@ -1,26 +0,0 @@
'''
>>> from back_reference_ext import *
>>> y = Y(3)
>>> z = Z(4)
>>> x_instances()
2
>>> y2 = copy_Y(y)
>>> x_instances()
3
>>> z2 = copy_Z(z)
>>> x_instances()
4
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

View File

@@ -1,41 +0,0 @@
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/return_value_policy.hpp>
struct A {};
struct V
{
virtual void f() = 0;
const A* inside() {return &a;}
A a;
};
const A* outside(const V& v) {return &v.a;}
BOOST_PYTHON_MODULE_INIT(bienstman1_ext)
{
using namespace boost::python;
using boost::shared_ptr;
using boost::python::return_value_policy;
using boost::python::reference_existing_object;
module m("bienstman1_ext");
m
.add(class_<A, shared_ptr<A> >("A"))
.add(
class_<V, boost::noncopyable>("V")
.def("inside", &V::inside,
return_value_policy<reference_existing_object>())
.def("outside", outside,
return_value_policy<reference_existing_object>())
)
;
}

View File

@@ -1,29 +0,0 @@
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
struct C {};
struct D {};
struct E
{
const D fe (const C&) {return D();}
const D fe2(const C&, const C&) {return D();}
};
BOOST_PYTHON_MODULE_INIT(bienstman2_ext)
{
using namespace boost::python;
module m("bienstman2_ext");
m
.add(class_<C>("C"))
.add(class_<D>("D"))
.add(
class_<E>("E")
.def("fe", &E::fe) // this compiles.
.def("fe2", &E::fe2) // this doesn't.
)
;
}

View File

@@ -1,33 +0,0 @@
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/mpl/type_list.hpp>
struct V
{
virtual void f() = 0;
};
struct B
{
B(const V&) {}
};
BOOST_PYTHON_MODULE_INIT(bienstman3_ext)
{
using namespace boost::python;
using boost::mpl::type_list;
module m("bienstman3_ext");
m
.add(
class_<V, boost::noncopyable>("V")
)
.add(
class_<B>("B")
.def_init(type_list<const V&>())
)
;
}

View File

@@ -1,15 +0,0 @@
'''
>>> from bienstman3_ext import *
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

View File

@@ -1,40 +0,0 @@
// Copyright David Abrahams 2002. 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/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/implicit.hpp>
#include <boost/mpl/type_list.hpp>
struct Type1 {};
struct Term {Term(Type1 const&) {} };
struct Expression {void add(Term const&) {} };
BOOST_PYTHON_MODULE_INIT(bienstman4_ext)
{
using namespace boost::python;
using boost::mpl::type_list;
implicitly_convertible<Type1,Term>();
module("bienstman4_ext")
.add(class_<Expression>("Expression")
.def_init()
.def("add", &Expression::add))
.add(class_<Type1>("T1")
.def_init())
.add(class_<Term>("Term")
.def_init(type_list<Type1&>()))
;
Type1 t1;
Expression e;
e.add(t1);
}

View File

@@ -1,29 +0,0 @@
// Copyright David Abrahams 2002. 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/module.hpp>
#include <boost/python/class.hpp>
#include <boost/mpl/type_list.hpp>
#include <complex>
struct M {M(const std::complex<double>&) {} };
BOOST_PYTHON_MODULE_INIT(bienstman5_ext)
{
using namespace boost::python;
using boost::mpl::type_list;
module m("bienstman5_ext");
m
.add(class_<M>("M")
.def_init(args<std::complex<double> const&>()))
;
}

View File

@@ -1,128 +0,0 @@
// Copyright David Abrahams 2002. 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/module.hpp>
//#include <boost/python/returning.hpp>
#include <boost/python/class.hpp>
#include <boost/ref.hpp>
#include <boost/python/ptr.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/call.hpp>
using namespace boost::python;
int apply_int_int(PyObject* f, int x)
{
return call<int>(f, x);
}
void apply_void_int(PyObject* f, int x)
{
call<void>(f, x);
}
struct X
{
explicit X(int x) : x(x), magic(7654321) { ++counter; }
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int x) { assert(magic == 7654321); this->x = x; }
int value() const { assert(magic == 7654321); return x; }
static int count() { return counter; }
private:
void operator=(X const&);
private:
int x;
long magic;
static int counter;
};
X apply_X_X(PyObject* f, X x)
{
return call<X>(f, x);
}
void apply_void_X_ref(PyObject* f, X& x)
{
call<void>(f, boost::ref(x));
}
X& apply_X_ref_pyobject(PyObject* f, PyObject* obj)
{
return call<X&>(f, obj);
}
X* apply_X_ptr_pyobject(PyObject* f, PyObject* obj)
{
return call<X*>(f, obj);
}
void apply_void_X_cref(PyObject* f, X const& x)
{
call<void>(f, boost::cref(x));
}
void apply_void_X_ptr(PyObject* f, X* x)
{
call<void>(f, ptr(x));
}
void apply_void_X_deep_ptr(PyObject* f, X* x)
{
call<void>(f, x);
}
char const* apply_cstring_cstring(PyObject* f, char const* s)
{
return call<char const*>(f, s);
}
char const* apply_cstring_pyobject(PyObject* f, PyObject* s)
{
return call<char const*>(f, s);
}
char apply_char_char(PyObject* f, char c)
{
return call<char>(f, c);
}
int X::counter;
BOOST_PYTHON_MODULE_INIT(callbacks_ext)
{
boost::python::module("callbacks_ext")
.def("apply_int_int", apply_int_int)
.def("apply_void_int", apply_void_int)
.def("apply_X_X", apply_X_X)
.def("apply_void_X_ref", apply_void_X_ref)
.def("apply_void_X_cref", apply_void_X_cref)
.def("apply_void_X_ptr", apply_void_X_ptr)
.def("apply_void_X_deep_ptr", apply_void_X_deep_ptr)
.def("apply_X_ptr_pyobject", apply_X_ptr_pyobject
, return_value_policy<reference_existing_object>())
.def("apply_X_ref_pyobject", apply_X_ref_pyobject
, return_value_policy<reference_existing_object>())
.def("apply_cstring_cstring", apply_cstring_cstring)
.def("apply_cstring_pyobject", apply_cstring_pyobject)
.def("apply_char_char", apply_char_char)
.add(
class_<X>("X")
.def_init(args<int>())
.def_init(args<X const&>())
.def("value", &X::value)
.def("set", &X::set)
)
.def("x_count", &X::count)
;
}
#include "module_tail.cpp"

View File

@@ -1,122 +0,0 @@
'''
>>> from callbacks_ext import *
>>> def double(x):
... return x + x
...
>>> apply_int_int(double, 42)
84
>>> apply_void_int(double, 42)
>>> def identity(x):
... return x
>>> x = apply_X_X(identity, X(42))
>>> x.value()
42
>>> x_count()
1
>>> del x
>>> x_count()
0
>>> def increment(x):
... x.set(x.value() + 1)
...
>>> x = X(42)
>>> apply_void_X_ref(increment, x)
>>> x.value()
43
>>> apply_void_X_cref(increment, x)
>>> x.value() # const-ness is not respected, sorry!
44
>>> last_x = 1
>>> def decrement(x):
... global last_x
... last_x = x
... if x is not None:
... x.set(x.value() - 1)
>>> apply_void_X_ptr(decrement, x)
>>> x.value()
43
>>> last_x.value()
43
>>> increment(last_x)
>>> x.value()
44
>>> last_x.value()
44
>>> apply_void_X_ptr(decrement, None)
>>> assert last_x is None
>>> x.value()
44
>>> last_x = 1
>>> apply_void_X_deep_ptr(decrement, None)
>>> assert last_x is None
>>> x.value()
44
>>> apply_void_X_deep_ptr(decrement, x)
>>> x.value()
44
>>> last_x.value()
43
>>> y = apply_X_ref_pyobject(identity, x)
>>> assert y.value() == x.value()
>>> increment(x)
>>> assert y.value() == x.value()
>>> y = apply_X_ptr_pyobject(identity, x)
>>> assert y.value() == x.value()
>>> increment(x)
>>> assert y.value() == x.value()
>>> y = apply_X_ptr_pyobject(identity, None)
>>> y
>>> def new_x(ignored):
... return X(666)
...
>>> try: apply_X_ref_pyobject(new_x, 1)
... except ReferenceError: pass
... else: print 'no error'
>>> try: apply_X_ptr_pyobject(new_x, 1)
... except ReferenceError: pass
... else: print 'no error'
>>> try: apply_cstring_cstring(identity, 'hello')
... except ReferenceError: pass
... else: print 'no error'
>>> apply_char_char(identity, 'x')
'x'
>>> apply_cstring_pyobject(identity, 'hello')
'hello'
>>> apply_cstring_pyobject(identity, None)
>>> apply_char_char(identity, 'x')
'x'
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +0,0 @@
// Copyright David Abrahams 2002. 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/class.hpp>
#include <boost/python/module.hpp>
#include "test_class.hpp"
using namespace boost::python;
typedef test_class<> X;
typedef test_class<1> Y;
BOOST_PYTHON_MODULE_INIT(data_members_ext)
{
module("data_members_ext")
.add(
class_<X>("X")
.def_init(args<int>())
.def("value", &X::value)
.def("set", &X::set)
.def_readonly("x", &X::x)
)
.add(
class_<Y>("Y")
.def_init(args<int>())
.def("value", &Y::value)
.def("set", &Y::set)
.def_readwrite("x", &Y::x)
)
;
}
#include "module_tail.cpp"

View File

@@ -1,29 +0,0 @@
'''
>>> from data_members_ext import *
>>> x = X(42)
>>> x.x
42
>>> try: x.x = 77
... except AttributeError: pass
... else: print 'no error'
>>> y = Y(69)
>>> y.x
69
>>> y.x = 77
>>> y.x
77
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

View File

@@ -1,81 +0,0 @@
#include <boost/python/detail/destroy.hpp>
#include <cassert>
struct bar;
namespace boost
{
// lie to the library about bar so we can show that it's destructor is optimized away.
template <>
struct has_trivial_destructor<bar>
{
BOOST_STATIC_CONSTANT(bool, value=true);
};
}
int count;
int marks[] = {
-1
, -1, -1
, -1, -1, -1, -1
, -1
};
int* kills = marks;
struct foo
{
foo() : n(count++) {}
~foo()
{
*kills++ = n;
}
int n;
};
struct bar : foo {};
void assert_destructions(int n)
{
for (int i = 0; i < n; ++i)
assert(marks[i] == i);
assert(marks[n] == -1);
}
int main()
{
assert_destructions(0);
typedef int a[2];
foo* f1 = new foo;
boost::python::detail::destroy_reference<foo const volatile&>(f1);
assert_destructions(1);
foo* f2 = new foo[2];
typedef foo x[2];
boost::python::detail::destroy_reference<x const&>(f2);
assert_destructions(3);
typedef foo y[2][2];
x* f3 = new y;
boost::python::detail::destroy_reference<y&>(f3);
assert_destructions(7);
bar* b1 = new bar;
boost::python::detail::destroy_reference<bar&>(b1);
assert_destructions(7);
bar* b2 = new bar[2];
typedef bar xb[2];
boost::python::detail::destroy_reference<xb&>(b2);
assert_destructions(7);
typedef bar yb[2][2];
xb* b3 = new yb;
boost::python::detail::destroy_reference<yb&>(b3);
assert_destructions(7);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +0,0 @@
// Copyright David Abrahams 2002. 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/static_assert.hpp>
#include <boost/python/detail/if_else.hpp>
#include <boost/type_traits/same_traits.hpp>
typedef char c1;
typedef char c2[2];
typedef char c3[3];
typedef char c4[4];
template <unsigned size>
struct choose
{
#if 1
typedef typename boost::python::detail::if_<
(sizeof(c1) == size)
>::template then<
c1
>::template elif<
(sizeof(c2) == size)
>::template then<
c2
>::template elif<
(sizeof(c3) == size)
>::template then<
c3
>::template elif<
(sizeof(c4) == size)
>::template then<
c4
>::template else_<void*>::type type;
#else
typedef typename boost::python::detail::if_<
(sizeof(c1) == size)
, c1
>::template elif<
(sizeof(c2) == size)
, c2
>::template elif<
(sizeof(c3) == size)
, c3
>::template elif<
(sizeof(c4) == size)
, c4
>::template else_<void*>::type type;
#endif
};
int main()
{
BOOST_STATIC_ASSERT((boost::is_same<choose<1>::type,c1>::value));
BOOST_STATIC_ASSERT((boost::is_same<choose<2>::type,c2>::value));
BOOST_STATIC_ASSERT((boost::is_same<choose<3>::type,c3>::value));
BOOST_STATIC_ASSERT((boost::is_same<choose<4>::type,c4>::value));
BOOST_STATIC_ASSERT((boost::is_same<choose<5>::type,void*>::value));
return 0;
}

View File

@@ -1,38 +0,0 @@
// Copyright David Abrahams 2002. 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/class.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/module.hpp>
#include "test_class.hpp"
using namespace boost::python;
typedef test_class<> X;
int x_value(X const& x)
{
return x.value();
}
X make_x(int n) { return X(n); }
BOOST_PYTHON_MODULE_INIT(implicit_ext)
{
implicitly_convertible<int,X>();
module("implicit_ext")
.def("x_value", x_value)
.def("make_x", make_x)
.add(
class_<X>("X")
.def_init(args<int>())
.def("value", &X::value)
.def("set", &X::set)
)
;
implicitly_convertible<X,int>();
}
#include "module_tail.cpp"

View File

@@ -1,56 +0,0 @@
//#include <stdio.h>
#include <cassert>
#include <boost/python/detail/indirect_traits.hpp>
//#define print(expr) printf("%s ==> %s\n", #expr, expr)
int main()
{
using namespace boost::python::detail;
#if 0 // not yet supported
assert(is_reference_to_function<int (&)()>::value);
assert(!is_reference_to_function<int (*)()>::value);
#endif
assert(!is_pointer_to_function<int (&)()>::value);
assert(is_pointer_to_function<int (*)()>::value);
assert(is_reference_to_pointer<int*&>::value);
assert(is_reference_to_pointer<int* const&>::value);
assert(is_reference_to_pointer<int*volatile&>::value);
assert(is_reference_to_pointer<int*const volatile&>::value);
assert(!is_reference_to_pointer<int const volatile>::value);
assert(!is_reference_to_pointer<int>::value);
assert(!is_reference_to_pointer<int*>::value);
assert(!is_reference_to_const<int*&>::value);
assert(is_reference_to_const<int* const&>::value);
assert(!is_reference_to_const<int*volatile&>::value);
assert(is_reference_to_const<int*const volatile&>::value);
assert(!is_reference_to_const<int const volatile>::value);
assert(!is_reference_to_const<int>::value);
assert(!is_reference_to_const<int*>::value);
assert(is_reference_to_non_const<int*&>::value);
assert(!is_reference_to_non_const<int* const&>::value);
assert(is_reference_to_non_const<int*volatile&>::value);
assert(!is_reference_to_non_const<int*const volatile&>::value);
assert(!is_reference_to_non_const<int const volatile>::value);
assert(!is_reference_to_non_const<int>::value);
assert(!is_reference_to_non_const<int*>::value);
assert(!is_reference_to_volatile<int*&>::value);
assert(!is_reference_to_volatile<int* const&>::value);
assert(is_reference_to_volatile<int*volatile&>::value);
assert(is_reference_to_volatile<int*const volatile&>::value);
assert(!is_reference_to_volatile<int const volatile>::value);
assert(!is_reference_to_volatile<int>::value);
assert(!is_reference_to_volatile<int*>::value);
return 0;
}

View File

@@ -1,290 +0,0 @@
// 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 "simple_type.hpp"
#include "complicated.hpp"
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/type_from_python.hpp>
#include <boost/python/object/value_holder.hpp>
#include <boost/python/object/pointer_holder.hpp>
#include <boost/python/object/class.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/to_python_converter.hpp>
#include <boost/python/errors.hpp>
#include <boost/mpl/type_list.hpp>
#include <string.h>
// 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 = {
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 */
};
// 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 = {
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 */
};
// Create a Simple containing "hello, world"
PyObject* new_simple()
{
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
simple->x.s = "hello, world";
return (PyObject*)simple;
}
//
// Declare some wrappers/unwrappers to test the low-level conversion
// mechanism. See boost/python/converter/source.hpp,target.hpp for a
// description of how the type parameters to wrapper<> and unwrapper<>
// are selected.
//
using boost::python::to_python_converter;
// Wrap a simple by copying it into a Simple
struct simple_to_python
: to_python_converter<simple, simple_to_python>
{
static PyObject* convert(simple const& x)
{
SimpleObject* p = PyObject_New(SimpleObject, &SimpleType);
p->x = x;
return (PyObject*)p;
}
};
struct int_from_noddy_extractor
{
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 const& b) { return b; }
C take_c(C const& c) { return c; }
D take_d(D const& d) { return d; }
BOOST_PYTHON_MODULE_INIT(m1)
{
using namespace boost::python;
using boost::mpl::type_list;
using boost::shared_ptr;
simple_to_python();
type_from_python<&NoddyType,int_from_noddy_extractor>();
boost::python::type_from_python<
&SimpleType
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
, member_extractor<SimpleObject, simple, &SimpleObject::x>
#else
, extract_simple_object
#endif
>();
type_from_python<&SimpleType, identity_extractor<SimpleObject> >();
module m1("m1");
m1
// Insert the metaclass for all extension classes
.setattr("xclass", boost::python::objects::class_metatype())
// Insert the base class for all extension classes
.setattr("xinst", boost::python::objects::class_type())
.def("new_noddy", new_noddy)
.def("new_simple", new_simple)
// 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<copy_const_reference>()
)
.def("take_a", take_a)
.def("take_b", take_b)
.def("take_c", take_c)
.def("take_d", take_d)
.add(
class_<A, shared_ptr<A> >("A")
.def_init()
.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
m1
.add(
class_<B,bases<A>, shared_ptr<B> >("B")
.def_init()
.def("name", &B::name)
)
.add(
class_<C,bases<A>, shared_ptr<C> >("C")
.def_init()
.def("name", &C::name)
)
;
m1
.add(
class_<D,shared_ptr<D>, bases<B,C> >("D")
.def_init()
.def("name", &D::name)
)
.add(
class_<complicated>("complicated")
.def_init(type_list<simple const&,int>())
.def_init(type_list<simple const&>())
.def("get_n", &complicated::get_n)
)
;
}
#include "module_tail.cpp"

View File

@@ -1,99 +0,0 @@
// 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 module exercises the converters exposed in m1 at a low level
// by exposing raw Python extension functions that use wrap<> and
// unwrap<> objects.
#include <boost/python/module.hpp>
#include <boost/python/copy_non_const_reference.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include "simple_type.hpp"
// Get a simple (by value) from the argument, and return the
// string it holds.
PyObject* unwrap_simple(simple x)
{
return PyString_FromString(x.s);
}
// Likewise, but demands that its possible to get a non-const
// reference to the simple.
PyObject* unwrap_simple_ref(simple& x)
{
return PyString_FromString(x.s);
}
// Likewise, with a const reference to the simple object.
PyObject* unwrap_simple_const_ref(simple const& x)
{
return PyString_FromString(x.s);
}
// Get an int (by value) from the argument, and convert it to a
// Python Int.
PyObject* unwrap_int(int x)
{
return PyInt_FromLong(x);
}
// Get a non-const reference to an int from the argument
PyObject* unwrap_int_ref(int& x)
{
return PyInt_FromLong(x);
}
// Get a const reference to an int from the argument.
PyObject* unwrap_int_const_ref(int const& x)
{
return PyInt_FromLong(x);
}
// rewrap<T> extracts a T from the argument, then converts the T back
// to a PyObject* and returns it.
template <class T>
struct rewrap
{
static T f(T x) { return x; }
};
BOOST_PYTHON_MODULE_INIT(m2)
{
using boost::python::return_value_policy;
using boost::python::copy_const_reference;
using boost::python::copy_non_const_reference;
boost::python::module("m2")
.def("unwrap_int", unwrap_int)
.def("unwrap_int_ref", unwrap_int_ref)
.def("unwrap_int_const_ref", unwrap_int_const_ref)
.def("unwrap_simple", unwrap_simple)
.def("unwrap_simple_ref", unwrap_simple_ref)
.def("unwrap_simple_const_ref", unwrap_simple_const_ref)
.def("wrap_int", &rewrap<int>::f)
.def("wrap_int_ref", &rewrap<int&>::f
, return_value_policy<copy_non_const_reference>()
)
.def("wrap_int_const_ref", &rewrap<int const&>::f
, return_value_policy<copy_const_reference>()
)
.def("wrap_simple", &rewrap<simple>::f)
.def("wrap_simple_ref", &rewrap<simple&>::f
, return_value_policy<copy_non_const_reference>()
)
.def("wrap_simple_const_ref", &rewrap<simple const&>::f
, return_value_policy<copy_const_reference>()
)
;
}
#include "module_tail.cpp"

View File

@@ -1,174 +0,0 @@
"""
>>> 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 non-const reference to a built-in integer object
>>> try:
... unwrap_int_ref(7)
... except: pass
... else: print 'no exception'
>>> unwrap_int_const_ref(9)
9
>>> 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
>>> f_mutable_ref(g(s))
12
>>> f_const_ptr(g(s))
12
>>> f_mutable_ptr(g(s))
12
>>> f2(g(s))
12
Create an extension class which wraps "complicated" (init1 and get_n)
are a complicated constructor and member function, respectively.
>>> c1 = complicated(s, 99)
>>> c1.get_n()
99
>>> c2 = complicated(s)
>>> c2.get_n()
0
>>> a = A()
>>> b = B()
>>> c = C()
>>> d = D()
------
>>> take_a(a).name()
'A'
>>> try:
... take_b(a)
... except: pass
... else: print 'no exception'
>>> try:
... take_c(a)
... except: pass
... else: print 'no exception'
>>> try:
... take_d(a)
... except: pass
... else: print 'no exception'
------
>>> take_a(b).name()
'A'
>>> take_b(b).name()
'B'
>>> try:
... take_c(b)
... except: pass
... else: print 'no exception'
>>> try:
... take_d(b)
... except: pass
... else: print 'no exception'
-------
>>> take_a(c).name()
'A'
>>> try:
... take_b(c)
... except: pass
... else: print 'no exception'
>>> take_c(c).name()
'C'
>>> try:
... take_d(c)
... except: pass
... else: print 'no exception'
-------
>>> take_a(d).name()
'A'
>>> take_b(d).name()
'B'
>>> take_c(d).name()
'C'
>>> take_d(d).name()
'D'
"""
def run(args = None):
### Strange bug somewhere: with Metrowerks: it will crash in
### garbage-collection code unless traceback and sre have been
### loaded before m1.
# import traceback
# import sre
# import m2
# import m1
import sys
import doctest
if args is not None:
sys.argv = args
# import sys
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

View File

@@ -1,35 +0,0 @@
// Copyright David Abrahams 2002. 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/detail/pointee.hpp>
#include <boost/type_traits/same_traits.hpp>
#include <memory>
#include <boost/shared_ptr.hpp>
#include <boost/static_assert.hpp>
struct A;
int main()
{
BOOST_STATIC_ASSERT(
(boost::is_same<
boost::python::detail::pointee<std::auto_ptr<char**> >::type
, char**
>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<
boost::python::detail::pointee<boost::shared_ptr<A> >::type
, A>::value));
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
BOOST_STATIC_ASSERT(
(boost::is_same<
boost::python::detail::pointee<char*>::type
, char
>::value));
#endif
return 0;
}

View File

@@ -1,39 +0,0 @@
#include <boost/python/converter/type_id.hpp>
#include <cassert>
#include <boost/python/converter/pointer_type_id.hpp>
int main()
{
using namespace boost::python::converter;
undecorated_type_id_t x
= undecorated_type_id<int>();
assert(pointer_type_id<int*>() == x);
assert(pointer_type_id<int const*>() == x);
assert(pointer_type_id<int volatile*>() == x);
assert(pointer_type_id<int const volatile*>() == x);
assert(pointer_type_id<int*&>() == x);
assert(pointer_type_id<int const*&>() == x);
assert(pointer_type_id<int volatile*&>() == x);
assert(pointer_type_id<int const volatile*&>() == x);
assert(pointer_type_id<int*const&>() == x);
assert(pointer_type_id<int const*const&>() == x);
assert(pointer_type_id<int volatile*const&>() == x);
assert(pointer_type_id<int const volatile*const&>() == x);
assert(pointer_type_id<int*volatile&>() == x);
assert(pointer_type_id<int const*volatile&>() == x);
assert(pointer_type_id<int volatile*volatile&>() == x);
assert(pointer_type_id<int const volatile*volatile&>() == x);
assert(pointer_type_id<int*const volatile&>() == x);
assert(pointer_type_id<int const*const volatile&>() == x);
assert(pointer_type_id<int volatile*const volatile&>() == x);
assert(pointer_type_id<int const volatile*const volatile&>() == x);
return 0;
}

View File

@@ -1,148 +0,0 @@
#include <boost/python/converter/from_python.hpp>
//#include <cassert>
//#include <boost/type_traits.hpp>
#include <boost/python/converter/type_id.hpp>
#include <iostream>
int result;
#define ASSERT_SAME(T1,T2) \
if (!is_same< T1, T2 >::value) { \
std::cout << "*********************\n"; \
std::cout << type_id< T1 >() << " != " << type_id< T2 >() << "\n"; \
std::cout << "*********************\n"; \
result = 1; \
}
int main()
{
using namespace boost::python::converter;
using namespace boost;
ASSERT_SAME(
select_from_python<int>::type, rvalue_from_python<int>
);
ASSERT_SAME(
select_from_python<int const>::type, rvalue_from_python<int const>
);
ASSERT_SAME(
select_from_python<int volatile>::type, rvalue_from_python<int volatile>
);
ASSERT_SAME(
select_from_python<int const volatile>::type, rvalue_from_python<int const volatile>
);
ASSERT_SAME(
select_from_python<int*>::type, pointer_from_python<int*>
);
ASSERT_SAME(
select_from_python<int const*>::type, pointer_from_python<int const*>
);
ASSERT_SAME(
select_from_python<int volatile*>::type, pointer_from_python<int volatile*>
);
ASSERT_SAME(
select_from_python<int const volatile*>::type, pointer_from_python<int const volatile*>
);
ASSERT_SAME(
select_from_python<int&>::type, reference_from_python<int&>
);
ASSERT_SAME(
select_from_python<int const&>::type, rvalue_from_python<int const&>
);
ASSERT_SAME(
select_from_python<int volatile&>::type, reference_from_python<int volatile&>
);
ASSERT_SAME(
select_from_python<int const volatile&>::type, reference_from_python<int const volatile&>
);
ASSERT_SAME(
select_from_python<int*&>::type, reference_from_python<int*&>
);
ASSERT_SAME(
select_from_python<int const*&>::type, reference_from_python<int const*&>
);
ASSERT_SAME(
select_from_python<int volatile*&>::type, reference_from_python<int volatile*&>
);
ASSERT_SAME(
select_from_python<int const volatile*&>::type, reference_from_python<int const volatile*&>
);
ASSERT_SAME(
select_from_python<int* const&>::type, pointer_const_reference_from_python<int*const&>
);
ASSERT_SAME(
select_from_python<int const* const&>::type, pointer_const_reference_from_python<int const*const&>
);
ASSERT_SAME(
select_from_python<int volatile* const&>::type, pointer_const_reference_from_python<int volatile*const&>
);
ASSERT_SAME(
select_from_python<int const volatile* const&>::type, pointer_const_reference_from_python<int const volatile*const&>
);
ASSERT_SAME(
select_from_python<int*volatile&>::type, reference_from_python<int*volatile&>
);
ASSERT_SAME(
select_from_python<int const*volatile&>::type, reference_from_python<int const*volatile&>
);
ASSERT_SAME(
select_from_python<int volatile*volatile&>::type, reference_from_python<int volatile*volatile&>
);
ASSERT_SAME(
select_from_python<int const volatile*volatile&>::type, reference_from_python<int const volatile*volatile&>
);
ASSERT_SAME(
select_from_python<int*const volatile&>::type, reference_from_python<int*const volatile&>
);
ASSERT_SAME(
select_from_python<int const*const volatile&>::type, reference_from_python<int const*const volatile&>
);
ASSERT_SAME(
select_from_python<int volatile*const volatile&>::type, reference_from_python<int volatile*const volatile&>
);
ASSERT_SAME(
select_from_python<int const volatile*const volatile&>::type, reference_from_python<int const volatile*const volatile&>
);
return result;
}

View File

@@ -1,78 +0,0 @@
// Copyright David Abrahams 2002. 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/static_assert.hpp>
#include <boost/type_traits/same_traits.hpp>
#include <boost/python/object/select_holder.hpp>
#include <boost/python/has_back_reference.hpp>
#include <boost/python/detail/not_specified.hpp>
#include <memory>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
struct BR {};
struct Base {};
struct Derived : Base {};
namespace boost { namespace python
{
// specialization
template <>
struct has_back_reference<BR>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
}} // namespace boost::python
template <class T, class U>
void assert_same(U* = 0, T* = 0)
{
BOOST_TEST((boost::is_same<T,U>::value));
BOOST_STATIC_ASSERT((boost::is_same<T,U>::value));
}
template <class T, class Held, class Holder>
void assert_holder(T* = 0, Held* = 0, Holder* = 0)
{
assert_same<Holder>(boost::python::objects::select_holder<T,Held>((Held*)0).get());
}
int test_main(int, char * [])
{
using namespace boost::python::detail;
using namespace boost::python::objects;
assert_holder<Base,not_specified,value_holder<Base> >();
assert_holder<BR,not_specified,value_holder_back_reference<BR,BR> >();
assert_holder<Base,Base,value_holder<Base> >();
assert_holder<BR,BR,value_holder_back_reference<BR,BR> >();
assert_holder<Base,Derived
,value_holder_back_reference<Base,Derived> >();
assert_holder<Base,std::auto_ptr<Base>
,pointer_holder<std::auto_ptr<Base>,Base> >();
assert_holder<Base,std::auto_ptr<Derived>
,pointer_holder_back_reference<std::auto_ptr<Derived>,Base> >();
assert_holder<BR,std::auto_ptr<BR>
,pointer_holder_back_reference<std::auto_ptr<BR>,BR> > ();
return 0;
}
#if !defined(_WIN32) || defined(__GNUC__)
// This definition is needed for MinGW 2.95.2 and KCC on OSF for some
// reason, but will break other Win32 compilers.
namespace boost { namespace python
{
bool handle_exception_impl(boost::function0<void>) { return false; }
}}
#endif

View File

@@ -1,71 +0,0 @@
// Copyright David Abrahams 2002. 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 <string>
#include <boost/python/module.hpp>
#include <complex>
template <class T>
struct by_value
{
static T rewrap(T x)
{
return x;
}
};
template <class T>
struct by_const_reference
{
static T rewrap(T const& x)
{
return x;
}
};
BOOST_PYTHON_MODULE_INIT(builtin_converters)
{
boost::python::module("builtin_converters")
.def("rewrap_value_bool", by_value<bool>::rewrap)
.def("rewrap_value_signed_char", by_value<signed char>::rewrap)
.def("rewrap_value_unsigned_char", by_value<unsigned char>::rewrap)
.def("rewrap_value_int", by_value<int>::rewrap)
.def("rewrap_value_unsigned_int", by_value<unsigned int>::rewrap)
.def("rewrap_value_short", by_value<short>::rewrap)
.def("rewrap_value_unsigned_short", by_value<unsigned short>::rewrap)
.def("rewrap_value_long", by_value<long>::rewrap)
.def("rewrap_value_unsigned_long", by_value<unsigned long>::rewrap)
.def("rewrap_value_float", by_value<float>::rewrap)
.def("rewrap_value_double", by_value<double>::rewrap)
.def("rewrap_value_long_double", by_value<long double>::rewrap)
.def("rewrap_value_complex_float", by_value<std::complex<float> >::rewrap)
.def("rewrap_value_complex_double", by_value<std::complex<double> >::rewrap)
.def("rewrap_value_complex_long_double", by_value<std::complex<long double> >::rewrap)
.def("rewrap_value_string", by_value<std::string>::rewrap)
.def("rewrap_value_cstring", by_value<char const*>::rewrap)
.def("rewrap_const_reference_bool", by_const_reference<bool>::rewrap)
.def("rewrap_const_reference_signed_char", by_const_reference<signed char>::rewrap)
.def("rewrap_const_reference_unsigned_char", by_const_reference<unsigned char>::rewrap)
.def("rewrap_const_reference_int", by_const_reference<int>::rewrap)
.def("rewrap_const_reference_unsigned_int", by_const_reference<unsigned int>::rewrap)
.def("rewrap_const_reference_short", by_const_reference<short>::rewrap)
.def("rewrap_const_reference_unsigned_short", by_const_reference<unsigned short>::rewrap)
.def("rewrap_const_reference_long", by_const_reference<long>::rewrap)
.def("rewrap_const_reference_unsigned_long", by_const_reference<unsigned long>::rewrap)
.def("rewrap_const_reference_float", by_const_reference<float>::rewrap)
.def("rewrap_const_reference_double", by_const_reference<double>::rewrap)
.def("rewrap_const_reference_long_double", by_const_reference<long double>::rewrap)
.def("rewrap_const_reference_complex_float", by_const_reference<std::complex<float> >::rewrap)
.def("rewrap_const_reference_complex_double", by_const_reference<std::complex<double> >::rewrap)
.def("rewrap_const_reference_complex_long_double", by_const_reference<std::complex<long double> >::rewrap)
.def("rewrap_const_reference_string", by_const_reference<std::string>::rewrap)
.def("rewrap_const_reference_cstring", by_const_reference<char const*>::rewrap)
;
}

View File

@@ -1,145 +0,0 @@
"""
>>> from builtin_converters import *
>>> rewrap_value_bool(None)
0
>>> rewrap_value_bool(0)
0
>>> rewrap_value_bool(33)
1
>>> rewrap_value_signed_char(42)
42
>>> rewrap_value_unsigned_char(42)
42
>>> rewrap_value_int(42)
42
>>> rewrap_value_unsigned_int(42)
42
>>> rewrap_value_short(42)
42
>>> rewrap_value_unsigned_short(42)
42
>>> rewrap_value_long(42)
42
>>> rewrap_value_unsigned_long(42)
42
>>> abs(rewrap_value_float(4.2) - 4.2) < .000001
1
>>> rewrap_value_double(4.2) - 4.2
0.0
>>> rewrap_value_long_double(4.2) - 4.2
0.0
>>> abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001
1
>>> abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001
1
>>> abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001
1
>>> rewrap_value_cstring('hello, world')
'hello, world'
>>> rewrap_value_string('yo, wassup?')
'yo, wassup?'
>>> rewrap_const_reference_bool(None)
0
>>> rewrap_const_reference_bool(0)
0
>>> rewrap_const_reference_bool('yes')
1
>>> rewrap_const_reference_signed_char(42)
42
>>> rewrap_const_reference_unsigned_char(42)
42
>>> rewrap_const_reference_int(42)
42
>>> rewrap_const_reference_unsigned_int(42)
42
>>> rewrap_const_reference_short(42)
42
>>> rewrap_const_reference_unsigned_short(42)
42
>>> rewrap_const_reference_long(42)
42
>>> rewrap_const_reference_unsigned_long(42)
42
>>> abs(rewrap_const_reference_float(4.2) - 4.2) < .000001
1
>>> rewrap_const_reference_double(4.2) - 4.2
0.0
>>> rewrap_const_reference_long_double(4.2) - 4.2
0.0
>>> abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001
1
>>> abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001
1
>>> abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001
1
>>> rewrap_const_reference_cstring('hello, world')
'hello, world'
>>> rewrap_const_reference_string('yo, wassup?')
'yo, wassup?'
Check that None <==> NULL
>>> rewrap_const_reference_cstring(None)
But when converted to a string rvalue, None becomes 'None':
>>> rewrap_const_reference_string(None)
'None'
Now check implicit conversions between floating/integer types
>>> rewrap_const_reference_float(42)
42.0
>>> rewrap_const_reference_int(42.0)
42
>>> rewrap_value_float(42)
42.0
>>> rewrap_value_int(42.0)
42
Check that classic classes also work
>>> class FortyTwo:
... def __int__(self):
... return 42
... def __float__(self):
... return 42.0
... def __complex__(self):
... return complex(4+.2j)
... def __str__(self):
... return '42'
>>> rewrap_const_reference_float(FortyTwo())
42.0
>>> rewrap_value_int(FortyTwo())
42
>>> rewrap_const_reference_string(FortyTwo())
'42'
>>> abs(rewrap_value_complex_double(FortyTwo()) - (4+.2j)) < .000001
1
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

View File

@@ -1,118 +0,0 @@
// Copyright David Abrahams 2002. 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/module.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/manage_new_object.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/class.hpp>
#include <boost/mpl/type_list.hpp>
using namespace boost::python;
using boost::mpl::type_list;
int a_instances = 0;
int num_a_instances() { return a_instances; }
struct inner
{
inner(std::string const& s)
: s(s)
{}
void change(std::string const& new_s)
{
this->s = new_s;
}
std::string s;
};
struct A
{
A(std::string const& s)
: x(s)
{
++a_instances;
}
~A()
{
--a_instances;
}
std::string content() const
{
return x.s;
}
inner& get_inner()
{
return x;
}
inner x;
};
struct B
{
B() : x(0) {}
B(A* x_) : x(x_) {}
inner const* adopt(A* x) { this->x = x; return &x->get_inner(); }
std::string a_content()
{
return x ? x->content() : std::string("empty");
}
A* x;
};
A* create(std::string const& s)
{
return new A(s);
}
BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext)
{
boost::python::module("test_pointer_adoption_ext")
.def("num_a_instances", num_a_instances)
// Specify the manage_new_object return policy to take
// ownership of create's result
.def("create", create, return_value_policy<manage_new_object>())
.add(
class_<A>()
.def("content", &A::content)
.def("get_inner", &A::get_inner, return_internal_reference<>())
)
.add(
class_<inner>()
.def("change", &inner::change)
)
.add(
class_<B>("B")
.def_init()
.def_init(args<A*>(), with_custodian_and_ward_postcall<1,2>())
.def("adopt", &B::adopt
// Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self")
, return_internal_reference<2
// Meanwhile, self holds a reference to the 2nd argument.
, with_custodian_and_ward<1,2> >()
)
.def("a_content", &B::a_content)
)
;
}

View File

@@ -1,85 +0,0 @@
"""
>>> from test_pointer_adoption_ext import *
>>> num_a_instances()
0
>>> a = create('dynamically allocated')
>>> num_a_instances()
1
>>> a.content()
'dynamically allocated'
>>> innards = a.get_inner()
>>> innards.change('with an exposed reference')
>>> a.content()
'with an exposed reference'
# The a instance should be kept alive...
>>> a = None
>>> num_a_instances()
1
# ...until we're done with its innards
>>> innards = None
>>> num_a_instances()
0
>>> b = B()
>>> a = create('another')
>>> b.a_content()
'empty'
>>> innards = b.adopt(a);
>>> b.a_content()
'another'
>>> num_a_instances()
1
>>> del a # innards and b are both holding a reference
>>> num_a_instances()
1
>>> innards.change('yet another')
>>> b.a_content()
'yet another'
>>> del innards
>>> num_a_instances() # b still owns a reference to a
1
>>> del b
>>> num_a_instances()
0
Test call policies for constructors here
>>> a = create('second a')
>>> num_a_instances()
1
>>> b = B(a)
>>> num_a_instances()
1
>>> a.content()
'second a'
>>> del a
>>> num_a_instances()
1
>>> b.a_content()
'second a'
>>> del b
>>> num_a_instances()
0
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

View File

@@ -1,118 +0,0 @@
// Copyright David Abrahams 2002. 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/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/call_method.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>
using namespace boost::python;
struct X
{
explicit X(int x) : x(x), magic(7654321) { ++counter; }
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int x) { assert(magic == 7654321); this->x = x; }
int value() const { assert(magic == 7654321); return x; }
static int count() { return counter; }
private:
void operator=(X const&);
private:
int x;
long magic;
static int counter;
};
struct Y : X
{
Y(int x) : X(x) {};
};
struct abstract : X
{
abstract(int x) : X(x) {};
int call_f(Y const& y) { return f(y); }
virtual int f(Y const& y) = 0;
};
struct concrete : X
{
concrete(int x) : X(x) {};
int call_f(Y const& y) { return f(y); }
virtual int f(Y const& y) { set(y.value()); return y.value(); }
};
struct abstract_callback : abstract
{
abstract_callback(PyObject* p, int x)
: abstract(x), self(p)
{}
int f(Y const& y)
{
return call_method<int>(self, "f", boost::ref(y));
}
PyObject* self;
};
struct concrete_callback : concrete
{
concrete_callback(PyObject* p, int x)
: concrete(x), self(p)
{}
concrete_callback(PyObject* p, concrete const& x)
: concrete(x), self(p)
{}
int f(Y const& y)
{
return call_method<int>(self, "f", boost::ref(y));
}
int f_impl(Y const& y)
{
return this->concrete::f(y);
}
PyObject* self;
};
int X::counter;
BOOST_PYTHON_MODULE_INIT(virtual_functions_ext)
{
module("virtual_functions_ext")
.add(
class_<concrete, concrete_callback>("concrete")
.def_init(args<int>())
.def("value", &concrete::value)
.def("set", &concrete::set)
.def("call_f", &concrete::call_f)
.def("f", &concrete_callback::f_impl))
.add(
class_<abstract, boost::noncopyable, boost::shared_ptr<abstract_callback>
>("abstract")
.def_init(args<int>())
.def("value", &abstract::value)
.def("call_f", &abstract::call_f)
.def("set", &abstract::set))
.add(
class_<Y>("Y")
.def_init(args<int>())
.def("value", &Y::value)
.def("set", &Y::set)
)
;
}
#include "module_tail.cpp"