From 81124780d0d2a6d7bf7e24cbdc5395c240e659db Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 2 Apr 2002 22:19:22 +0000 Subject: [PATCH] Support for constructor policies [SVN r13350] --- include/boost/python/class.hpp | 13 +++ .../boost/python/detail/indirect_traits.hpp | 82 +++++++++++++++++++ include/boost/python/make_function.hpp | 14 ++++ test/indirect_traits_test.cpp | 8 ++ test/test_pointer_adoption.cpp | 2 + test/test_pointer_adoption.py | 22 +++++ 6 files changed, 141 insertions(+) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index ad1561ba..8e921780 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -132,6 +132,19 @@ class class_ : public objects::class_base return *this; } + template + self& def_init(Args const&, CallPolicy policy) + { + def("__init__", + make_constructor( + policy + // Using runtime type selection works around a CWPro7 bug. + , objects::select_holder((held_type*)0).get() + ) + ); + return *this; + } + // Define the default constructor. self& def_init() { diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index f925eaee..a3e67dd3 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -7,6 +7,7 @@ # define INDIRECT_TRAITS_DWA2002131_HPP # include # include +# include # include namespace boost { namespace python { namespace detail { @@ -24,6 +25,68 @@ struct is_reference_to_const BOOST_STATIC_CONSTANT(bool, value = true); }; +# if 0 // Corresponding code doesn't work on MSVC yet +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; +# endif + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + template struct is_reference_to_non_const { @@ -114,6 +177,25 @@ struct is_pointer_help >::type type; }; +# if 0 // doesn't seem to work yet +template +struct is_reference_to_function +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type)); +# endif + +template +struct is_pointer_to_function +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type)); +}; + template typename is_const_help::type reference_to_const_helper(V&); outer_no_type diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 6e7f1661..5ce5ec7d 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -49,6 +49,20 @@ objects::function* make_constructor(Holder* = 0, ArgList* = 0) , nargs + 1); } +template +objects::function* make_constructor(Policies const& policies, Holder* = 0, ArgList* = 0) +{ + enum { nargs = mpl::size::value }; + + return new objects::function( + objects::py_function( + ::boost::bind(detail::caller(), + objects::make_holder + ::template apply::execute + , _1, _2, policies)) + , nargs + 1); +} + }} // namespace boost::python #endif // MAKE_FUNCTION_DWA20011221_HPP diff --git a/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp index a15e7f85..338e4d6a 100644 --- a/test/indirect_traits_test.cpp +++ b/test/indirect_traits_test.cpp @@ -8,6 +8,14 @@ int main() { using namespace boost::python::detail; +#if 0 // not yet supported + assert(is_reference_to_function::value); + assert(!is_reference_to_function::value); +#endif + + assert(!is_pointer_to_function::value); + assert(is_pointer_to_function::value); + assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index 87b3eaab..33cd4dc2 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -60,6 +60,7 @@ struct A struct B { B() : x(0) {} + B(A* x_) : x(x_) {} inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } @@ -101,6 +102,7 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) .add( class_("B") .def_init() + .def_init(args(), 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") diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py index 075a640b..d28dea5c 100644 --- a/test/test_pointer_adoption.py +++ b/test/test_pointer_adoption.py @@ -48,6 +48,28 @@ >>> 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