• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)64 template<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)69 template<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)108 AUX_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