diff --git a/doc/v2/configuration.html b/doc/v2/configuration.html index 0415ca2b..1be862ed 100644 --- a/doc/v2/configuration.html +++ b/doc/v2/configuration.html @@ -106,6 +106,33 @@ function from being treated as an exported symbol on platforms which support that distinction in-code + + + BOOST_PYTHON_ENABLE_CDECL + + not defined + + If defined, allows functions using the __cdecl + calling convention to be wrapped. + + + + BOOST_PYTHON_ENABLE_STDCALL + + not defined + + If defined, allows functions using the __stdcall + calling convention to be wrapped. + + + + BOOST_PYTHON_ENABLE_FASTCALL + + not defined + + If defined, allows functions using the __fastcall + calling convention to be wrapped. +

Library Defined Implementation diff --git a/include/boost/python/object/make_instance.hpp b/include/boost/python/object/make_instance.hpp index 8f355fe2..937c97c2 100644 --- a/include/boost/python/object/make_instance.hpp +++ b/include/boost/python/object/make_instance.hpp @@ -21,7 +21,7 @@ struct make_instance_impl template static inline PyObject* execute(Arg& x) { - BOOST_STATIC_ASSERT(is_class::value); + BOOST_MPL_ASSERT((mpl::or_, is_union >)); PyTypeObject* type = Derived::get_class_object(x); diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 2dc6dda9..4627e34a 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -35,6 +35,8 @@ # include +# include + namespace boost { namespace python { template class wrapper; @@ -122,26 +124,29 @@ inline pointer_holder_back_reference::pointer_holder_back_referen template void* pointer_holder::holds(type_info dst_t, bool null_ptr_only) { + typedef typename boost::remove_const< Value >::type non_const_value; + if (dst_t == python::type_id() && !(null_ptr_only && get_pointer(this->m_p)) ) return &this->m_p; - Value* p + Value* p0 # if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) = static_cast( get_pointer(this->m_p) ) # else = get_pointer(this->m_p) # endif ; - + non_const_value* p = const_cast( p0 ); + if (p == 0) return 0; if (void* wrapped = holds_wrapped(dst_t, p, p)) return wrapped; - type_info src_t = python::type_id(); + type_info src_t = python::type_id(); return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t); } diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 1bb2b226..f1143e3a 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -52,16 +52,23 @@ struct most_derived // // template // inline mpl::vector -// get_signature(RT(*)(T0...TN), void* = 0) +// get_signature(RT(BOOST_PYTHON_FN_CC *)(T0...TN), void* = 0) // { // return mpl::list(); // } // +// where BOOST_PYTHON_FN_CC is a calling convention keyword, can be +// +// empty, for default calling convention +// __cdecl (if BOOST_PYTHON_ENABLE_CDECL is defined) +// __stdcall (if BOOST_PYTHON_ENABLE_STDCALL is defined) +// __fastcall (if BOOST_PYTHON_ENABLE_FASTCALL is defined) +// // And, for an appropriate assortment of cv-qualifications:: // // template // inline mpl::vector -// get_signature(RT(ClassT::*)(T0...TN) cv)) +// get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv)) // { // return mpl::list(); // } @@ -72,7 +79,7 @@ struct most_derived // , typename most_derived::type& // , T0...TN // > -// get_signature(RT(ClassT::*)(T0...TN) cv), Target*) +// get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv), Target*) // { // return mpl::list(); // } @@ -87,7 +94,8 @@ struct most_derived // // These functions extract the return type, class (for member // functions) and arguments of the input signature and stuff them in -// an mpl type sequence. Note that cv-qualification is dropped from +// an mpl type sequence (the calling convention is dropped). +// Note that cv-qualification is dropped from // the "hidden this" argument of member functions; that is a // necessary sacrifice to ensure that an lvalue from_python converter // is used. A pointer is not used so that None will be rejected for @@ -100,10 +108,64 @@ struct most_derived // // @group { +// 'default' calling convention + +# define BOOST_PYTHON_FN_CC + # define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FN_CC + +// __cdecl calling convention + +# if defined(BOOST_PYTHON_ENABLE_CDECL) + +# define BOOST_PYTHON_FN_CC __cdecl +# define BOOST_PYTHON_FN_CC_IS_CDECL + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) + +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FN_CC +# undef BOOST_PYTHON_FN_CC_IS_CDECL + +# endif // defined(BOOST_PYTHON_ENABLE_CDECL) + +// __stdcall calling convention + +# if defined(BOOST_PYTHON_ENABLE_STDCALL) + +# define BOOST_PYTHON_FN_CC __stdcall + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) + +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FN_CC + +# endif // defined(BOOST_PYTHON_ENABLE_STDCALL) + +// __fastcall calling convention + +# if defined(BOOST_PYTHON_ENABLE_FASTCALL) + +# define BOOST_PYTHON_FN_CC __fastcall + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) + +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FN_CC + +# endif // defined(BOOST_PYTHON_ENABLE_FASTCALL) + # undef BOOST_PYTHON_LIST_INC // } @@ -120,17 +182,24 @@ struct most_derived # define N BOOST_PP_ITERATION() + // as 'get_signature(RT(*)(T0...TN), void* = 0)' is the same + // function as 'get_signature(RT(__cdecl *)(T0...TN), void* = 0)', + // we don't define it twice +# if !defined(BOOST_PYTHON_FN_CC_IS_CDECL) + template < class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> inline BOOST_PYTHON_LIST_INC(N)< RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> -get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0) +get_signature(RT(BOOST_PYTHON_FN_CC *)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0) { return BOOST_PYTHON_LIST_INC(N)< RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) >(); } +# endif // !defined(BOOST_PYTHON_FN_CC_IS_CDECL) + # undef N # define BOOST_PP_ITERATION_PARAMS_2 \ @@ -146,7 +215,7 @@ template < class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> -get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) +get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) { return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) @@ -165,7 +234,7 @@ inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) > get_signature( - RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q + RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q , Target* ) { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 764dfa41..1204769e 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -184,6 +184,9 @@ bpl-test crossmod_opaque # bpl-test bienstman5 ; # } +[ bpl-test calling_conventions ] +[ bpl-test calling_conventions_mf ] + # --- unit tests of library components --- [ compile indirect_traits_test.cpp ] @@ -196,6 +199,7 @@ bpl-test crossmod_opaque [ compile string_literal.cpp ] [ py-compile borrowed.cpp ] +[ py-compile union.cpp ] [ py-compile object_manager.cpp ] [ py-compile copy_ctor_mutates_rhs.cpp ]