basic_op.hpp 4.5 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. namespace boost {
  24. namespace movelib {
  25. struct forward_t{};
  26. struct backward_t{};
  27. struct three_way_t{};
  28. struct three_way_forward_t{};
  29. struct four_way_t{};
  30. struct move_op
  31. {
  32. template <class SourceIt, class DestinationIt>
  33. BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest)
  34. { *dest = ::boost::move(*source); }
  35. template <class SourceIt, class DestinationIt>
  36. BOOST_MOVE_FORCEINLINE DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
  37. { return ::boost::move(first, last, dest_begin); }
  38. template <class SourceIt, class DestinationIt>
  39. BOOST_MOVE_FORCEINLINE DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_last)
  40. { return ::boost::move_backward(first, last, dest_last); }
  41. template <class SourceIt, class DestinationIt1, class DestinationIt2>
  42. BOOST_MOVE_FORCEINLINE void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it)
  43. {
  44. *dest2it = boost::move(*dest1it);
  45. *dest1it = boost::move(*srcit);
  46. }
  47. template <class SourceIt, class DestinationIt1, class DestinationIt2>
  48. DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it)
  49. {
  50. //Destination2 range can overlap SourceIt range so avoid boost::move
  51. while(srcit != srcitend){
  52. this->operator()(three_way_t(), srcit++, dest1it++, dest2it++);
  53. }
  54. return dest2it;
  55. }
  56. template <class SourceIt, class DestinationIt1, class DestinationIt2, class DestinationIt3>
  57. BOOST_MOVE_FORCEINLINE void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it)
  58. {
  59. *dest3it = boost::move(*dest2it);
  60. *dest2it = boost::move(*dest1it);
  61. *dest1it = boost::move(*srcit);
  62. }
  63. };
  64. struct swap_op
  65. {
  66. template <class SourceIt, class DestinationIt>
  67. BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest)
  68. { boost::adl_move_swap(*dest, *source); }
  69. template <class SourceIt, class DestinationIt>
  70. BOOST_MOVE_FORCEINLINE DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
  71. { return boost::adl_move_swap_ranges(first, last, dest_begin); }
  72. template <class SourceIt, class DestinationIt>
  73. BOOST_MOVE_FORCEINLINE DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
  74. { return boost::adl_move_swap_ranges_backward(first, last, dest_begin); }
  75. template <class SourceIt, class DestinationIt1, class DestinationIt2>
  76. BOOST_MOVE_FORCEINLINE void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it)
  77. {
  78. typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest2it));
  79. *dest2it = boost::move(*dest1it);
  80. *dest1it = boost::move(*srcit);
  81. *srcit = boost::move(tmp);
  82. }
  83. template <class SourceIt, class DestinationIt1, class DestinationIt2>
  84. DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it)
  85. {
  86. while(srcit != srcitend){
  87. this->operator()(three_way_t(), srcit++, dest1it++, dest2it++);
  88. }
  89. return dest2it;
  90. }
  91. template <class SourceIt, class DestinationIt1, class DestinationIt2, class DestinationIt3>
  92. BOOST_MOVE_FORCEINLINE void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it)
  93. {
  94. typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest3it));
  95. *dest3it = boost::move(*dest2it);
  96. *dest2it = boost::move(*dest1it);
  97. *dest1it = boost::move(*srcit);
  98. *srcit = boost::move(tmp);
  99. }
  100. };
  101. }} //namespace boost::movelib
  102. #endif //BOOST_MOVE_ALGO_BASIC_OP