mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 16:32:16 +00:00
Add the ability to easily use new-style polymorphism wrappers with
smart pointer held_type. [SVN r31392]
This commit is contained in:
@@ -30,6 +30,10 @@
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/mpl/placeholders.hpp>
|
||||
# include <boost/mpl/single_view.hpp>
|
||||
|
||||
# include <boost/mpl/assert.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
# include <boost/noncopyable.hpp>
|
||||
@@ -49,6 +53,8 @@ struct register_base_of
|
||||
template <class Base>
|
||||
inline void operator()(Base*) const
|
||||
{
|
||||
BOOST_MPL_ASSERT_NOT((is_same<Base,Derived>));
|
||||
|
||||
// Register the Base class
|
||||
register_dynamic_id<Base>();
|
||||
|
||||
@@ -58,7 +64,7 @@ struct register_base_of
|
||||
// Register the down-cast, if appropriate.
|
||||
this->register_downcast((Base*)0, is_polymorphic<Base>());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static inline void register_downcast(void*, mpl::false_) {}
|
||||
|
||||
@@ -186,7 +192,7 @@ struct class_metadata
|
||||
, mpl::if_<
|
||||
use_value_holder
|
||||
, value_holder<T>
|
||||
, pointer_holder<held_type,T>
|
||||
, pointer_holder<held_type,wrapped>
|
||||
>
|
||||
>::type holder;
|
||||
|
||||
@@ -253,6 +259,8 @@ struct class_metadata
|
||||
//
|
||||
inline static void maybe_register_callback_class(void*, mpl::false_) {}
|
||||
|
||||
inline static void maybe_register_callback_class(wrapped*, mpl::true_) {}
|
||||
|
||||
template <class T2>
|
||||
inline static void maybe_register_callback_class(T2*, mpl::true_)
|
||||
{
|
||||
|
||||
12
test/Jamfile
12
test/Jamfile
@@ -101,6 +101,10 @@ bpl-test crossmod_exception
|
||||
[ bpl-test andreas_beyer ]
|
||||
[ bpl-test polymorphism ]
|
||||
[ bpl-test polymorphism2 ]
|
||||
|
||||
[ bpl-test wrapper_held_type ]
|
||||
[ bpl-test polymorphism2_auto_ptr ]
|
||||
|
||||
[ bpl-test auto_ptr ]
|
||||
[ bpl-test minimal ]
|
||||
[ bpl-test args ]
|
||||
@@ -115,7 +119,7 @@ bpl-test crossmod_exception
|
||||
[ bpl-test keywords : keywords.cpp keywords_test.py ]
|
||||
|
||||
[ extension builtin_converters : test_builtin_converters.cpp <template>../build/extension ]
|
||||
[ boost-python-runtest builtin_converters : test_builtin_converters.py <pyd>builtin_converters ]
|
||||
[ boost-python-runtest builtin_converters : test_builtin_converters.py <pyd>builtin_converters : : : -v ]
|
||||
|
||||
[ bpl-test test_pointer_adoption ]
|
||||
[ bpl-test operators ]
|
||||
@@ -164,11 +168,11 @@ bpl-test crossmod_exception
|
||||
[ bpl-test vector_indexing_suite ]
|
||||
[ bpl-test pointer_vector ]
|
||||
|
||||
|
||||
[ extension map_indexing_suite_ext
|
||||
: map_indexing_suite.cpp int_map_indexing_suite.cpp <template>../build/extension ]
|
||||
[ boost-python-runtest
|
||||
map_indexing_suite : map_indexing_suite.py <pyd>map_indexing_suite_ext ]
|
||||
|
||||
#[ boost-python-runtest
|
||||
# map_indexing_suite : map_indexing_suite.py <pyd>map_indexing_suite_ext : : : -v ]
|
||||
|
||||
# if $(TEST_BIENSTMAN_NON_BUGS)
|
||||
# {
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
#include <boost/python/call.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef HELD_BY_AUTO_PTR
|
||||
# define HELD_PTR(X) , std::auto_ptr< X >
|
||||
#else
|
||||
# define HELD_PTR(X)
|
||||
#endif
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct P
|
||||
@@ -123,19 +131,23 @@ C& getCCppObj ()
|
||||
|
||||
A* pass_a(A* x) { return x; }
|
||||
|
||||
#ifdef HELD_BY_AUTO_PTR
|
||||
BOOST_PYTHON_MODULE_INIT(polymorphism2_auto_ptr_ext)
|
||||
#else
|
||||
BOOST_PYTHON_MODULE_INIT(polymorphism2_ext)
|
||||
#endif
|
||||
{
|
||||
class_<ACallback,boost::noncopyable>("A")
|
||||
class_<ACallback HELD_PTR(A),boost::noncopyable>("A")
|
||||
.def("f", &A::f, &ACallback::default_f)
|
||||
;
|
||||
|
||||
def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
|
||||
|
||||
class_<C,bases<A>,boost::noncopyable>("C")
|
||||
class_<C HELD_PTR(C),bases<A>,boost::noncopyable>("C")
|
||||
.def("f", &C::f)
|
||||
;
|
||||
|
||||
class_<DCallback,bases<A>,boost::noncopyable>("D")
|
||||
class_<DCallback HELD_PTR(D),bases<A>,boost::noncopyable>("D")
|
||||
.def("f", &D::f)
|
||||
.def("g", &D::g)
|
||||
;
|
||||
@@ -152,7 +164,7 @@ BOOST_PYTHON_MODULE_INIT(polymorphism2_ext)
|
||||
.def("f", pure_virtual(&P::f))
|
||||
;
|
||||
|
||||
class_<Q, bases<P> >("Q")
|
||||
class_<Q HELD_PTR(Q), bases<P> >("Q")
|
||||
.def("g", &P::g) // make sure virtual inheritance doesn't interfere
|
||||
;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
import unittest
|
||||
from polymorphism2_ext import *
|
||||
import sys
|
||||
|
||||
class PolymorphTest(unittest.TestCase):
|
||||
|
||||
@@ -77,11 +77,18 @@ class PolymorphTest(unittest.TestCase):
|
||||
r = R()
|
||||
self.failUnlessEqual ('R.f', r.f())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# remove the option which upsets unittest
|
||||
|
||||
def test():
|
||||
# remove the option that upsets unittest
|
||||
import sys
|
||||
sys.argv = [ x for x in sys.argv if x != '--broken-auto-ptr' ]
|
||||
|
||||
unittest.main()
|
||||
|
||||
# This nasty hack basically says that if we're loaded by another module, we'll
|
||||
# be testing polymorphism2_auto_ptr_ext instead of polymorphism2_ext.
|
||||
if __name__ == "__main__":
|
||||
from polymorphism2_ext import *
|
||||
test()
|
||||
else:
|
||||
from polymorphism2_auto_ptr_ext import *
|
||||
|
||||
|
||||
6
test/polymorphism2_auto_ptr.cpp
Executable file
6
test/polymorphism2_auto_ptr.cpp
Executable file
@@ -0,0 +1,6 @@
|
||||
// Copyright David Abrahams 2005. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define HELD_BY_AUTO_PTR
|
||||
#include "polymorphism2.cpp"
|
||||
5
test/polymorphism2_auto_ptr.py
Normal file
5
test/polymorphism2_auto_ptr.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# Copyright David Abrahams 2005. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
import polymorphism2
|
||||
polymorphism2.test()
|
||||
68
test/wrapper_held_type.cpp
Executable file
68
test/wrapper_held_type.cpp
Executable file
@@ -0,0 +1,68 @@
|
||||
// Copyright David Abrahams 2005. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/register_ptr_to_python.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/wrapper.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/implicit.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
struct data
|
||||
{
|
||||
virtual int id() const
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
};
|
||||
|
||||
std::auto_ptr<data> create_data()
|
||||
{
|
||||
return std::auto_ptr<data>( new data );
|
||||
}
|
||||
|
||||
void do_nothing( std::auto_ptr<data>& ){}
|
||||
|
||||
|
||||
namespace bp = boost::python;
|
||||
|
||||
struct data_wrapper : data, bp::wrapper< data >
|
||||
{
|
||||
data_wrapper(data const & arg )
|
||||
: data( arg )
|
||||
, bp::wrapper< data >()
|
||||
{}
|
||||
|
||||
data_wrapper()
|
||||
: data()
|
||||
, bp::wrapper< data >()
|
||||
{}
|
||||
|
||||
virtual int id() const
|
||||
{
|
||||
if( bp::override id = this->get_override( "id" ) )
|
||||
return bp::call<int>(id.ptr()); // id();
|
||||
else
|
||||
return data::id( );
|
||||
}
|
||||
|
||||
virtual int default_id( ) const
|
||||
{
|
||||
return this->data::id( );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(wrapper_held_type_ext)
|
||||
{
|
||||
bp::class_< data_wrapper, std::auto_ptr< data > >( "data" )
|
||||
.def( "id", &data::id, &::data_wrapper::default_id );
|
||||
|
||||
bp::def( "do_nothing", &do_nothing );
|
||||
bp::def( "create_data", &create_data );
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
34
test/wrapper_held_type.py
Normal file
34
test/wrapper_held_type.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright David Abrahams 2005. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
'''
|
||||
>>> from wrapper_held_type_ext import *
|
||||
>>> d = data()
|
||||
>>> print d.id()
|
||||
42
|
||||
>>> do_nothing( d )
|
||||
>>> print d.id()
|
||||
42
|
||||
>>> d = create_data()
|
||||
>>> print d.id()
|
||||
42
|
||||
>>> do_nothing( d )
|
||||
>>> print d.id()
|
||||
42
|
||||
'''
|
||||
|
||||
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
|
||||
status = run()[0]
|
||||
if (status == 0): print "Done."
|
||||
sys.exit(status)
|
||||
|
||||
Reference in New Issue
Block a user