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 29namespace boost 30{ 31 32template<class T> class reference_wrapper 33{ 34public: 35 typedef T type; 36 37#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) 38 39 explicit reference_wrapper(T& t): t_(&t) {} 40 41#else 42 43 explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} 44 45#endif 46 47 operator T& () const { return *t_; } 48 49 T& get() const { return *t_; } 50 51 T* get_pointer() const { return t_; } 52 53private: 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 64template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t) 65{ 66 return reference_wrapper<T>(t); 67} 68 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 78template<typename T> 79class is_reference_wrapper 80 : public mpl::false_ 81{ 82}; 83 84template<typename T> 85class unwrap_reference 86{ 87 public: 88 typedef T type; 89}; 90 91# define AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(X) \ 92template<typename T> \ 93class is_reference_wrapper< X > \ 94 : public mpl::true_ \ 95{ \ 96}; \ 97\ 98template<typename T> \ 99class unwrap_reference< X > \ 100{ \ 101 public: \ 102 typedef T type; \ 103}; \ 104/**/ 105 106AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T>) 107#if !defined(BOOST_NO_CV_SPECIALIZATIONS) 108AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const) 109AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> volatile) 110AUX_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 121namespace boost 122{ 123 124namespace 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 155template<typename T> 156class 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 167template <typename T> 168class 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 176template <class T> inline typename unwrap_reference<T>::type& 177unwrap_ref(T& t) 178{ 179 return t; 180} 181 182template<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