blob: ad20bca72872d1eb2002aa5289432412c5112437 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001#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 <ndnboost/config.hpp>
11#include <ndnboost/utility/addressof.hpp>
12#include <ndnboost/mpl/bool.hpp>
13#include <ndnboost/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 ndnboost
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_(ndnboost::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 ndnboost
118
119#include <ndnboost/type.hpp>
120
121namespace ndnboost
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 ::ndnboost::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 ndnboost
188
189#endif // #ifndef BOOST_REF_HPP_INCLUDED