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