diff options
Diffstat (limited to 'boost/intrusive/detail/parent_from_member.hpp')
-rw-r--r-- | boost/intrusive/detail/parent_from_member.hpp | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/boost/intrusive/detail/parent_from_member.hpp b/boost/intrusive/detail/parent_from_member.hpp index c06d932a70..2afffb47bc 100644 --- a/boost/intrusive/detail/parent_from_member.hpp +++ b/boost/intrusive/detail/parent_from_member.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2009 +// (C) Copyright Ion Gaztanaga 2007-2012 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -31,29 +31,53 @@ inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_t //The implementation of a pointer to member is compiler dependent. #if defined(BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER) //msvc compliant compilers use their the first 32 bits as offset (even in 64 bit mode) - return *(const boost::int32_t*)(void*)&ptr_to_member; + union caster_union + { + const Member Parent::* ptr_to_member; + boost::int32_t offset; + } caster; + caster.ptr_to_member = ptr_to_member; + return std::ptrdiff_t(caster.offset); //This works with gcc, msvc, ac++, ibmcpp #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \ defined(__IBMCPP__) || defined(__DECCXX) const Parent * const parent = 0; - const char *const member = reinterpret_cast<const char*>(&(parent->*ptr_to_member)); - return std::ptrdiff_t(member - reinterpret_cast<const char*>(parent)); + const char *const member = static_cast<const char*>(static_cast<const void*>(&(parent->*ptr_to_member))); + return std::ptrdiff_t(member - static_cast<const char*>(static_cast<const void*>(parent))); #else //This is the traditional C-front approach: __MWERKS__, __DMC__, __SUNPRO_CC - return (*(const std::ptrdiff_t*)(void*)&ptr_to_member) - 1; + union caster_union + { + const Member Parent::* ptr_to_member; + std::ptrdiff_t offset; + } caster; + caster.ptr_to_member = ptr_to_member; + return caster.offset - 1; #endif } template<class Parent, class Member> inline Parent *parent_from_member(Member *member, const Member Parent::* ptr_to_member) { - return (Parent*)((char*)member - offset_from_pointer_to_member(ptr_to_member)); + return static_cast<Parent*> + ( + static_cast<void*> + ( + static_cast<char*>(static_cast<void*>(member)) - offset_from_pointer_to_member(ptr_to_member) + ) + ); } template<class Parent, class Member> inline const Parent *parent_from_member(const Member *member, const Member Parent::* ptr_to_member) { - return (const Parent*)((const char*)member - offset_from_pointer_to_member(ptr_to_member)); + return static_cast<const Parent*> + ( + static_cast<const void*> + ( + static_cast<const char*>(static_cast<const void*>(member)) - offset_from_pointer_to_member(ptr_to_member) + ) + ); } } //namespace detail { |