fix doc example typo
[boost.git] / boost / variant / detail / move.hpp
blob572cfbb0f3be58bfbab8d08300dbde3db6e42ffc
1 //-----------------------------------------------------------------------------
2 // boost variant/detail/move.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2002-2003 Eric Friedman
7 // Copyright (c) 2002 by Andrei Alexandrescu
8 //
9 // Use, modification and distribution are subject to the
10 // Boost Software License, Version 1.0. (See accompanying file
11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
13 // This file derivative of MoJO. Much thanks to Andrei for his initial work.
14 // See <http://www.cuj.com/experts/2102/alexandr.htm> for information on MOJO.
15 // Re-issued here under the Boost Software License, with permission of the original
16 // author (Andrei Alexandrescu).
19 #ifndef BOOST_VARIANT_DETAIL_MOVE_HPP
20 #define BOOST_VARIANT_DETAIL_MOVE_HPP
22 #include <iterator> // for iterator_traits
23 #include <new> // for placement new
25 #include "boost/config.hpp"
26 #include "boost/detail/workaround.hpp"
27 #include "boost/mpl/if.hpp"
28 #include "boost/type_traits/is_base_and_derived.hpp"
30 namespace boost {
31 namespace detail { namespace variant {
33 //////////////////////////////////////////////////////////////////////////
34 // forward declares
36 // NOTE: Incomplete until (if?) Boost.Move becomes part of Boost.
38 template <typename Deriving> class moveable;
39 template <typename T> class move_source;
40 template <typename T> class move_return;
42 namespace detail {
44 // (detail) moveable_tag
46 // Concrete type from which moveable<T> derives.
48 // TODO: Move into moveable_fwd.hpp and define has_move_constructor.
50 template <typename Deriving>
51 struct moveable_tag
55 } // namespace detail
57 //////////////////////////////////////////////////////////////////////////
58 // function template move
60 // Takes a T& and returns, if T derives moveable<T>, a move_source<T> for
61 // the object; else, returns the T&.
64 namespace detail {
66 // (detail) class template move_type
68 // Metafunction that, given moveable T, provides move_source<T>, else T&.
70 template <typename T>
71 struct move_type
73 public: // metafunction result
75 typedef typename mpl::if_<
76 is_base_and_derived<detail::moveable_tag<T>, T>
77 , move_source<T>
78 , T&
79 >::type type;
83 } // namespace detail
85 template <typename T>
86 inline
87 typename detail::move_type<T>::type
88 move(T& source)
90 typedef typename detail::move_type<T>::type
91 move_t;
93 return move_t(source);
96 //////////////////////////////////////////////////////////////////////////
97 // class template return_t
99 // Metafunction that, given moveable T, provides move_return<T>, else T.
101 template <typename T>
102 struct return_t
104 public: // metafunction result
106 typedef typename mpl::if_<
107 is_base_and_derived<moveable<T>, T>
108 , move_return<T>
110 >::type type;
114 //////////////////////////////////////////////////////////////////////////
115 // function template move_swap
117 // Swaps using Koenig lookup but falls back to move-swap for primitive
118 // types and on non-conforming compilers.
121 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \
122 || BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(2))
124 // [Indicate that move_swap by overload is disabled...]
125 #define BOOST_NO_MOVE_SWAP_BY_OVERLOAD
127 // [...and provide straight swap-by-move implementation:]
128 template <typename T>
129 inline void move_swap(T& lhs, T& rhs)
131 T tmp( boost::detail::variant::move(lhs) );
132 lhs = boost::detail::variant::move(rhs);
133 rhs = boost::detail::variant::move(tmp);
136 #else// !workaround
138 namespace detail { namespace move_swap {
140 template <typename T>
141 inline void swap(T& lhs, T& rhs)
143 T tmp( boost::detail::variant::move(lhs) );
144 lhs = boost::detail::variant::move(rhs);
145 rhs = boost::detail::variant::move(tmp);
148 }} // namespace detail::move_swap
150 template <typename T>
151 inline void move_swap(T& lhs, T& rhs)
153 using detail::move_swap::swap;
155 swap(lhs, rhs);
158 #endif // workaround
160 }} // namespace detail::variant
161 } // namespace boost
163 #endif // BOOST_VARIANT_DETAIL_MOVE_HPP