From 43e5ccd0a7176261146f703bcae431a87d259098 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 May 2003 22:17:23 +0000 Subject: [PATCH] object_core.hpp - allow wrapping of objects which take object managers in their constructors. forward.hpp pointer_holder.hpp value_holder.hpp test/long.[py/cpp] pointee.hpp, - begin making borland work. cv_category.hpp, referent_storage.hpp instance.hpp self.hpp - removed flotsam signature.hpp - use vector instead of list destroy.hpp - removed needless complication make_keyword_range_fn.hpp - support for simpler init using vectors class_converters.hpp - workaround for pro7 inheritance.hpp - simplified; took out pro7 workarounds; factored out inheritance_query.hpp to reduce recompilation dependencies make_ptr_instance.hpp - add missing typename registry.cpp - add a little invariant checking for metrowerks class.cpp - stopped relying on class_id typedef test/data_members.cpp - added a few more tests to make sure things compile at least. test/destroy_test.cpp - removed cheating has_trivial_destructor tests test/enum.cpp - added some pro7 workarounds test/virtual_functions.[py/cpp] - added _some_ tests for callbacks which return by reference. [SVN r18489] --- include/boost/python/detail/cv_category.hpp | 9 +- include/boost/python/detail/destroy.hpp | 37 ++----- .../python/detail/make_keyword_range_fn.hpp | 8 +- .../boost/python/detail/referent_storage.hpp | 4 +- .../boost/python/object/class_converters.hpp | 15 ++- include/boost/python/object/forward.hpp | 100 +++++++++++++++--- include/boost/python/object/inheritance.hpp | 63 ++++------- .../boost/python/object/inheritance_query.hpp | 18 ++++ include/boost/python/object/instance.hpp | 5 +- .../boost/python/object/make_ptr_instance.hpp | 4 +- .../boost/python/object/pointer_holder.hpp | 8 +- include/boost/python/object/value_holder.hpp | 8 +- include/boost/python/object_core.hpp | 65 ++++++++---- include/boost/python/pointee.hpp | 4 +- include/boost/python/self.hpp | 4 +- include/boost/python/signature.hpp | 2 +- src/converter/registry.cpp | 14 ++- src/object/class.cpp | 10 +- test/data_members.cpp | 29 +++++ test/destroy_test.cpp | 30 ------ test/enum.cpp | 7 ++ test/long.cpp | 11 ++ test/long.py | 2 + test/virtual_functions.cpp | 9 ++ test/virtual_functions.py | 7 +- 25 files changed, 302 insertions(+), 171 deletions(-) create mode 100755 include/boost/python/object/inheritance_query.hpp diff --git a/include/boost/python/detail/cv_category.hpp b/include/boost/python/detail/cv_category.hpp index f4ac4b92..e8c91d07 100644 --- a/include/boost/python/detail/cv_category.hpp +++ b/include/boost/python/detail/cv_category.hpp @@ -24,9 +24,12 @@ typedef cv_tag const_volatile_; template struct cv_category { - BOOST_STATIC_CONSTANT(bool, c = is_const::value); - BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); - typedef cv_tag type; +// BOOST_STATIC_CONSTANT(bool, c = is_const::value); +// BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); + typedef cv_tag< + ::boost::is_const::value + , ::boost::is_volatile::value + > type; }; }}} // namespace boost::python::detail diff --git a/include/boost/python/detail/destroy.hpp b/include/boost/python/detail/destroy.hpp index edbabea3..f134a124 100644 --- a/include/boost/python/detail/destroy.hpp +++ b/include/boost/python/detail/destroy.hpp @@ -6,15 +6,14 @@ #ifndef DESTROY_DWA2002221_HPP # define DESTROY_DWA2002221_HPP -# include -# include +# include namespace boost { namespace python { namespace detail { -template struct value_destroyer; - +template struct value_destroyer; + template <> -struct value_destroyer +struct value_destroyer { template static void execute(T const volatile* p) @@ -24,16 +23,17 @@ struct value_destroyer }; template <> -struct value_destroyer +struct value_destroyer { template static void execute(A*, T const volatile* const first) { for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p) + { value_destroyer< boost::is_array::value - ,boost::has_trivial_destructor::value - >::execute(p); + >::execute(p); + } } template @@ -43,24 +43,6 @@ struct value_destroyer } }; -template <> -struct value_destroyer -{ - template - static void execute(T const volatile*) - { - } -}; - -template <> -struct value_destroyer -{ - template - static void execute(T const volatile*) - { - } -}; - template inline void destroy_referent_impl(void* p, T& (*)()) { @@ -68,8 +50,7 @@ inline void destroy_referent_impl(void* p, T& (*)()) // must come *before* T for metrowerks value_destroyer< (boost::is_array::value) - ,(boost::has_trivial_destructor::value) - >::execute((const volatile T*)p); + >::execute((const volatile T*)p); } template diff --git a/include/boost/python/detail/make_keyword_range_fn.hpp b/include/boost/python/detail/make_keyword_range_fn.hpp index 9c749292..27de203a 100644 --- a/include/boost/python/detail/make_keyword_range_fn.hpp +++ b/include/boost/python/detail/make_keyword_range_fn.hpp @@ -34,17 +34,15 @@ object make_keyword_range_function(F f, Policies const& policies, keyword_range // constructor. // // Holder and ArgList are intended to be explicitly specified. -template +template object make_keyword_range_constructor( CallPolicies const& policies // The CallPolicies with which to invoke the Holder's constructor , detail::keyword_range const& kw // The (possibly empty) set of associated argument keywords , Holder* = 0 - , ArgList* = 0) + , ArgList* = 0, Arity* = 0) { - BOOST_STATIC_CONSTANT(unsigned, arity = mpl::size::value); - return detail::make_keyword_range_function( - objects::make_holder + objects::make_holder ::template apply::execute , policies , kw); diff --git a/include/boost/python/detail/referent_storage.hpp b/include/boost/python/detail/referent_storage.hpp index b93d888f..3d9540ee 100644 --- a/include/boost/python/detail/referent_storage.hpp +++ b/include/boost/python/detail/referent_storage.hpp @@ -67,7 +67,9 @@ union aligned_storage template struct referent_storage { - typedef aligned_storage::value> type; + typedef aligned_storage< + ::boost::python::detail::referent_size::value + > type; }; }}} // namespace boost::python::detail diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index e902a40f..b9cf4a43 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -14,6 +14,7 @@ # include # include +# include # include @@ -58,11 +59,15 @@ struct register_base_of register_conversion(false); // Register the down-cast, if appropriate. - mpl::if_c< - is_polymorphic::value - , register_downcast - , do_nothing - >::type::execute(); + mpl::if_< +# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + mpl::true_ +# else + is_polymorphic +# endif + , register_downcast + , do_nothing + >::type::execute(); } }; diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp index 789dfd23..17760608 100644 --- a/include/boost/python/object/forward.hpp +++ b/include/boost/python/object/forward.hpp @@ -7,10 +7,9 @@ # define FORWARD_DWA20011215_HPP # include -# include -# include -# include +# include # include +# include # include namespace boost { namespace python { namespace objects { @@ -24,7 +23,7 @@ struct reference_to_value typedef typename add_reference::type>::type reference; reference_to_value(reference x) : m_value(x) {} - operator reference() const { return m_value; } + reference get() const { return m_value; } private: reference m_value; }; @@ -34,27 +33,43 @@ struct reference_to_value // is T. template struct forward - : mpl::if_c< - is_scalar::value + : mpl::if_< + is_scalar , T - , reference_to_value > + , reference_to_value + > { }; # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template -class unforward +struct unforward { - public: typedef typename unwrap_reference::type& type; }; template -class unforward > +struct unforward > { - public: typedef T type; }; + +template +struct unforward_cref + : add_reference< + typename add_const< + typename unwrap_reference::type + >::type + > +{ +}; + +template +struct unforward_cref > + : add_reference::type> +{ +}; + # else // no partial specialization namespace detail @@ -87,26 +102,81 @@ namespace detail }; }; - template - class is_reference_to_value + template + struct cref_unforwarder + { + template + struct apply + : add_reference< + typename add_const< + typename unwrap_reference::type + >::type + > + { + }; + }; + + template<> + struct cref_unforwarder + { + template + struct apply + : add_reference< + typename add_const< + typename T::reference + >::type + > + { + }; + }; + + template + struct is_reference_to_value { - public: BOOST_STATIC_CONSTANT( bool, value = ( sizeof(is_reference_to_value_test(boost::type())) == sizeof(yes_reference_to_value_t))); + typedef mpl::bool_ type; }; } template -class unforward +struct unforward : public detail::unforwarder< detail::is_reference_to_value::value >::template apply {}; +template +struct unforward_cref + : public detail::cref_unforwarder< + detail::is_reference_to_value::value + >::template apply +{}; + # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +typename reference_to_value::reference +do_unforward(reference_to_value const& x, int) +{ + return x.get(); +} + +template +typename reference_wrapper::type& +do_unforward(reference_wrapper const& x, int) +{ + return x.get(); +} + +template +T const& do_unforward(T const& x, ...) +{ + return x; +} + }}} // namespace boost::python::objects #endif // FORWARD_DWA20011215_HPP diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp index 610f458c..dc97b9c9 100644 --- a/include/boost/python/object/inheritance.hpp +++ b/include/boost/python/object/inheritance.hpp @@ -26,11 +26,7 @@ BOOST_PYTHON_DECL void register_dynamic_id_aux( class_id static_id, dynamic_id_function get_dynamic_id); BOOST_PYTHON_DECL void add_cast( - class_id src_t, class_id dst_t, void* (*cast)(void*), bool polymorphic); - -BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src, class_id dst); - -BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src, class_id dst); + class_id src_t, class_id dst_t, void* (*cast)(void*), bool is_downcast); // // a generator with an execute() function which, given a source type @@ -62,12 +58,12 @@ struct non_polymorphic_id_generator // Now the generalized selector template struct dynamic_id_generator -{ - typedef typename mpl::if_c< - is_polymorphic::value - , polymorphic_id_generator - , non_polymorphic_id_generator >::type type; -}; + : mpl::if_< + boost::is_polymorphic + , boost::python::objects::polymorphic_id_generator + , boost::python::objects::non_polymorphic_id_generator + > +{}; // Register the dynamic id function for T with the type-conversion // system. @@ -108,45 +104,28 @@ struct implicit_cast_generator template struct cast_generator + : mpl::if_< + is_base_and_derived + , implicit_cast_generator + , dynamic_cast_generator + > { - // It's OK to return false, since we can always cast up with - // dynamic_cast<> if neccessary. -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - BOOST_STATIC_CONSTANT(bool, is_upcast = false); -# else - BOOST_STATIC_CONSTANT( - bool, is_upcast = ( - is_base_and_derived::value - )); -# endif - - typedef typename mpl::if_c< - is_upcast -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - // grab a few more implicit_cast cases for CodeWarrior - || !is_polymorphic::value - || !is_polymorphic::value -# endif - , implicit_cast_generator - , dynamic_cast_generator - >::type type; }; template inline void register_conversion( - // We need this parameter because CWPro7 can't determine - // which is the base reliably. - bool is_downcast = !cast_generator::is_upcast - - // These parameters shouldn't be used, they're an MSVC bug workaround + bool is_downcast = ::boost::is_base_and_derived::value + // These parameters shouldn't be used; they're an MSVC bug workaround , Source* = 0, Target* = 0) { typedef typename cast_generator::type generator; - - add_cast(python::type_id() - , python::type_id() - , &generator::execute - , is_downcast); + + add_cast( + python::type_id() + , python::type_id() + , &generator::execute + , is_downcast + ); } }}} // namespace boost::python::object diff --git a/include/boost/python/object/inheritance_query.hpp b/include/boost/python/object/inheritance_query.hpp new file mode 100755 index 00000000..de476f2d --- /dev/null +++ b/include/boost/python/object/inheritance_query.hpp @@ -0,0 +1,18 @@ +// Copyright David Abrahams 2003. 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 INHERITANCE_QUERY_DWA2003520_HPP +# define INHERITANCE_QUERY_DWA2003520_HPP + +# include + +namespace boost { namespace python { namespace objects { + +BOOST_PYTHON_DECL void* find_static_type(void* p, type_info src, type_info dst); +BOOST_PYTHON_DECL void* find_dynamic_type(void* p, type_info src, type_info dst); + +}}} // namespace boost::python::object + +#endif // INHERITANCE_QUERY_DWA2003520_HPP diff --git a/include/boost/python/object/instance.hpp b/include/boost/python/object/instance.hpp index b258a2a0..4f047f50 100644 --- a/include/boost/python/object/instance.hpp +++ b/include/boost/python/object/instance.hpp @@ -26,8 +26,9 @@ struct instance PyObject* weakrefs; instance_holder* objects; - BOOST_STATIC_CONSTANT(std::size_t, alignment = alignment_of::value); - typedef typename type_with_alignment::type align_t; + typedef typename type_with_alignment< + ::boost::alignment_of::value + >::type align_t; union { diff --git a/include/boost/python/object/make_ptr_instance.hpp b/include/boost/python/object/make_ptr_instance.hpp index 54d3e4d5..9bc9e86b 100644 --- a/include/boost/python/object/make_ptr_instance.hpp +++ b/include/boost/python/object/make_ptr_instance.hpp @@ -37,7 +37,9 @@ struct make_ptr_instance if (p == 0) return 0; - PyTypeObject* derived = get_derived_class_object(is_polymorphic::type(), p); + PyTypeObject* derived = get_derived_class_object( + BOOST_DEDUCED_TYPENAME is_polymorphic::type(), p); + if (derived) return derived; return converter::registered::converters.get_class_object(); diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 4400abe6..cc114925 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -13,7 +13,7 @@ # include # include -# include +# include # include # include # include @@ -43,7 +43,11 @@ bool is_null(T* p, int) return p == 0; } -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) +# if BOOST_WORKAROUND(__GNUC__, == 2) +# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)objects::do_unforward(a##n,0) +# else +# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0) +# endif template struct pointer_holder : instance_holder diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 6ae3ae75..c83bb9c7 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -14,7 +14,7 @@ # include # include -# include +# include # include # include @@ -31,7 +31,11 @@ namespace boost { namespace python { namespace objects { -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) +# if BOOST_WORKAROUND(__GNUC__, == 2) +# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)objects::do_unforward(a##n,0) +# else +# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0) +# endif template struct value_holder : instance_holder diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 4727edba..7efc5471 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -12,12 +12,15 @@ # include # include # include -# include # include # include # include + +# include # include +# include + # include # include @@ -81,7 +84,7 @@ namespace api }; # endif - template struct object_initializer; + template struct object_initializer; class object; typedef PyObject* (object::*bool_type)() const; @@ -211,19 +214,35 @@ namespace api public: // default constructor creates a None object object(); + // explicit conversion from any C++ object to Python template explicit object(T const& x) - : object_base( - object_initializer< - is_proxy::value - , converter::is_object_manager::value - >::get(&x, detail::convertible::check(&x))) + : object_base( + object_initializer< + BOOST_DEDUCED_TYPENAME unwrap_reference::type + >::get( + do_unforward(x) + , detail::convertible::check( + to_ptr( + do_unforward(x) + ) + ) + )) { } // Throw error_already_set() if the handle is null. BOOST_PYTHON_DECL explicit object(handle<> const&); + private: + template + static T const* to_ptr(T const&) { return 0; } + + template + typename objects::unforward_cref::type do_unforward(T const& x) + { + return x; + } public: // implementation detail -- for internal use only explicit object(detail::borrowed_reference); @@ -264,47 +283,55 @@ namespace api // based on whether T is a proxy or derived from object // template - struct object_initializer + struct object_initializer_impl { static PyObject* - get(object const* x, detail::yes_convertible) + get(object const& x, detail::yes_convertible) { - return python::incref(x->ptr()); + return python::incref(x.ptr()); } template static PyObject* - get(T const* x, detail::no_convertible) + get(T const& x, detail::no_convertible) { - return python::incref(converter::arg_to_python(*x).get()); + return python::incref(converter::arg_to_python(x).get()); } }; template <> - struct object_initializer + struct object_initializer_impl { template static PyObject* - get(proxy const* x, detail::no_convertible) + get(proxy const& x, detail::no_convertible) { - return python::incref(x->operator object().ptr()); + return python::incref(x.operator object().ptr()); } }; template <> - struct object_initializer + struct object_initializer_impl { template static PyObject* - get(T const* x, ...) + get(T const& x, ...) { - return python::incref(get_managed_object(*x, tag)); + return python::incref(get_managed_object(x, tag)); } }; template <> - struct object_initializer + struct object_initializer_impl {}; // empty implementation should cause an error + + template + struct object_initializer : object_initializer_impl< + is_proxy::value + , converter::is_object_manager::value + > + {}; + } using api::object; template struct extract; diff --git a/include/boost/python/pointee.hpp b/include/boost/python/pointee.hpp index d62bab54..ca8293ad 100644 --- a/include/boost/python/pointee.hpp +++ b/include/boost/python/pointee.hpp @@ -31,7 +31,9 @@ namespace detail template struct pointee - : detail::pointee_impl::value>::template apply + : detail::pointee_impl< + ::boost::is_pointer::value + >::template apply { }; diff --git a/include/boost/python/self.hpp b/include/boost/python/self.hpp index c7d3f670..ff8d2f8d 100755 --- a/include/boost/python/self.hpp +++ b/include/boost/python/self.hpp @@ -10,9 +10,7 @@ namespace boost { namespace python { -//# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 -# define BOOST_PYTHON_SELF_IS_CLASS -//# endif +#define BOOST_PYTHON_SELF_IS_CLASS // Sink self_t into its own namespace so that we have a safe place to // put the completely general operator templates which operate on diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 5b0f6026..9e66ca4a 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -27,7 +27,7 @@ # include # define BOOST_PYTHON_LIST_INC(n) \ - BOOST_PP_CAT(mpl::list, BOOST_PP_INC(n)) + BOOST_PP_CAT(mpl::vector, BOOST_PP_INC(n)) /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { namespace detail { diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index b4891941..2b523cdc 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -92,10 +92,16 @@ namespace // std::cout << "looking up " << type << (p == entries().end() || p->target_type != type ? "...NOT found\n" : "...found\n"); -# endif - return const_cast( - &*entries().insert(entry(type)).first - ); +# endif + std::pair pos_ins + = entries().insert(entry(type)); + +# if __MWERKS__ >= 0x3000 + // do a little invariant checking if a change was made + if ( pos_ins.second ) + assert(entries().invariants()); +# endif + return const_cast(&*pos_ins.first); } } // namespace diff --git a/src/object/class.cpp b/src/object/class.cpp index 637467eb..a936cc11 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -437,7 +437,7 @@ namespace objects { // Find a registered class object corresponding to id. Return a // null handle if no such class is registered. - inline type_handle query_class(class_id id) + inline type_handle query_class(type_info id) { converter::registration const* p = converter::registry::query(id); return type_handle( @@ -448,7 +448,7 @@ namespace objects // Find a registered class corresponding to id. If not found, // throw an appropriate exception. - type_handle get_class(class_id id) + type_handle get_class(type_info id) { type_handle result(query_class(id)); @@ -473,7 +473,7 @@ namespace objects // rest corresponding to its declared bases. // inline object - new_class(char const* name, std::size_t num_types, class_id const* const types, char const* doc) + new_class(char const* name, std::size_t num_types, type_info const* const types, char const* doc) { assert(num_types >= 1); @@ -510,7 +510,7 @@ namespace objects } class_base::class_base( - char const* name, std::size_t num_types, class_id const* const types, char const* doc) + char const* name, std::size_t num_types, type_info const* const types, char const* doc) : object(new_class(name, num_types, types, doc)) { // Insert the new class object in the registry @@ -630,7 +630,7 @@ namespace objects )); } - BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) + BOOST_PYTHON_DECL type_handle registered_class_object(type_info id) { return query_class(id); } diff --git a/test/data_members.cpp b/test/data_members.cpp index 51765174..2b349e4d 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -51,6 +51,35 @@ struct Var : VarBase int Var::static1 = 0; Y Var::static2(0); +// Compilability regression tests +namespace +{ + struct trivial + { + trivial() : value(123) {} + double value; + }; + + struct Color3 + { + static const Color3 black; + }; + + const Color3 Color3::black; + + void compilability_test() + { + class_("trivial") + .add_property("property", make_getter(&trivial::value, return_value_policy())) + .def_readonly("readonly", &trivial::value) + ; + + class_< Color3 >("Color3", init< const Color3 & >()) + .def_readonly("BLACK", &Color3::black) // line 17 + ; + } +} + BOOST_PYTHON_MODULE(data_members_ext) { class_("X", init()) diff --git a/test/destroy_test.cpp b/test/destroy_test.cpp index 38d5d1d5..eaf121aa 100644 --- a/test/destroy_test.cpp +++ b/test/destroy_test.cpp @@ -1,19 +1,6 @@ #include #include -struct bar; - -namespace boost -{ - // lie to the library about bar so we can show that its destructor is optimized away. - template <> - struct has_trivial_destructor - { - BOOST_STATIC_CONSTANT(bool, value=true); - }; -} - - int count; int marks[] = { -1 @@ -33,8 +20,6 @@ struct foo int n; }; -struct bar : foo {}; - void assert_destructions(int n) { for (int i = 0; i < n; ++i) @@ -62,20 +47,5 @@ int main() boost::python::detail::destroy_referent(f3); assert_destructions(7); - bar* b1 = new bar; - boost::python::detail::destroy_referent(b1); - assert_destructions(7); - - bar* b2 = new bar[2]; - typedef bar xb[2]; - - boost::python::detail::destroy_referent(b2); - assert_destructions(7); - - typedef bar yb[2][2]; - xb* b3 = new yb; - boost::python::detail::destroy_referent(b3); - assert_destructions(7); - return 0; } diff --git a/test/enum.cpp b/test/enum.cpp index 1a4f178b..9569e3b3 100644 --- a/test/enum.cpp +++ b/test/enum.cpp @@ -40,9 +40,16 @@ BOOST_PYTHON_MODULE(enum_ext) def("identity", identity_); +#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) + color colorized::*px = &colorized::x; + class_("colorized") + .def_readwrite("x", px) + ; +#else class_("colorized") .def_readwrite("x", &colorized::x) ; +#endif } #include "module_tail.cpp" diff --git a/test/long.cpp b/test/long.cpp index cc619987..1fb96e50 100644 --- a/test/long.cpp +++ b/test/long.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include using namespace boost::python; @@ -39,6 +40,14 @@ int is_long2(char const*) return 0; } +// tests for accepting objects (and derived classes) in constructors +// from "Milind Patil" + +struct Y +{ + Y(boost::python::long_) {} +}; + BOOST_PYTHON_MODULE(long_ext) { def("new_long", new_long); @@ -46,6 +55,8 @@ BOOST_PYTHON_MODULE(long_ext) def("longify_string", longify_string); def("is_long", is_long1); def("is_long", is_long2); + + class_< Y >("Y", init< boost::python::long_ >()) ; } diff --git a/test/long.py b/test/long.py index 7d08e9b7..61c75d89 100644 --- a/test/long.py +++ b/test/long.py @@ -10,6 +10,8 @@ 'yes' >>> is_long('20') 0 + +>>> x = Y(4294967295) ''' def run(args = None): diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index 4fa6c7ee..3e26708d 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,8 @@ struct abstract : X abstract(int x) : X(x) {}; int call_f(Y const& y) { return f(y); } virtual int f(Y const& y) = 0; + abstract& call_g(Y const& y) { return g(y); } + virtual abstract& g(Y const& y) = 0; }; struct concrete : X @@ -59,6 +62,11 @@ struct abstract_callback : abstract return call_method(self, "f", boost::ref(y)); } + abstract& g(Y const& y) + { + return call_method(self, "g", boost::ref(y)); + } + PyObject* self; }; @@ -101,6 +109,7 @@ BOOST_PYTHON_MODULE(virtual_functions_ext) .def("value", &abstract::value) .def("call_f", &abstract::call_f) + .def("call_g", &abstract::call_g, return_internal_reference<>()) .def("set", &abstract::set) ; diff --git a/test/virtual_functions.py b/test/virtual_functions.py index 9b074b1a..f152a446 100644 --- a/test/virtual_functions.py +++ b/test/virtual_functions.py @@ -11,6 +11,8 @@ >>> class A1(abstract): ... def f(self, y): ... return y.value() * 2 +... def g(self, y): +... return self >>> class A2(abstract): ... pass @@ -22,15 +24,16 @@ # -# Test abstract with f overridden +# Test abstract with f,g overridden # >>> a1 = A1(42) >>> a1.value() 42 -# Call f indirectly from C++ +# Call f,g indirectly from C++ >>> a1.call_f(y1) 32 +>>> assert type(a1.call_g(y1)) is abstract # Call f directly from Python >>> a1.f(y2)