Line data Source code
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 : */ 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 : namespace detail 49 : { 50 : 51 : template< 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) 63 : struct 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 : */ 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 : */ 95 239440 : 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)) 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 : */ 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 0 : BOOST_FORCEINLINE operator T& () const BOOST_NOEXCEPT { return *t_; } 138 : 139 : /** 140 : @return The stored reference. 141 : @remark Does not throw. 142 : */ 143 21608 : 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 : 152 : private: 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 : */ 175 119720 : template<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 119720 : 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 : */ 194 : template<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 : */ 218 : template<class T> void ref(T const&&) BOOST_REF_DELETE; 219 : 220 : /** 221 : @remark Construction from a temporary object is disabled. 222 : */ 223 : template<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 : */ 238 : template<typename T> struct is_reference_wrapper 239 : { 240 : BOOST_STATIC_CONSTANT( bool, value = false ); 241 : }; 242 : 243 : /** 244 : @cond 245 : */ 246 : template<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 : 253 : template<typename T> struct is_reference_wrapper< reference_wrapper<T> const > 254 : { 255 : BOOST_STATIC_CONSTANT( bool, value = true ); 256 : }; 257 : 258 : template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile > 259 : { 260 : BOOST_STATIC_CONSTANT( bool, value = true ); 261 : }; 262 : 263 : template<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 : */ 283 : template<typename T> struct unwrap_reference 284 : { 285 : typedef T type; 286 : }; 287 : 288 : /** 289 : @cond 290 : */ 291 : template<typename T> struct unwrap_reference< reference_wrapper<T> > 292 : { 293 : typedef T type; 294 : }; 295 : 296 : #if !defined(BOOST_NO_CV_SPECIALIZATIONS) 297 : 298 : template<typename T> struct unwrap_reference< reference_wrapper<T> const > 299 : { 300 : typedef T type; 301 : }; 302 : 303 : template<typename T> struct unwrap_reference< reference_wrapper<T> volatile > 304 : { 305 : typedef T type; 306 : }; 307 : 308 : template<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 : */ 325 : template<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 : */ 335 : template<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