1 | #ifndef BOOST_CORE_REF_HPP |
2 | #define BOOST_CORE_REF_HPP |
3 | |
4 | // MS compatible compilers support #pragma once |
5 | |
6 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
7 | # pragma once |
8 | #endif |
9 | |
10 | #include <boost/config.hpp> |
11 | #include <boost/utility/addressof.hpp> |
12 | #include <boost/detail/workaround.hpp> |
13 | |
14 | // |
15 | // ref.hpp - ref/cref, useful helper functions |
16 | // |
17 | // Copyright (C) 1999, 2000 Jaakko Jarvi ([email protected]) |
18 | // Copyright (C) 2001, 2002 Peter Dimov |
19 | // Copyright (C) 2002 David Abrahams |
20 | // |
21 | // Copyright (C) 2014 Glen Joseph Fernandes |
22 | // glenfe at live dot com |
23 | // Copyright (C) 2014 Agustin Berge |
24 | // |
25 | // Distributed under the Boost Software License, Version 1.0. (See |
26 | // accompanying file LICENSE_1_0.txt or copy at |
27 | // http://www.boost.org/LICENSE_1_0.txt) |
28 | // |
29 | // See http://www.boost.org/libs/core/doc/html/core/ref.html for documentation. |
30 | // |
31 | |
32 | /** |
33 | @file |
34 | */ |
35 | |
36 | /** |
37 | Boost namespace. |
38 | */ |
39 | namespace boost |
40 | { |
41 | |
42 | #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) |
43 | |
44 | struct ref_workaround_tag {}; |
45 | |
46 | #endif |
47 | |
48 | // reference_wrapper |
49 | |
50 | /** |
51 | @brief Contains a reference to an object of type `T`. |
52 | |
53 | `reference_wrapper` is primarily used to "feed" references to |
54 | function templates (algorithms) that take their parameter by |
55 | value. It provides an implicit conversion to `T&`, which |
56 | usually allows the function templates to work on references |
57 | unmodified. |
58 | */ |
59 | template<class T> class reference_wrapper |
60 | { |
61 | public: |
62 | /** |
63 | Type `T`. |
64 | */ |
65 | typedef T type; |
66 | |
67 | /** |
68 | Constructs a `reference_wrapper` object that stores a |
69 | reference to `t`. |
70 | |
71 | @remark Does not throw. |
72 | */ |
73 | BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} |
74 | |
75 | #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) |
76 | |
77 | BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {} |
78 | |
79 | #endif |
80 | |
81 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
82 | /** |
83 | @remark Construction from a temporary object is disabled. |
84 | */ |
85 | BOOST_DELETED_FUNCTION(reference_wrapper(T&& t)) |
86 | public: |
87 | #endif |
88 | |
89 | /** |
90 | @return The stored reference. |
91 | @remark Does not throw. |
92 | */ |
93 | BOOST_FORCEINLINE operator T& () const { return *t_; } |
94 | |
95 | /** |
96 | @return The stored reference. |
97 | @remark Does not throw. |
98 | */ |
99 | BOOST_FORCEINLINE T& get() const { return *t_; } |
100 | |
101 | /** |
102 | @return A pointer to the object referenced by the stored |
103 | reference. |
104 | @remark Does not throw. |
105 | */ |
106 | BOOST_FORCEINLINE T* get_pointer() const { return t_; } |
107 | |
108 | private: |
109 | |
110 | T* t_; |
111 | }; |
112 | |
113 | // ref |
114 | |
115 | /** |
116 | @cond |
117 | */ |
118 | #if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) |
119 | # define BOOST_REF_CONST |
120 | #else |
121 | # define BOOST_REF_CONST const |
122 | #endif |
123 | /** |
124 | @endcond |
125 | */ |
126 | |
127 | /** |
128 | @return `reference_wrapper<T>(t)` |
129 | @remark Does not throw. |
130 | */ |
131 | template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t ) |
132 | { |
133 | #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) |
134 | |
135 | return reference_wrapper<T>( t, ref_workaround_tag() ); |
136 | |
137 | #else |
138 | |
139 | return reference_wrapper<T>( t ); |
140 | |
141 | #endif |
142 | } |
143 | |
144 | // cref |
145 | |
146 | /** |
147 | @return `reference_wrapper<T const>(t)` |
148 | @remark Does not throw. |
149 | */ |
150 | template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t ) |
151 | { |
152 | return reference_wrapper<T const>(t); |
153 | } |
154 | |
155 | #undef BOOST_REF_CONST |
156 | |
157 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
158 | |
159 | /** |
160 | @cond |
161 | */ |
162 | #if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) |
163 | # define BOOST_REF_DELETE |
164 | #else |
165 | # define BOOST_REF_DELETE = delete |
166 | #endif |
167 | /** |
168 | @endcond |
169 | */ |
170 | |
171 | /** |
172 | @remark Construction from a temporary object is disabled. |
173 | */ |
174 | template<class T> void ref(T const&&) BOOST_REF_DELETE; |
175 | |
176 | /** |
177 | @remark Construction from a temporary object is disabled. |
178 | */ |
179 | template<class T> void cref(T const&&) BOOST_REF_DELETE; |
180 | |
181 | #undef BOOST_REF_DELETE |
182 | |
183 | #endif |
184 | |
185 | // is_reference_wrapper |
186 | |
187 | /** |
188 | @brief Determine if a type `T` is an instantiation of |
189 | `reference_wrapper`. |
190 | |
191 | The value static constant will be true if the type `T` is a |
192 | specialization of `reference_wrapper`. |
193 | */ |
194 | template<typename T> struct is_reference_wrapper |
195 | { |
196 | BOOST_STATIC_CONSTANT( bool, value = false ); |
197 | }; |
198 | |
199 | /** |
200 | @cond |
201 | */ |
202 | template<typename T> struct is_reference_wrapper< reference_wrapper<T> > |
203 | { |
204 | BOOST_STATIC_CONSTANT( bool, value = true ); |
205 | }; |
206 | |
207 | #if !defined(BOOST_NO_CV_SPECIALIZATIONS) |
208 | |
209 | template<typename T> struct is_reference_wrapper< reference_wrapper<T> const > |
210 | { |
211 | BOOST_STATIC_CONSTANT( bool, value = true ); |
212 | }; |
213 | |
214 | template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile > |
215 | { |
216 | BOOST_STATIC_CONSTANT( bool, value = true ); |
217 | }; |
218 | |
219 | template<typename T> struct is_reference_wrapper< reference_wrapper<T> const volatile > |
220 | { |
221 | BOOST_STATIC_CONSTANT( bool, value = true ); |
222 | }; |
223 | |
224 | #endif // !defined(BOOST_NO_CV_SPECIALIZATIONS) |
225 | |
226 | /** |
227 | @endcond |
228 | */ |
229 | |
230 | |
231 | // unwrap_reference |
232 | |
233 | /** |
234 | @brief Find the type in a `reference_wrapper`. |
235 | |
236 | The `typedef` type is `T::type` if `T` is a |
237 | `reference_wrapper`, `T` otherwise. |
238 | */ |
239 | template<typename T> struct unwrap_reference |
240 | { |
241 | typedef T type; |
242 | }; |
243 | |
244 | /** |
245 | @cond |
246 | */ |
247 | template<typename T> struct unwrap_reference< reference_wrapper<T> > |
248 | { |
249 | typedef T type; |
250 | }; |
251 | |
252 | #if !defined(BOOST_NO_CV_SPECIALIZATIONS) |
253 | |
254 | template<typename T> struct unwrap_reference< reference_wrapper<T> const > |
255 | { |
256 | typedef T type; |
257 | }; |
258 | |
259 | template<typename T> struct unwrap_reference< reference_wrapper<T> volatile > |
260 | { |
261 | typedef T type; |
262 | }; |
263 | |
264 | template<typename T> struct unwrap_reference< reference_wrapper<T> const volatile > |
265 | { |
266 | typedef T type; |
267 | }; |
268 | |
269 | #endif // !defined(BOOST_NO_CV_SPECIALIZATIONS) |
270 | |
271 | /** |
272 | @endcond |
273 | */ |
274 | |
275 | // unwrap_ref |
276 | |
277 | /** |
278 | @return `unwrap_reference<T>::type&(t)` |
279 | @remark Does not throw. |
280 | */ |
281 | template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t ) |
282 | { |
283 | return t; |
284 | } |
285 | |
286 | // get_pointer |
287 | |
288 | /** |
289 | @cond |
290 | */ |
291 | template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r ) |
292 | { |
293 | return r.get_pointer(); |
294 | } |
295 | /** |
296 | @endcond |
297 | */ |
298 | |
299 | } // namespace boost |
300 | |
301 | #endif // #ifndef BOOST_CORE_REF_HPP |
302 | |