1 #ifndef BOOST_CORE_REF_HPP
2 #define BOOST_CORE_REF_HPP
4 // MS compatible compilers support #pragma once
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
10 #include <boost/config.hpp>
11 #include <boost/config/workaround.hpp>
12 #include <boost/core/addressof.hpp>
13 #include <boost/core/enable_if.hpp>
16 // ref.hpp - ref/cref, useful helper functions
18 // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
19 // Copyright (C) 2001, 2002 Peter Dimov
20 // Copyright (C) 2002 David Abrahams
22 // Copyright (C) 2014 Glen Joseph Fernandes
23 // (glenjofe@gmail.com)
25 // Copyright (C) 2014 Agustin Berge
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)
31 // See http://www.boost.org/libs/core/doc/html/core/ref.html for documentation.
44 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
46 struct ref_workaround_tag {};
53 template< class Y, class T > struct ref_convertible
55 typedef char (&yes) [1];
56 typedef char (&no) [2];
61 enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
73 @brief Contains a reference to an object of type `T`.
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
81 template<class T> class reference_wrapper
90 Constructs a `reference_wrapper` object that stores a
93 @remark Does not throw.
95 BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
97 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
99 BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {}
103 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
105 @remark Construction from a temporary object is disabled.
107 BOOST_DELETED_FUNCTION(reference_wrapper(T&& t))
111 template<class Y> friend class reference_wrapper;
114 Constructs a `reference_wrapper` object that stores the
115 reference stored in the compatible `reference_wrapper` `r`.
117 @remark Only enabled when `Y*` is convertible to `T*`.
118 @remark Does not throw.
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_ )
127 @return The stored reference.
128 @remark Does not throw.
130 BOOST_FORCEINLINE operator T& () const { return *t_; }
133 @return The stored reference.
134 @remark Does not throw.
136 BOOST_FORCEINLINE T& get() const { return *t_; }
139 @return A pointer to the object referenced by the stored
141 @remark Does not throw.
143 BOOST_FORCEINLINE T* get_pointer() const { return t_; }
155 #if defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) )
156 # define BOOST_REF_CONST
158 # define BOOST_REF_CONST const
165 @return `reference_wrapper<T>(t)`
166 @remark Does not throw.
168 template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t )
170 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
172 return reference_wrapper<T>( t, ref_workaround_tag() );
176 return reference_wrapper<T>( t );
184 @return `reference_wrapper<T const>(t)`
185 @remark Does not throw.
187 template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t )
189 return reference_wrapper<T const>(t);
192 #undef BOOST_REF_CONST
194 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
199 #if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
200 # define BOOST_REF_DELETE
202 # define BOOST_REF_DELETE = delete
209 @remark Construction from a temporary object is disabled.
211 template<class T> void ref(T const&&) BOOST_REF_DELETE;
214 @remark Construction from a temporary object is disabled.
216 template<class T> void cref(T const&&) BOOST_REF_DELETE;
218 #undef BOOST_REF_DELETE
222 // is_reference_wrapper
225 @brief Determine if a type `T` is an instantiation of
228 The value static constant will be true if the type `T` is a
229 specialization of `reference_wrapper`.
231 template<typename T> struct is_reference_wrapper
233 BOOST_STATIC_CONSTANT( bool, value = false );
239 template<typename T> struct is_reference_wrapper< reference_wrapper<T> >
241 BOOST_STATIC_CONSTANT( bool, value = true );
244 #if !defined(BOOST_NO_CV_SPECIALIZATIONS)
246 template<typename T> struct is_reference_wrapper< reference_wrapper<T> const >
248 BOOST_STATIC_CONSTANT( bool, value = true );
251 template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile >
253 BOOST_STATIC_CONSTANT( bool, value = true );
256 template<typename T> struct is_reference_wrapper< reference_wrapper<T> const volatile >
258 BOOST_STATIC_CONSTANT( bool, value = true );
261 #endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
271 @brief Find the type in a `reference_wrapper`.
273 The `typedef` type is `T::type` if `T` is a
274 `reference_wrapper`, `T` otherwise.
276 template<typename T> struct unwrap_reference
284 template<typename T> struct unwrap_reference< reference_wrapper<T> >
289 #if !defined(BOOST_NO_CV_SPECIALIZATIONS)
291 template<typename T> struct unwrap_reference< reference_wrapper<T> const >
296 template<typename T> struct unwrap_reference< reference_wrapper<T> volatile >
301 template<typename T> struct unwrap_reference< reference_wrapper<T> const volatile >
306 #endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
315 @return `unwrap_reference<T>::type&(t)`
316 @remark Does not throw.
318 template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t )
328 template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r )
330 return r.get_pointer();
338 #endif // #ifndef BOOST_CORE_REF_HPP