diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index 57a3d76e..d88eb90e 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -19,6 +19,8 @@ # include # include # include +# else +# include # endif namespace boost { namespace python { namespace converter { @@ -105,24 +107,23 @@ namespace detail bool, choose_t2 = ( aligned2 && ( is_same::value - | (align2 < alignment_of::value) + | (align2 < align1) | (sizeof(T2) < sizeof(T1))) )); - typedef mpl::select_type::type type; + typedef typename mpl::select_type::type type; }; }; typedef mpl::type_list< - char,short,int,long,float,double,long double + char,short,int,long, float,double,long double ,void* ,void(*)() ,void (alignment_dummy::*)() , char (alignment_dummy::*) - > + >::type align_types; -#endif // EDG is too slow - +#endif // EDG is too slow template union aligned_storage { @@ -148,10 +149,27 @@ namespace detail typedef typename loop::state align_t; #else + typedef typename remove_cv::type>::type referent; + // The Python source makes the assumption that double has - // maximal alignment anyway - typedef double align_t; - + // maximal alignment, but that fails on some platforms + BOOST_STATIC_CONSTANT( + std::size_t, target_align = alignment_of::value); + + // Here we make some assumptions and leave out some possible + // types worth checking, but this should work most of the time. + typedef typename mpl::select_type< + is_POD::value + , referent + , typename mpl::select_type< + alignment_of::value >= target_align + , long + , typename mpl::select_type< + alignment_of::value >= target_align + , double + , long double>::type + >::type + >::type align_t; #endif BOOST_STATIC_CONSTANT(std::size_t, alignment1 = alignment_of::value); BOOST_STATIC_CONSTANT(std::size_t, alignment2 = referent_alignment::value);