1 #ifndef BOOST_REF_HPP_INCLUDED 2 #define BOOST_REF_HPP_INCLUDED 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/mpl/bool.hpp> 13 #include <boost/detail/workaround.hpp> 14 15 // 16 // ref.hpp - ref/cref, useful helper functions 17 // 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 21 // 22 // Distributed under the Boost Software License, Version 1.0. (See 23 // accompanying file LICENSE_1_0.txt or copy at 24 // http://www.boost.org/LICENSE_1_0.txt) 25 // 26 // See http://www.boost.org/libs/bind/ref.html for documentation. 27 // 28 29 namespace boost 30 { 31 32 template<class T> class reference_wrapper 33 { 34 public: 35 typedef T type; 36 37 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) 38 reference_wrapper(T & t)39 explicit reference_wrapper(T& t): t_(&t) {} 40 41 #else 42 reference_wrapper(T & t)43 explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} 44 45 #endif 46 operator T&() const47 operator T& () const { return *t_; } 48 get() const49 T& get() const { return *t_; } 50 get_pointer() const51 T* get_pointer() const { return t_; } 52 53 private: 54 55 T* t_; 56 }; 57 58 # if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) 59 # define BOOST_REF_CONST 60 # else 61 # define BOOST_REF_CONST const 62 # endif 63 ref(T & t)64template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t) 65 { 66 return reference_wrapper<T>(t); 67 } 68 cref(T const & t)69template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const & t) 70 { 71 return reference_wrapper<T const>(t); 72 } 73 74 # undef BOOST_REF_CONST 75 76 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 77 78 template<typename T> 79 class is_reference_wrapper 80 : public mpl::false_ 81 { 82 }; 83 84 template<typename T> 85 class unwrap_reference 86 { 87 public: 88 typedef T type; 89 }; 90 91 # define AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(X) \ 92 template<typename T> \ 93 class is_reference_wrapper< X > \ 94 : public mpl::true_ \ 95 { \ 96 }; \ 97 \ 98 template<typename T> \ 99 class unwrap_reference< X > \ 100 { \ 101 public: \ 102 typedef T type; \ 103 }; \ 104 /**/ 105 106 AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T>) 107 #if !defined(BOOST_NO_CV_SPECIALIZATIONS) AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const)108AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const) 109 AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> volatile) 110 AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const volatile) 111 #endif 112 113 # undef AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF 114 115 # else // no partial specialization 116 117 } // namespace boost 118 119 #include <boost/type.hpp> 120 121 namespace boost 122 { 123 124 namespace detail 125 { 126 typedef char (&yes_reference_wrapper_t)[1]; 127 typedef char (&no_reference_wrapper_t)[2]; 128 129 no_reference_wrapper_t is_reference_wrapper_test(...); 130 131 template<typename T> 132 yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper<T> >); 133 134 template<bool wrapped> 135 struct reference_unwrapper 136 { 137 template <class T> 138 struct apply 139 { 140 typedef T type; 141 }; 142 }; 143 144 template<> 145 struct reference_unwrapper<true> 146 { 147 template <class T> 148 struct apply 149 { 150 typedef typename T::type type; 151 }; 152 }; 153 } 154 155 template<typename T> 156 class is_reference_wrapper 157 { 158 public: 159 BOOST_STATIC_CONSTANT( 160 bool, value = ( 161 sizeof(detail::is_reference_wrapper_test(type<T>())) 162 == sizeof(detail::yes_reference_wrapper_t))); 163 164 typedef ::boost::mpl::bool_<value> type; 165 }; 166 167 template <typename T> 168 class unwrap_reference 169 : public detail::reference_unwrapper< 170 is_reference_wrapper<T>::value 171 >::template apply<T> 172 {}; 173 174 # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 175 176 template <class T> inline typename unwrap_reference<T>::type& 177 unwrap_ref(T& t) 178 { 179 return t; 180 } 181 182 template<class T> inline T* get_pointer( reference_wrapper<T> const & r ) 183 { 184 return r.get_pointer(); 185 } 186 187 } // namespace boost 188 189 #endif // #ifndef BOOST_REF_HPP_INCLUDED 190