diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp index c36b9e4..75a1598 100644 --- a/include/boost/function/function_base.hpp +++ b/include/boost/function/function_base.hpp @@ -41,7 +41,7 @@ # pragma warning( push ) # pragma warning( disable : 4793 ) // complaint about native code generation # pragma warning( disable : 4127 ) // "conditional expression is constant" -#endif +#endif #if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG) # define BOOST_FUNCTION_TARGET_FIX(x) x @@ -68,7 +68,8 @@ namespace boost { union function_buffer { // For pointers to function objects - mutable void* obj_ptr; + typedef void* obj_ptr_t; + mutable obj_ptr_t obj_ptr; // For pointers to std::type_info objects struct type_t { @@ -82,7 +83,8 @@ namespace boost { } type; // For function pointers of all kinds - mutable void (*func_ptr)(); + typedef void (*func_ptr_t)(); + mutable func_ptr_t func_ptr; // For bound member pointers struct bound_memfunc_ptr_t { @@ -98,8 +100,16 @@ namespace boost { bool is_volatile_qualified; } obj_ref; + enum { + size1 = sizeof(obj_ptr_t) > sizeof(type_t) ? sizeof(obj_ptr_t) : sizeof(type_t), + size2 = size1 > sizeof(func_ptr_t) ? size1 : sizeof(func_ptr_t), + size3 = size2 > sizeof(bound_memfunc_ptr_t) ? size2 : sizeof(bound_memfunc_ptr_t), + size4 = size3 > sizeof(obj_ref_t) ? size3 : sizeof(obj_ref_t), + data_size = size4 + }; + // To relax aliasing constraints - mutable char data; + mutable char data[data_size]; }; /** @@ -277,28 +287,28 @@ namespace boost { { if (op == clone_functor_tag || op == move_functor_tag) { const functor_type* in_functor = - reinterpret_cast(&in_buffer.data); - new (reinterpret_cast(&out_buffer.data)) functor_type(*in_functor); + reinterpret_cast(in_buffer.data); + new (reinterpret_cast(out_buffer.data)) functor_type(*in_functor); if (op == move_functor_tag) { - functor_type* f = reinterpret_cast(&in_buffer.data); + functor_type* f = reinterpret_cast(in_buffer.data); (void)f; // suppress warning about the value of f not being used (MSVC) f->~Functor(); } } else if (op == destroy_functor_tag) { // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. - functor_type* f = reinterpret_cast(&out_buffer.data); + functor_type* f = reinterpret_cast(out_buffer.data); (void)f; // suppress warning about the value of f not being used (MSVC) f->~Functor(); } else if (op == check_functor_type_tag) { if (*out_buffer.type.type == boost::typeindex::type_id()) - out_buffer.obj_ptr = &in_buffer.data; + out_buffer.obj_ptr = in_buffer.data; else out_buffer.obj_ptr = 0; } else /* op == get_functor_type_tag */ { out_buffer.type.type = &boost::typeindex::type_id().type_info(); out_buffer.type.const_qualified = false; - out_buffer.type.volatile_qualified = false; + out_buffer.type.volatile_qualified = false; } } }; @@ -853,6 +863,6 @@ namespace detail { #if defined(BOOST_MSVC) # pragma warning( pop ) -#endif +#endif #endif // BOOST_FUNCTION_BASE_HEADER diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index 211b81d..b2bb540 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -16,7 +16,7 @@ #if defined(BOOST_MSVC) # pragma warning( push ) # pragma warning( disable : 4127 ) // "conditional expression is constant" -#endif +#endif #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) @@ -132,7 +132,7 @@ namespace boost { { FunctionObj* f; if (function_allows_small_object_optimization::value) - f = reinterpret_cast(&function_obj_ptr.data); + f = reinterpret_cast(function_obj_ptr.data); else f = reinterpret_cast(function_obj_ptr.obj_ptr); return (*f)(BOOST_FUNCTION_ARGS); @@ -153,7 +153,7 @@ namespace boost { { FunctionObj* f; if (function_allows_small_object_optimization::value) - f = reinterpret_cast(&function_obj_ptr.data); + f = reinterpret_cast(function_obj_ptr.data); else f = reinterpret_cast(function_obj_ptr.obj_ptr); BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); @@ -209,7 +209,7 @@ namespace boost { { MemberPtr* f = - reinterpret_cast(&function_obj_ptr.data); + reinterpret_cast(function_obj_ptr.data); return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); } }; @@ -227,7 +227,7 @@ namespace boost { { MemberPtr* f = - reinterpret_cast(&function_obj_ptr.data); + reinterpret_cast(function_obj_ptr.data); BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS)); } }; @@ -569,7 +569,7 @@ namespace boost { void assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const { - new (reinterpret_cast(&functor.data)) FunctionObj(f); + new (reinterpret_cast(functor.data)) FunctionObj(f); } template void @@ -752,14 +752,14 @@ namespace boost { { this->assign_to_own(f); } - + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base() { this->move_assign(f); } #endif - + ~BOOST_FUNCTION_FUNCTION() { clear(); } result_type operator()(BOOST_FUNCTION_PARMS) const @@ -840,12 +840,11 @@ namespace boost { BOOST_CATCH_END return *this; } - + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES // Move assignment from another BOOST_FUNCTION_FUNCTION BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f) { - if (&f == this) return *this; @@ -925,7 +924,7 @@ namespace boost { template apply handler_type; - + typedef typename handler_type::invoker_type invoker_type; typedef typename handler_type::manager_type manager_type; @@ -960,7 +959,7 @@ namespace boost { BOOST_FUNCTION_TEMPLATE_ARGS, Allocator> handler_type; - + typedef typename handler_type::invoker_type invoker_type; typedef typename handler_type::manager_type manager_type; @@ -987,7 +986,7 @@ namespace boost { // has its function object allocated on the heap, move_assign will pass // its buffer to *this, and set the argument's buffer pointer to NULL. void move_assign(BOOST_FUNCTION_FUNCTION& f) - { + { if (&f == this) return; @@ -1098,7 +1097,7 @@ public: function(self_type&& f): base_type(static_cast(f)){} function(base_type&& f): base_type(static_cast(f)){} #endif - + self_type& operator=(const self_type& f) { self_type(f).swap(*this); @@ -1111,7 +1110,7 @@ public: self_type(static_cast(f)).swap(*this); return *this; } -#endif +#endif template #ifndef BOOST_NO_SFINAE @@ -1147,7 +1146,7 @@ public: self_type(static_cast(f)).swap(*this); return *this; } -#endif +#endif }; #undef BOOST_FUNCTION_PARTIAL_SPEC @@ -1187,4 +1186,4 @@ public: #if defined(BOOST_MSVC) # pragma warning( pop ) -#endif +#endif