Skip to content

Commit 11bd4c3

Browse files
committed
Test for has_back_reference<> specialization
[SVN r13272]
1 parent 8d88a92 commit 11bd4c3

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed

test/Jamfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters
5656
bpl-test test_pointer_adoption ;
5757
bpl-test callbacks ;
5858
bpl-test virtual_functions ;
59+
bpl-test back_reference ;
5960

6061
# --- unit tests of library components ---
6162
unit-test indirect_traits_test

test/back_reference.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright David Abrahams 2002. Permission to copy, use,
2+
// modify, sell and distribute this software is granted provided this
3+
// copyright notice appears in all copies. This software is provided
4+
// "as is" without express or implied warranty, and with no claim as
5+
// to its suitability for any purpose.
6+
#include <boost/python/class.hpp>
7+
#include <boost/python/module.hpp>
8+
#include <boost/python/has_back_reference.hpp>
9+
#include <boost/ref.hpp>
10+
#include <boost/utility.hpp>
11+
#include <memory>
12+
#include <cassert>
13+
#include <boost/python/copy_const_reference.hpp>
14+
#include <boost/python/return_value_policy.hpp>
15+
16+
// This test shows that a class can be wrapped "as itself" but also
17+
// acquire a back-reference iff has_back_reference<> is appropriately
18+
// specialized.
19+
using namespace boost::python;
20+
21+
struct X
22+
{
23+
explicit X(int x) : x(x), magic(7654321) { ++counter; }
24+
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
25+
virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; }
26+
27+
void set(int x) { assert(magic == 7654321); this->x = x; }
28+
int value() const { assert(magic == 7654321); return x; }
29+
static int count() { return counter; }
30+
private:
31+
void operator=(X const&);
32+
private:
33+
int x;
34+
long magic;
35+
static int counter;
36+
};
37+
38+
int X::counter;
39+
40+
struct Y : X
41+
{
42+
Y(PyObject* self, int x) : X(x) {};
43+
Y(PyObject* self, Y const& rhs) : X(rhs), self(self) {};
44+
private:
45+
Y(Y const&);
46+
PyObject* self;
47+
};
48+
49+
struct Z : X
50+
{
51+
Z(PyObject* self, int x) : X(x) {};
52+
Z(PyObject* self, Z const& rhs) : X(rhs), self(self) {};
53+
private:
54+
Z(Z const&);
55+
PyObject* self;
56+
};
57+
58+
Y const& copy_Y(Y const& y) { return y; }
59+
Z const& copy_Z(Z const& z) { return z; }
60+
61+
namespace boost { namespace python
62+
{
63+
template <>
64+
struct has_back_reference<Y>
65+
{
66+
BOOST_STATIC_CONSTANT(bool, value = true);
67+
};
68+
69+
template <>
70+
struct has_back_reference<Z>
71+
{
72+
BOOST_STATIC_CONSTANT(bool, value = true);
73+
};
74+
}}
75+
76+
77+
BOOST_PYTHON_MODULE_INIT(back_reference_ext)
78+
{
79+
module("back_reference_ext")
80+
.def("copy_Y", copy_Y, return_value_policy<copy_const_reference>())
81+
.def("copy_Z", copy_Z, return_value_policy<copy_const_reference>())
82+
.def("x_instances", &X::count)
83+
.add(
84+
class_<Y>("Y")
85+
.def_init(args<int>())
86+
.def("value", &Y::value)
87+
.def("set", &Y::set)
88+
)
89+
90+
.add(
91+
class_<Z,std::auto_ptr<Z> >("Z")
92+
.def_init(args<int>())
93+
.def("value", &Z::value)
94+
.def("set", &Z::set)
95+
)
96+
;
97+
}
98+
99+
#include "module_tail.cpp"

test/back_reference.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'''
2+
>>> from back_reference_ext import *
3+
>>> y = Y(3)
4+
>>> z = Z(4)
5+
>>> x_instances()
6+
2
7+
>>> y2 = copy_Y(y)
8+
>>> x_instances()
9+
3
10+
>>> z2 = copy_Z(z)
11+
>>> x_instances()
12+
4
13+
'''
14+
15+
def run(args = None):
16+
import sys
17+
import doctest
18+
19+
if args is not None:
20+
sys.argv = args
21+
return doctest.testmod(sys.modules.get(__name__))
22+
23+
if __name__ == '__main__':
24+
print "running..."
25+
import sys
26+
sys.exit(run()[0])

0 commit comments

Comments
 (0)