]> git.lyx.org Git - lyx.git/blob - boost/boost/ref.hpp
fb7497b787eeca62b6e6764039c1ec6f40641e3e
[lyx.git] / boost / boost / ref.hpp
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
14 //
15 //  ref.hpp - ref/cref, useful helper functions
16 //
17 //  Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
18 //  Copyright (C) 2001, 2002 Peter Dimov
19 //  Copyright (C) 2002 David Abrahams
20 //
21 //  Permission to copy, use, modify, sell and distribute this software
22 //  is granted provided this copyright notice appears in all copies.
23 //  This software is provided "as is" without express or implied
24 //  warranty, and with no claim as to its suitability for any purpose.
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_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
53 private:
54
55     T* t_;
56 };
57
58 # if defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)
59 #  define BOOST_REF_CONST
60 # else
61 #  define BOOST_REF_CONST const
62 # endif
63
64 template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t)
65
66     return reference_wrapper<T>(t);
67 }
68
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 template<typename T>
78 class is_reference_wrapper
79     : public mpl::false_
80 {
81 };
82
83 template<typename T>
84 class is_reference_wrapper<reference_wrapper<T> >
85     : public mpl::true_
86 {
87 };
88
89 template<typename T>
90 class unwrap_reference
91 {
92  public:
93     typedef T type;
94 };
95
96 template<typename T>
97 class unwrap_reference<reference_wrapper<T> >
98 {
99  public:
100     typedef T type;
101 };
102 # else // no partial specialization
103
104 } // namespace boost
105
106 #include <boost/type.hpp>
107
108 namespace boost
109 {
110
111 namespace detail
112 {
113   typedef char (&yes_reference_wrapper_t)[1];
114   typedef char (&no_reference_wrapper_t)[2];
115       
116   no_reference_wrapper_t is_reference_wrapper_test(...);
117
118   template<typename T>
119   yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper<T> >);
120
121   template<bool wrapped>
122   struct reference_unwrapper
123   {
124       template <class T>
125       struct apply
126       {
127           typedef T type;
128       };
129   };
130
131   template<>
132   struct reference_unwrapper<true>
133   {
134       template <class T>
135       struct apply
136       {
137           typedef typename T::type type;
138       };
139   };
140 }
141
142 template<typename T>
143 class is_reference_wrapper
144 {
145  public:
146     BOOST_STATIC_CONSTANT(
147         bool, value = (
148              sizeof(detail::is_reference_wrapper_test(type<T>()))
149             == sizeof(detail::yes_reference_wrapper_t)));
150     
151     typedef ::boost::mpl::bool_<value> type;
152 };
153
154 template <typename T>
155 class unwrap_reference
156     : public detail::reference_unwrapper<
157         is_reference_wrapper<T>::value
158       >::template apply<T>
159 {};
160
161 # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
162
163 } // namespace boost
164
165 #endif // #ifndef BOOST_REF_HPP_INCLUDED