sl@0: //----------------------------------------------------------------------------- sl@0: // boost variant/detail/move.hpp header file sl@0: // See http://www.boost.org for updates, documentation, and revision history. sl@0: //----------------------------------------------------------------------------- sl@0: // sl@0: // Copyright (c) 2002-2003 Eric Friedman sl@0: // Copyright (c) 2002 by Andrei Alexandrescu sl@0: // sl@0: // Use, modification and distribution are subject to the sl@0: // Boost Software License, Version 1.0. (See accompanying file sl@0: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) sl@0: // sl@0: // This file derivative of MoJO. Much thanks to Andrei for his initial work. sl@0: // See for information on MOJO. sl@0: // Re-issued here under the Boost Software License, with permission of the original sl@0: // author (Andrei Alexandrescu). sl@0: sl@0: sl@0: #ifndef BOOST_VARIANT_DETAIL_MOVE_HPP sl@0: #define BOOST_VARIANT_DETAIL_MOVE_HPP sl@0: sl@0: #include // for iterator_traits sl@0: #include // for placement new sl@0: sl@0: #include "boost/config.hpp" sl@0: #include "boost/detail/workaround.hpp" sl@0: #include "boost/mpl/if.hpp" sl@0: #include "boost/type_traits/is_base_and_derived.hpp" sl@0: sl@0: namespace boost { sl@0: namespace detail { namespace variant { sl@0: sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: // forward declares sl@0: // sl@0: // NOTE: Incomplete until (if?) Boost.Move becomes part of Boost. sl@0: // sl@0: template class moveable; sl@0: template class move_source; sl@0: template class move_return; sl@0: sl@0: namespace detail { sl@0: sl@0: // (detail) moveable_tag sl@0: // sl@0: // Concrete type from which moveable derives. sl@0: // sl@0: // TODO: Move into moveable_fwd.hpp and define has_move_constructor. sl@0: // sl@0: template sl@0: struct moveable_tag sl@0: { sl@0: }; sl@0: sl@0: } // namespace detail sl@0: sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: // function template move sl@0: // sl@0: // Takes a T& and returns, if T derives moveable, a move_source for sl@0: // the object; else, returns the T&. sl@0: // sl@0: sl@0: namespace detail { sl@0: sl@0: // (detail) class template move_type sl@0: // sl@0: // Metafunction that, given moveable T, provides move_source, else T&. sl@0: // sl@0: template sl@0: struct move_type sl@0: { sl@0: public: // metafunction result sl@0: sl@0: typedef typename mpl::if_< sl@0: is_base_and_derived, T> sl@0: , move_source sl@0: , T& sl@0: >::type type; sl@0: sl@0: }; sl@0: sl@0: } // namespace detail sl@0: sl@0: template sl@0: inline sl@0: typename detail::move_type::type sl@0: move(T& source) sl@0: { sl@0: typedef typename detail::move_type::type sl@0: move_t; sl@0: sl@0: return move_t(source); sl@0: } sl@0: sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: // class template return_t sl@0: // sl@0: // Metafunction that, given moveable T, provides move_return, else T. sl@0: // sl@0: template sl@0: struct return_t sl@0: { sl@0: public: // metafunction result sl@0: sl@0: typedef typename mpl::if_< sl@0: is_base_and_derived, T> sl@0: , move_return sl@0: , T sl@0: >::type type; sl@0: sl@0: }; sl@0: sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: // function template move_swap sl@0: // sl@0: // Swaps using Koenig lookup but falls back to move-swap for primitive sl@0: // types and on non-conforming compilers. sl@0: // sl@0: sl@0: #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \ sl@0: || BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(2)) sl@0: sl@0: // [Indicate that move_swap by overload is disabled...] sl@0: #define BOOST_NO_MOVE_SWAP_BY_OVERLOAD sl@0: sl@0: // [...and provide straight swap-by-move implementation:] sl@0: template sl@0: inline void move_swap(T& lhs, T& rhs) sl@0: { sl@0: T tmp( boost::detail::variant::move(lhs) ); sl@0: lhs = boost::detail::variant::move(rhs); sl@0: rhs = boost::detail::variant::move(tmp); sl@0: } sl@0: sl@0: #else// !workaround sl@0: sl@0: namespace detail { namespace move_swap { sl@0: sl@0: template sl@0: inline void swap(T& lhs, T& rhs) sl@0: { sl@0: T tmp( boost::detail::variant::move(lhs) ); sl@0: lhs = boost::detail::variant::move(rhs); sl@0: rhs = boost::detail::variant::move(tmp); sl@0: } sl@0: sl@0: }} // namespace detail::move_swap sl@0: sl@0: template sl@0: inline void move_swap(T& lhs, T& rhs) sl@0: { sl@0: using detail::move_swap::swap; sl@0: sl@0: swap(lhs, rhs); sl@0: } sl@0: sl@0: #endif // workaround sl@0: sl@0: }} // namespace detail::variant sl@0: } // namespace boost sl@0: sl@0: #endif // BOOST_VARIANT_DETAIL_MOVE_HPP sl@0: sl@0: sl@0: