/Src/Dependencies/Boost/boost/variant/detail/move.hpp

http://hadesmem.googlecode.com/ · C++ Header · 166 lines · 80 code · 36 blank · 50 comment · 1 complexity · b9b0fe0ea7ba65249cca8accdfbd661b MD5 · raw file

  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)
  12. //
  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).
  17. #ifndef BOOST_VARIANT_DETAIL_MOVE_HPP
  18. #define BOOST_VARIANT_DETAIL_MOVE_HPP
  19. #include <iterator> // for iterator_traits
  20. #include <new> // for placement new
  21. #include "boost/config.hpp"
  22. #include "boost/detail/workaround.hpp"
  23. #include "boost/mpl/if.hpp"
  24. #include "boost/type_traits/is_base_and_derived.hpp"
  25. namespace boost {
  26. namespace detail { namespace variant {
  27. //////////////////////////////////////////////////////////////////////////
  28. // forward declares
  29. //
  30. // NOTE: Incomplete until (if?) Boost.Move becomes part of Boost.
  31. //
  32. template <typename Deriving> class moveable;
  33. template <typename T> class move_source;
  34. template <typename T> class move_return;
  35. namespace detail {
  36. // (detail) moveable_tag
  37. //
  38. // Concrete type from which moveable<T> derives.
  39. //
  40. // TODO: Move into moveable_fwd.hpp and define has_move_constructor.
  41. //
  42. template <typename Deriving>
  43. struct moveable_tag
  44. {
  45. };
  46. } // namespace detail
  47. //////////////////////////////////////////////////////////////////////////
  48. // function template move
  49. //
  50. // Takes a T& and returns, if T derives moveable<T>, a move_source<T> for
  51. // the object; else, returns the T&.
  52. //
  53. namespace detail {
  54. // (detail) class template move_type
  55. //
  56. // Metafunction that, given moveable T, provides move_source<T>, else T&.
  57. //
  58. template <typename T>
  59. struct move_type
  60. {
  61. public: // metafunction result
  62. typedef typename mpl::if_<
  63. is_base_and_derived<detail::moveable_tag<T>, T>
  64. , move_source<T>
  65. , T&
  66. >::type type;
  67. };
  68. } // namespace detail
  69. template <typename T>
  70. inline
  71. typename detail::move_type<T>::type
  72. move(T& source)
  73. {
  74. typedef typename detail::move_type<T>::type
  75. move_t;
  76. return move_t(source);
  77. }
  78. //////////////////////////////////////////////////////////////////////////
  79. // class template return_t
  80. //
  81. // Metafunction that, given moveable T, provides move_return<T>, else T.
  82. //
  83. template <typename T>
  84. struct return_t
  85. {
  86. public: // metafunction result
  87. typedef typename mpl::if_<
  88. is_base_and_derived<moveable<T>, T>
  89. , move_return<T>
  90. , T
  91. >::type type;
  92. };
  93. //////////////////////////////////////////////////////////////////////////
  94. // function template move_swap
  95. //
  96. // Swaps using Koenig lookup but falls back to move-swap for primitive
  97. // types and on non-conforming compilers.
  98. //
  99. #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \
  100. || BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(2))
  101. // [Indicate that move_swap by overload is disabled...]
  102. #define BOOST_NO_MOVE_SWAP_BY_OVERLOAD
  103. // [...and provide straight swap-by-move implementation:]
  104. template <typename T>
  105. inline void move_swap(T& lhs, T& rhs)
  106. {
  107. T tmp( boost::detail::variant::move(lhs) );
  108. lhs = boost::detail::variant::move(rhs);
  109. rhs = boost::detail::variant::move(tmp);
  110. }
  111. #else// !workaround
  112. namespace detail { namespace move_swap {
  113. template <typename T>
  114. inline void swap(T& lhs, T& rhs)
  115. {
  116. T tmp( boost::detail::variant::move(lhs) );
  117. lhs = boost::detail::variant::move(rhs);
  118. rhs = boost::detail::variant::move(tmp);
  119. }
  120. }} // namespace detail::move_swap
  121. template <typename T>
  122. inline void move_swap(T& lhs, T& rhs)
  123. {
  124. using detail::move_swap::swap;
  125. swap(lhs, rhs);
  126. }
  127. #endif // workaround
  128. }} // namespace detail::variant
  129. } // namespace boost
  130. #endif // BOOST_VARIANT_DETAIL_MOVE_HPP