]> git.lyx.org Git - lyx.git/blob - boost/boost/move/utility_core.hpp
Cmake export tests: More tests to be inverted, suspended or made non-standard
[lyx.git] / boost / boost / move / utility_core.hpp
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/core.hpp>
30 #include <boost/move/detail/meta_utils.hpp>
31 #include <boost/static_assert.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    inline 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    inline 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    inline 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    inline 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    inline 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    inline 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    inline 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    inline 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          inline 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          inline typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
212          { return static_cast<typename ::boost::move_detail::remove_reference<T>::type &&>(t); }
213
214       #endif   //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
215
216       //////////////////////////////////////////////////////////////////////////////
217       //
218       //                                  forward
219       //
220       //////////////////////////////////////////////////////////////////////////////
221
222
223       #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
224          //! This function provides limited form of forwarding that is usually enough for
225          //! in-place construction and avoids the exponential overloading for
226          //! achieve the limited forwarding in C++03.
227          //!
228          //! For compilers with rvalue references this function provides perfect forwarding.
229          //!
230          //! Otherwise:
231          //! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
232          //!   ::boost::rv<T> &
233          //!
234          //! * Else, output_reference is equal to input_reference.
235          template <class T> output_reference forward(input_reference) noexcept;
236       #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
237
238          //Old move approach, lvalues could bind to rvalue references
239
240          template <class T>
241          inline T&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
242          {  return t;   }
243
244       #else //Old move
245
246          template <class T>
247          inline T&& forward(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
248          {  return static_cast<T&&>(t);   }
249
250          template <class T>
251          inline T&& forward(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
252          {
253             //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
254             BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
255             return static_cast<T&&>(t);
256          }
257
258       #endif   //BOOST_MOVE_DOXYGEN_INVOKED
259
260       //////////////////////////////////////////////////////////////////////////////
261       //
262       //                         move_if_not_lvalue_reference
263       //
264       //////////////////////////////////////////////////////////////////////////////
265
266
267       #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
268          template <class T> output_reference move_if_not_lvalue_reference(input_reference) noexcept;
269       #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
270
271          //Old move approach, lvalues could bind to rvalue references
272
273          template <class T>
274          inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
275          {  return t;   }
276
277       #else //Old move
278
279          template <class T>
280          inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
281          {  return static_cast<T&&>(t);   }
282
283          template <class T>
284          inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
285          {
286             //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
287             BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
288             return static_cast<T&&>(t);
289          }
290
291       #endif   //BOOST_MOVE_DOXYGEN_INVOKED
292
293       }  //namespace boost {
294
295    #endif   //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
296
297 #endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
298
299 #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
300
301 namespace boost{
302 namespace move_detail{
303
304 template <typename T>
305 typename boost::move_detail::add_rvalue_reference<T>::type declval();
306
307 }  //namespace move_detail{
308 }  //namespace boost{
309
310 #endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
311
312
313 #include <boost/move/detail/config_end.hpp>
314
315 #endif //#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP