From 3caa91cc36bc04cf1bbe0726a6d8b2fdf20949d9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Mar 2002 21:07:26 +0000 Subject: [PATCH] More fixes [SVN r13182] --- include/boost/python/class.hpp | 15 +++- include/boost/python/object/find_instance.hpp | 37 +++++++++ .../boost/python/object/pointer_holder.hpp | 76 ++++++++++++++----- include/boost/python/object/value_holder.hpp | 55 +++++++++++--- test/Jamfile | 1 + 5 files changed, 150 insertions(+), 34 deletions(-) create mode 100644 include/boost/python/object/find_instance.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 7f31df88..0a9c5d87 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -12,6 +12,7 @@ # include # include # include +# include # include # include # include @@ -103,14 +104,24 @@ class class_ : private objects::class_base // Use function::add_to_namespace to achieve overloading if // appropriate. objects::function::add_to_namespace( - this->object(), name, ref(detail::wrap_function(f))); + this->object(), name, + ref(detail::wrap_function( + // This bit of nastiness casts F to a member function of T if possible. + detail::member_function_cast::stage1(f).stage2((T*)0).stage3(f) + ))); return *this; } template self& def(char const* name, Fn fn, CallPolicy policy) { - this->def(name, boost::python::make_function(fn, policy)); + this->def(name + , boost::python::make_function( + // This bit of nastiness casts F to a member function of T if possible. + detail::member_function_cast::stage1(fn).stage2((T*)0).stage3(fn) + , policy) + ); + return *this; } diff --git a/include/boost/python/object/find_instance.hpp b/include/boost/python/object/find_instance.hpp new file mode 100644 index 00000000..c60a82f7 --- /dev/null +++ b/include/boost/python/object/find_instance.hpp @@ -0,0 +1,37 @@ +// 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. +#ifndef FIND_INSTANCE_DWA2002312_HPP +# define FIND_INSTANCE_DWA2002312_HPP + +namespace boost { namespace python { namespace objects { + +// Given an undecorated type_id, find the instance data which +// corresponds to it, or return 0 in case no such type is held. +BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::undecorated_type_id_t); + +// This produces a function with the right signature for use in from_python conversions +template +struct instance_finder +{ + instance_finder() + { + converter::registry::insert(&execute, converter::undecorated_type_id()); + } + + static instance_finder const registration; + private: + static inline void* execute(PyObject* p) + { + return find_instance_impl(p, converter::undecorated_type_id()); + } +}; + +template +instance_finder const instance_finder::registration; + +}}} // namespace boost::python::objects + +#endif // FIND_INSTANCE_DWA2002312_HPP diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 57cb6b47..84700299 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -9,6 +9,7 @@ # include # include # include +# include # include # include # include @@ -153,67 +154,88 @@ struct pointer_holder_back_reference : instance_holder // Forward construction to the held object pointer_holder_back_reference(PyObject* p) - : m_p(new Value(p)) {} + : m_p(new BackReferenceType(p)) { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) - )) {} + )) { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) , (typename unwrap_reference::type&)(a6) - )) {} + )) { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -222,11 +244,14 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a6) , (typename unwrap_reference::type&)(a7) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -236,11 +261,14 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a7) , (typename unwrap_reference::type&)(a8) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -251,11 +279,14 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a8) , (typename unwrap_reference::type&)(a9) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -267,7 +298,10 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a9) , (typename unwrap_reference::type&)(a10) )) - {} + { + (void)instance_finder::registration; + } + private: // required holder implementation void* holds(converter::undecorated_type_id_t); diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 62222a23..c0a5c580 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -10,6 +10,7 @@ # include # include # include +# include # include namespace boost { namespace python { namespace objects { @@ -146,14 +147,20 @@ struct value_holder_back_reference : instance_holder { // Forward construction to the held object value_holder_back_reference(PyObject* p) - : m_held() {} + : m_held() { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1) : m_held(p , (typename unwrap_reference::type&)(a1) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2) @@ -161,7 +168,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) @@ -170,7 +180,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) @@ -180,7 +193,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) @@ -190,7 +206,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) - ) {} + ) { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) @@ -201,7 +220,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) , (typename unwrap_reference::type&)(a6) - ) {} + ) { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) @@ -214,7 +236,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a6) , (typename unwrap_reference::type&)(a7) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) @@ -228,7 +253,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a7) , (typename unwrap_reference::type&)(a8) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) @@ -243,7 +271,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a8) , (typename unwrap_reference::type&)(a9) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) @@ -259,7 +290,9 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a9) , (typename unwrap_reference::type&)(a10) ) - {} + { + (void)instance_finder::registration; + } private: // required holder implementation void* holds(converter::undecorated_type_id_t); diff --git a/test/Jamfile b/test/Jamfile index 767b07e6..1f5de1e9 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -55,6 +55,7 @@ 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 ; # --- unit tests of library components --- unit-test indirect_traits_test