1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2012-2012.
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7//
8// See http://www.boost.org/libs/move for documentation.
9//
10//////////////////////////////////////////////////////////////////////////////
11
12//! \file
13//! This header defines core utilities to ease the development
14//! of move-aware functions. This header minimizes dependencies
15//! from other libraries.
16
17#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
18#define BOOST_MOVE_MOVE_UTILITY_CORE_HPP
19
20#ifndef BOOST_CONFIG_HPP
21# include <boost/config.hpp>
22#endif
23#
24#if defined(BOOST_HAS_PRAGMA_ONCE)
25# pragma once
26#endif
27
28#include <boost/move/detail/config_begin.hpp>
29#include <boost/move/detail/workaround.hpp> //forceinline
30#include <boost/move/core.hpp>
31#include <boost/move/detail/meta_utils.hpp>
32
33#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
34
35 namespace boost {
36
37 template<class T>
38 struct enable_move_utility_emulation
39 {
40 static const bool value = true;
41 };
42
43 //////////////////////////////////////////////////////////////////////////////
44 //
45 // move()
46 //
47 //////////////////////////////////////////////////////////////////////////////
48
49 template <class T>
50 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
51 < T &
52 , enable_move_utility_emulation<T>
53 , has_move_emulation_disabled<T>
54 >::type
55 move(T& x) BOOST_NOEXCEPT
56 {
57 return x;
58 }
59
60 template <class T>
61 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
62 < rv<T>&
63 , enable_move_utility_emulation<T>
64 , has_move_emulation_enabled<T>
65 >::type
66 move(T& x) BOOST_NOEXCEPT
67 {
68 return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x) );
69 }
70
71 template <class T>
72 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
73 < rv<T>&
74 , enable_move_utility_emulation<T>
75 , has_move_emulation_enabled<T>
76 >::type
77 move(rv<T>& x) BOOST_NOEXCEPT
78 {
79 return x;
80 }
81
82 //////////////////////////////////////////////////////////////////////////////
83 //
84 // forward()
85 //
86 //////////////////////////////////////////////////////////////////////////////
87
88 template <class T>
89 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
90 < T &
91 , enable_move_utility_emulation<T>
92 , ::boost::move_detail::is_rv<T>
93 >::type
94 forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
95 {
96 return const_cast<T&>(x);
97 }
98
99 template <class T>
100 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
101 < const T &
102 , enable_move_utility_emulation<T>
103 , ::boost::move_detail::is_not_rv<T>
104 >::type
105 forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
106 {
107 return x;
108 }
109
110 //////////////////////////////////////////////////////////////////////////////
111 //
112 // move_if_not_lvalue_reference()
113 //
114 //////////////////////////////////////////////////////////////////////////////
115
116 template <class T>
117 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
118 < T &
119 , enable_move_utility_emulation<T>
120 , ::boost::move_detail::is_rv<T>
121 >::type
122 move_if_not_lvalue_reference(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
123 {
124 return const_cast<T&>(x);
125 }
126
127 template <class T>
128 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
129 < typename ::boost::move_detail::add_lvalue_reference<T>::type
130 , enable_move_utility_emulation<T>
131 , ::boost::move_detail::is_not_rv<T>
132 , ::boost::move_detail::or_
133 < ::boost::move_detail::is_lvalue_reference<T>
134 , has_move_emulation_disabled<T>
135 >
136 >::type
137 move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
138 {
139 return x;
140 }
141
142 template <class T>
143 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
144 < rv<T>&
145 , enable_move_utility_emulation<T>
146 , ::boost::move_detail::is_not_rv<T>
147 , ::boost::move_detail::and_
148 < ::boost::move_detail::not_< ::boost::move_detail::is_lvalue_reference<T> >
149 , has_move_emulation_enabled<T>
150 >
151 >::type
152 move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
153 {
154 return move(x);
155 }
156
157 } //namespace boost
158
159#else //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
160
161 #if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
162 #include <utility>
163
164 namespace boost{
165
166 using ::std::move;
167 using ::std::forward;
168
169 } //namespace boost
170
171 #else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
172
173 namespace boost {
174
175 //! This trait's internal boolean `value` is false in compilers with rvalue references
176 //! and true in compilers without rvalue references.
177 //!
178 //! A user can specialize this trait for a type T to false to SFINAE out `move` and `forward`
179 //! so that the user can define a different move emulation for that type in namespace boost
180 //! (e.g. another Boost library for its types) and avoid any overload ambiguity.
181 template<class T>
182 struct enable_move_utility_emulation
183 {
184 static const bool value = false;
185 };
186
187 //////////////////////////////////////////////////////////////////////////////
188 //
189 // move
190 //
191 //////////////////////////////////////////////////////////////////////////////
192
193 #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
194 //! This function provides a way to convert a reference into a rvalue reference
195 //! in compilers with rvalue references. For other compilers if `T` is Boost.Move
196 //! enabled type then it converts `T&` into <tt>::boost::rv<T> &</tt> so that
197 //! move emulation is activated, else it returns `T &`.
198 template <class T>
199 rvalue_reference move(input_reference) noexcept;
200
201 #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
202
203 //Old move approach, lvalues could bind to rvalue references
204 template <class T>
205 BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
206 { return t; }
207
208 #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
209
210 template <class T>
211 BOOST_MOVE_INTRINSIC_CAST
212 typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
213 { return static_cast<typename ::boost::move_detail::remove_reference<T>::type &&>(t); }
214
215 #endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
216
217 //////////////////////////////////////////////////////////////////////////////
218 //
219 // forward
220 //
221 //////////////////////////////////////////////////////////////////////////////
222
223
224 #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
225 //! This function provides limited form of forwarding that is usually enough for
226 //! in-place construction and avoids the exponential overloading for
227 //! achieve the limited forwarding in C++03.
228 //!
229 //! For compilers with rvalue references this function provides perfect forwarding.
230 //!
231 //! Otherwise:
232 //! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
233 //! ::boost::rv<T> &
234 //!
235 //! * Else, output_reference is equal to input_reference.
236 template <class T> output_reference forward(input_reference) noexcept;
237 #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
238
239 //Old move approach, lvalues could bind to rvalue references
240
241 template <class T>
242 BOOST_MOVE_FORCEINLINE T&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
243 { return t; }
244
245 #else //Old move
246
247 template <class T>
248 BOOST_MOVE_INTRINSIC_CAST
249 T&& forward(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
250 { return static_cast<T&&>(t); }
251
252 template <class T>
253 BOOST_MOVE_INTRINSIC_CAST
254 T&& forward(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
255 {
256 //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
257 BOOST_MOVE_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
258 return static_cast<T&&>(t);
259 }
260
261 #endif //BOOST_MOVE_DOXYGEN_INVOKED
262
263 } //namespace boost {
264
265 #endif //BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
266
267 //////////////////////////////////////////////////////////////////////////////
268 //
269 // move_if_not_lvalue_reference
270 //
271 //////////////////////////////////////////////////////////////////////////////
272
273 namespace boost {
274
275 #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
276 //! <b>Effects</b>: Calls `boost::move` if `input_reference` is not a lvalue reference.
277 //! Otherwise returns the reference
278 template <class T> output_reference move_if_not_lvalue_reference(input_reference) noexcept;
279 #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
280
281 //Old move approach, lvalues could bind to rvalue references
282
283 template <class T>
284 BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
285 { return t; }
286
287 #else //Old move
288
289 template <class T>
290 BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
291 { return static_cast<T&&>(t); }
292
293 template <class T>
294 BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
295 {
296 //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
297 BOOST_MOVE_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
298 return static_cast<T&&>(t);
299 }
300
301 #endif //BOOST_MOVE_DOXYGEN_INVOKED
302
303 } //namespace boost {
304
305#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
306
307#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
308
309namespace boost{
310namespace move_detail{
311
312template <typename T>
313typename boost::move_detail::add_rvalue_reference<T>::type declval();
314
315} //namespace move_detail{
316} //namespace boost{
317
318#endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
319
320
321#include <boost/move/detail/config_end.hpp>
322
323#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
324

source code of boost/libs/move/include/boost/move/utility_core.hpp