basic_op.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2015-2016.
  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. #ifndef BOOST_MOVE_ALGO_BASIC_OP
  12. #define BOOST_MOVE_ALGO_BASIC_OP
  13. #ifndef BOOST_CONFIG_HPP
  14. # include <boost/config.hpp>
  15. #endif
  16. #
  17. #if defined(BOOST_HAS_PRAGMA_ONCE)
  18. # pragma once
  19. #endif
  20. #include <boost/move/utility_core.hpp>
  21. #include <boost/move/adl_move_swap.hpp>
  22. #include <boost/move/detail/iterator_traits.hpp>
  23. #include <boost/move/algo/move.hpp>
  24. namespace boost {
  25. namespace movelib {
  26. struct forward_t{};
  27. struct backward_t{};
  28. struct three_way_t{};
  29. struct three_way_forward_t{};
  30. struct four_way_t{};
  31. struct move_op
  32. {
  33. template <class SourceIt, class DestinationIt>
  34. inline void operator()(SourceIt source, DestinationIt dest)
  35. { *dest = ::boost::move(*source); }
  36. template <class SourceIt, class DestinationIt>
  37. inline DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
  38. { return ::boost::move(first, last, dest_begin); }
  39. template <class SourceIt, class DestinationIt>
  40. inline DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_last)
  41. { return ::boost::move_backward(first, last, dest_last); }
  42. template <class SourceIt, class DestinationIt1, class DestinationIt2>
  43. inline void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it)
  44. {
  45. *dest2it = boost::move(*dest1it);
  46. *dest1it = boost::move(*srcit);
  47. }
  48. template <class SourceIt, class DestinationIt1, class DestinationIt2>
  49. DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it)
  50. {
  51. //Destination2 range can overlap SourceIt range so avoid boost::move
  52. while(srcit != srcitend){
  53. this->operator()(three_way_t(), srcit++, dest1it++, dest2it++);
  54. }
  55. return dest2it;
  56. }
  57. template <class SourceIt, class DestinationIt1, class DestinationIt2, class DestinationIt3>
  58. inline void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it)
  59. {
  60. *dest3it = boost::move(*dest2it);
  61. *dest2it = boost::move(*dest1it);
  62. *dest1it = boost::move(*srcit);
  63. }
  64. };
  65. struct swap_op
  66. {
  67. template <class SourceIt, class DestinationIt>
  68. inline void operator()(SourceIt source, DestinationIt dest)
  69. { boost::adl_move_swap(*dest, *source); }
  70. template <class SourceIt, class DestinationIt>
  71. inline DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
  72. { return boost::adl_move_swap_ranges(first, last, dest_begin); }
  73. template <class SourceIt, class DestinationIt>
  74. inline DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
  75. { return boost::adl_move_swap_ranges_backward(first, last, dest_begin); }
  76. template <class SourceIt, class DestinationIt1, class DestinationIt2>
  77. inline void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it)
  78. {
  79. typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest2it));
  80. *dest2it = boost::move(*dest1it);
  81. *dest1it = boost::move(*srcit);
  82. *srcit = boost::move(tmp);
  83. }
  84. template <class SourceIt, class DestinationIt1, class DestinationIt2>
  85. DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it)
  86. {
  87. while(srcit != srcitend){
  88. this->operator()(three_way_t(), srcit++, dest1it++, dest2it++);
  89. }
  90. return dest2it;
  91. }
  92. template <class SourceIt, class DestinationIt1, class DestinationIt2, class DestinationIt3>
  93. inline void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it)
  94. {
  95. typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest3it));
  96. *dest3it = boost::move(*dest2it);
  97. *dest2it = boost::move(*dest1it);
  98. *dest1it = boost::move(*srcit);
  99. *srcit = boost::move(tmp);
  100. }
  101. };
  102. }} //namespace boost::movelib
  103. #endif //BOOST_MOVE_ALGO_BASIC_OP