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