From 11bd4c32231261d82fc561e76cd879663db6cbab Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Mar 2002 23:55:08 +0000 Subject: [PATCH] Test for has_back_reference<> specialization [SVN r13272] --- test/Jamfile | 1 + test/back_reference.cpp | 99 +++++++++++++++++++++++++++++++++++++++++ test/back_reference.py | 26 +++++++++++ 3 files changed, 126 insertions(+) create mode 100644 test/back_reference.cpp create mode 100644 test/back_reference.py diff --git a/test/Jamfile b/test/Jamfile index 6db104fb..9809c5db 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -56,6 +56,7 @@ bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters bpl-test test_pointer_adoption ; bpl-test callbacks ; bpl-test virtual_functions ; +bpl-test back_reference ; # --- unit tests of library components --- unit-test indirect_traits_test diff --git a/test/back_reference.cpp b/test/back_reference.cpp new file mode 100644 index 00000000..e1338eaa --- /dev/null +++ b/test/back_reference.cpp @@ -0,0 +1,99 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include + +// 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 + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template <> + struct has_back_reference + { + 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()) + .def("copy_Z", copy_Z, return_value_policy()) + .def("x_instances", &X::count) + .add( + class_("Y") + .def_init(args()) + .def("value", &Y::value) + .def("set", &Y::set) + ) + + .add( + class_ >("Z") + .def_init(args()) + .def("value", &Z::value) + .def("set", &Z::set) + ) + ; +} + +#include "module_tail.cpp" diff --git a/test/back_reference.py b/test/back_reference.py new file mode 100644 index 00000000..552deec8 --- /dev/null +++ b/test/back_reference.py @@ -0,0 +1,26 @@ +''' +>>> 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])