1 /////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2007-2008
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 // See http://www.boost.org/libs/intrusive for documentation.
11 /////////////////////////////////////////////////////////////////////////////
12 #ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP
13 #define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP
15 #include <boost/intrusive/detail/config_begin.hpp>
18 #if defined(BOOST_MSVC) || ((defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && defined(BOOST_INTEL))
20 #define BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER
21 #include <boost/cstdint.hpp>
28 template<class Parent
, class Member
>
29 inline std::ptrdiff_t offset_from_pointer_to_member(const Member
Parent::* ptr_to_member
)
31 //The implementation of a pointer to member is compiler dependent.
32 #if defined(BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER)
33 //msvc compliant compilers use their the first 32 bits as offset (even in 64 bit mode)
34 return *(const boost::int32_t*)(void*)&ptr_to_member
;
35 //This works with gcc, msvc, ac++, ibmcpp
36 #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \
37 defined(__IBMCPP__) || defined(__DECCXX)
38 const Parent
* const parent
= 0;
39 const char *const member
= reinterpret_cast<const char*>(&(parent
->*ptr_to_member
));
40 return std::ptrdiff_t(member
- reinterpret_cast<const char*>(parent
));
42 //This is the traditional C-front approach: __MWERKS__, __DMC__, __SUNPRO_CC
43 return (*(const std::ptrdiff_t*)(void*)&ptr_to_member
) - 1;
47 template<class Parent
, class Member
>
48 inline Parent
*parent_from_member(Member
*member
, const Member
Parent::* ptr_to_member
)
50 return (Parent
*)((char*)member
-
51 offset_from_pointer_to_member(ptr_to_member
));
54 template<class Parent
, class Member
>
55 inline const Parent
*parent_from_member(const Member
*member
, const Member
Parent::* ptr_to_member
)
57 return (const Parent
*)((const char*)member
-
58 offset_from_pointer_to_member(ptr_to_member
));
61 } //namespace detail {
62 } //namespace intrusive {
65 #ifdef BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER
66 #undef BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER
69 #include <boost/intrusive/detail/config_end.hpp>
71 #endif //#ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP