Ticket #10277: ref.hpp

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