1 //-----------------------------------------------------------------------------
2 // boost variant/detail/move.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
6 // Copyright (c) 2002-2003 Eric Friedman
7 // Copyright (c) 2002 by Andrei Alexandrescu
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"
31 namespace detail
{ namespace variant
{
33 //////////////////////////////////////////////////////////////////////////
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
;
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
>
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&.
66 // (detail) class template move_type
68 // Metafunction that, given moveable T, provides move_source<T>, else T&.
73 public: // metafunction result
75 typedef typename
mpl::if_
<
76 is_base_and_derived
<detail::moveable_tag
<T
>, T
>
87 typename
detail::move_type
<T
>::type
90 typedef typename
detail::move_type
<T
>::type
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
>
104 public: // metafunction result
106 typedef typename
mpl::if_
<
107 is_base_and_derived
<moveable
<T
>, T
>
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
);
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
;
160 }} // namespace detail::variant
163 #endif // BOOST_VARIANT_DETAIL_MOVE_HPP