blob: 756ecd6d133d04d61522e5132e133647863192ea [file] [log] [blame]
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001#ifndef NDNBOOST_REF_HPP_INCLUDED
2#define NDNBOOST_REF_HPP_INCLUDED
Jeff Thompsona28eed82013-08-22 16:21:10 -07003
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -070037#if defined( NDNBOOST_MSVC ) && NDNBOOST_WORKAROUND( NDNBOOST_MSVC, < 1300 )
Jeff Thompsona28eed82013-08-22 16:21:10 -070038
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -070058# if defined( __BORLANDC__ ) && NDNBOOST_WORKAROUND( __BORLANDC__, NDNBOOST_TESTED_AT(0x581) )
59# define NDNBOOST_REF_CONST
Jeff Thompsona28eed82013-08-22 16:21:10 -070060# else
Jeff Thompson3d613fd2013-10-15 15:39:04 -070061# define NDNBOOST_REF_CONST const
Jeff Thompsona28eed82013-08-22 16:21:10 -070062# endif
63
Jeff Thompson3d613fd2013-10-15 15:39:04 -070064template<class T> inline reference_wrapper<T> NDNBOOST_REF_CONST ref(T & t)
Jeff Thompsona28eed82013-08-22 16:21:10 -070065{
66 return reference_wrapper<T>(t);
67}
68
Jeff Thompson3d613fd2013-10-15 15:39:04 -070069template<class T> inline reference_wrapper<T const> NDNBOOST_REF_CONST cref(T const & t)
Jeff Thompsona28eed82013-08-22 16:21:10 -070070{
71 return reference_wrapper<T const>(t);
72}
73
Jeff Thompson3d613fd2013-10-15 15:39:04 -070074# undef NDNBOOST_REF_CONST
Jeff Thompsona28eed82013-08-22 16:21:10 -070075
Jeff Thompson3d613fd2013-10-15 15:39:04 -070076# ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Jeff Thompsona28eed82013-08-22 16:21:10 -070077
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>)
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700107#if !defined(NDNBOOST_NO_CV_SPECIALIZATIONS)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700108AUX_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:
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700159 NDNBOOST_STATIC_CONSTANT(
Jeff Thompsona28eed82013-08-22 16:21:10 -0700160 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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700174# endif // NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Jeff Thompsona28eed82013-08-22 16:21:10 -0700175
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700189#endif // #ifndef NDNBOOST_REF_HPP_INCLUDED