1 | // Copyright (C) 2002 Brad King ([email protected]) |
2 | // Douglas Gregor ([email protected]) |
3 | // |
4 | // Copyright (C) 2002, 2008, 2013 Peter Dimov |
5 | // |
6 | // Distributed under the Boost Software License, Version 1.0. (See |
7 | // accompanying file LICENSE_1_0.txt or copy at |
8 | // http://www.boost.org/LICENSE_1_0.txt) |
9 | |
10 | // For more information, see http://www.boost.org |
11 | |
12 | #ifndef BOOST_CORE_ADDRESSOF_HPP |
13 | #define BOOST_CORE_ADDRESSOF_HPP |
14 | |
15 | # include <boost/config.hpp> |
16 | # include <boost/detail/workaround.hpp> |
17 | # include <cstddef> |
18 | |
19 | namespace boost |
20 | { |
21 | |
22 | namespace detail |
23 | { |
24 | |
25 | template<class T> struct addr_impl_ref |
26 | { |
27 | T & v_; |
28 | |
29 | BOOST_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {} |
30 | BOOST_FORCEINLINE operator T& () const { return v_; } |
31 | |
32 | private: |
33 | addr_impl_ref & operator=(const addr_impl_ref &); |
34 | }; |
35 | |
36 | template<class T> struct addressof_impl |
37 | { |
38 | static BOOST_FORCEINLINE T * f( T & v, long ) |
39 | { |
40 | return reinterpret_cast<T*>( |
41 | &const_cast<char&>(reinterpret_cast<const volatile char &>(v))); |
42 | } |
43 | |
44 | static BOOST_FORCEINLINE T * f( T * v, int ) |
45 | { |
46 | return v; |
47 | } |
48 | }; |
49 | |
50 | #if !defined( BOOST_NO_CXX11_NULLPTR ) |
51 | |
52 | #if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) ) |
53 | |
54 | typedef decltype(nullptr) addr_nullptr_t; |
55 | |
56 | #else |
57 | |
58 | typedef std::nullptr_t addr_nullptr_t; |
59 | |
60 | #endif |
61 | |
62 | template<> struct addressof_impl< addr_nullptr_t > |
63 | { |
64 | typedef addr_nullptr_t T; |
65 | |
66 | static BOOST_FORCEINLINE T * f( T & v, int ) |
67 | { |
68 | return &v; |
69 | } |
70 | }; |
71 | |
72 | template<> struct addressof_impl< addr_nullptr_t const > |
73 | { |
74 | typedef addr_nullptr_t const T; |
75 | |
76 | static BOOST_FORCEINLINE T * f( T & v, int ) |
77 | { |
78 | return &v; |
79 | } |
80 | }; |
81 | |
82 | template<> struct addressof_impl< addr_nullptr_t volatile > |
83 | { |
84 | typedef addr_nullptr_t volatile T; |
85 | |
86 | static BOOST_FORCEINLINE T * f( T & v, int ) |
87 | { |
88 | return &v; |
89 | } |
90 | }; |
91 | |
92 | template<> struct addressof_impl< addr_nullptr_t const volatile > |
93 | { |
94 | typedef addr_nullptr_t const volatile T; |
95 | |
96 | static BOOST_FORCEINLINE T * f( T & v, int ) |
97 | { |
98 | return &v; |
99 | } |
100 | }; |
101 | |
102 | #endif |
103 | |
104 | } // namespace detail |
105 | |
106 | template<class T> |
107 | BOOST_FORCEINLINE |
108 | T * addressof( T & v ) |
109 | { |
110 | #if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)) |
111 | |
112 | return boost::detail::addressof_impl<T>::f( v, 0 ); |
113 | |
114 | #else |
115 | |
116 | return boost::detail::addressof_impl<T>::f( boost::detail::addr_impl_ref<T>( v ), 0 ); |
117 | |
118 | #endif |
119 | } |
120 | |
121 | #if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) ) |
122 | |
123 | namespace detail |
124 | { |
125 | |
126 | template<class T> struct addressof_addp |
127 | { |
128 | typedef T * type; |
129 | }; |
130 | |
131 | } // namespace detail |
132 | |
133 | template< class T, std::size_t N > |
134 | BOOST_FORCEINLINE |
135 | typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] ) |
136 | { |
137 | return &t; |
138 | } |
139 | |
140 | #endif |
141 | |
142 | // Borland doesn't like casting an array reference to a char reference |
143 | // but these overloads work around the problem. |
144 | #if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
145 | template<typename T,std::size_t N> |
146 | BOOST_FORCEINLINE |
147 | T (*addressof(T (&t)[N]))[N] |
148 | { |
149 | return reinterpret_cast<T(*)[N]>(&t); |
150 | } |
151 | |
152 | template<typename T,std::size_t N> |
153 | BOOST_FORCEINLINE |
154 | const T (*addressof(const T (&t)[N]))[N] |
155 | { |
156 | return reinterpret_cast<const T(*)[N]>(&t); |
157 | } |
158 | #endif |
159 | |
160 | } // namespace boost |
161 | |
162 | #endif // BOOST_CORE_ADDRESSOF_HPP |
163 | |