1#ifndef BOOST_CORE_REF_HPP
2#define BOOST_CORE_REF_HPP
3
4#include <boost/config.hpp>
5#include <boost/config/workaround.hpp>
6#include <boost/core/addressof.hpp>
7#include <boost/core/enable_if.hpp>
8
9#if defined(BOOST_HAS_PRAGMA_ONCE)
10# pragma once
11#endif
12
13//
14// ref.hpp - ref/cref, useful helper functions
15//
16// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
17// Copyright (C) 2001, 2002 Peter Dimov
18// Copyright (C) 2002 David Abrahams
19//
20// Copyright (C) 2014 Glen Joseph Fernandes
21// (glenjofe@gmail.com)
22//
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*/
39namespace boost
40{
41
42#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
43
44 struct ref_workaround_tag {};
45
46#endif
47
48namespace detail
49{
50
51template< class Y, class T > struct ref_convertible
52{
53 typedef char (&yes) [1];
54 typedef char (&no) [2];
55
56 static yes f( T* );
57 static no f( ... );
58
59 enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
60};
61
62#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
63struct ref_empty
64{
65};
66#endif
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*/
81template<class T> class reference_wrapper
82{
83public:
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 */
95 BOOST_FORCEINLINE explicit reference_wrapper(T& t) BOOST_NOEXCEPT : t_(boost::addressof(t)) {}
96
97#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
98
99 BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ) BOOST_NOEXCEPT : 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))
108public:
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 */
120#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
121 template<class Y, class = typename enable_if_c<boost::detail::ref_convertible<Y, T>::value>::type>
122 reference_wrapper( reference_wrapper<Y> r ) BOOST_NOEXCEPT : t_( r.t_ )
123 {
124 }
125#else
126 template<class Y> reference_wrapper( reference_wrapper<Y> r,
127 typename enable_if_c<boost::detail::ref_convertible<Y, T>::value,
128 boost::detail::ref_empty>::type = boost::detail::ref_empty() ) BOOST_NOEXCEPT : t_( r.t_ )
129 {
130 }
131#endif
132
133 /**
134 @return The stored reference.
135 @remark Does not throw.
136 */
137 BOOST_FORCEINLINE operator T& () const BOOST_NOEXCEPT { return *t_; }
138
139 /**
140 @return The stored reference.
141 @remark Does not throw.
142 */
143 BOOST_FORCEINLINE T& get() const BOOST_NOEXCEPT { return *t_; }
144
145 /**
146 @return A pointer to the object referenced by the stored
147 reference.
148 @remark Does not throw.
149 */
150 BOOST_FORCEINLINE T* get_pointer() const BOOST_NOEXCEPT { return t_; }
151
152private:
153
154 T* t_;
155};
156
157// ref
158
159/**
160 @cond
161*/
162#if defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) )
163# define BOOST_REF_CONST
164#else
165# define BOOST_REF_CONST const
166#endif
167/**
168 @endcond
169*/
170
171/**
172 @return `reference_wrapper<T>(t)`
173 @remark Does not throw.
174*/
175template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t ) BOOST_NOEXCEPT
176{
177#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
178
179 return reference_wrapper<T>( t, ref_workaround_tag() );
180
181#else
182
183 return reference_wrapper<T>( t );
184
185#endif
186}
187
188// cref
189
190/**
191 @return `reference_wrapper<T const>(t)`
192 @remark Does not throw.
193*/
194template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t ) BOOST_NOEXCEPT
195{
196 return reference_wrapper<T const>(t);
197}
198
199#undef BOOST_REF_CONST
200
201#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
202
203/**
204 @cond
205*/
206#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
207# define BOOST_REF_DELETE
208#else
209# define BOOST_REF_DELETE = delete
210#endif
211/**
212 @endcond
213*/
214
215/**
216 @remark Construction from a temporary object is disabled.
217*/
218template<class T> void ref(T const&&) BOOST_REF_DELETE;
219
220/**
221 @remark Construction from a temporary object is disabled.
222*/
223template<class T> void cref(T const&&) BOOST_REF_DELETE;
224
225#undef BOOST_REF_DELETE
226
227#endif
228
229// is_reference_wrapper
230
231/**
232 @brief Determine if a type `T` is an instantiation of
233 `reference_wrapper`.
234
235 The value static constant will be true if the type `T` is a
236 specialization of `reference_wrapper`.
237*/
238template<typename T> struct is_reference_wrapper
239{
240 BOOST_STATIC_CONSTANT( bool, value = false );
241};
242
243/**
244 @cond
245*/
246template<typename T> struct is_reference_wrapper< reference_wrapper<T> >
247{
248 BOOST_STATIC_CONSTANT( bool, value = true );
249};
250
251#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
252
253template<typename T> struct is_reference_wrapper< reference_wrapper<T> const >
254{
255 BOOST_STATIC_CONSTANT( bool, value = true );
256};
257
258template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile >
259{
260 BOOST_STATIC_CONSTANT( bool, value = true );
261};
262
263template<typename T> struct is_reference_wrapper< reference_wrapper<T> const volatile >
264{
265 BOOST_STATIC_CONSTANT( bool, value = true );
266};
267
268#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
269
270/**
271 @endcond
272*/
273
274
275// unwrap_reference
276
277/**
278 @brief Find the type in a `reference_wrapper`.
279
280 The `typedef` type is `T::type` if `T` is a
281 `reference_wrapper`, `T` otherwise.
282*/
283template<typename T> struct unwrap_reference
284{
285 typedef T type;
286};
287
288/**
289 @cond
290*/
291template<typename T> struct unwrap_reference< reference_wrapper<T> >
292{
293 typedef T type;
294};
295
296#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
297
298template<typename T> struct unwrap_reference< reference_wrapper<T> const >
299{
300 typedef T type;
301};
302
303template<typename T> struct unwrap_reference< reference_wrapper<T> volatile >
304{
305 typedef T type;
306};
307
308template<typename T> struct unwrap_reference< reference_wrapper<T> const volatile >
309{
310 typedef T type;
311};
312
313#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
314
315/**
316 @endcond
317*/
318
319// unwrap_ref
320
321/**
322 @return `unwrap_reference<T>::type&(t)`
323 @remark Does not throw.
324*/
325template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t ) BOOST_NOEXCEPT
326{
327 return t;
328}
329
330// get_pointer
331
332/**
333 @cond
334*/
335template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r ) BOOST_NOEXCEPT
336{
337 return r.get_pointer();
338}
339/**
340 @endcond
341*/
342
343} // namespace boost
344
345#endif // #ifndef BOOST_CORE_REF_HPP
346