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 14 #ifndef BOOST_CONFIG_HPP 15 # include <boost/config.hpp> 16 #endif 17 # 18 #if defined(BOOST_HAS_PRAGMA_ONCE) 19 # pragma once 20 #endif 21 22 #include <boost/move/utility_core.hpp> 23 #include <boost/move/adl_move_swap.hpp> 24 #include <boost/move/detail/iterator_traits.hpp> 25 26 namespace boost { 27 namespace movelib { 28 29 struct forward_t{}; 30 struct backward_t{}; 31 struct three_way_t{}; 32 struct three_way_forward_t{}; 33 struct four_way_t{}; 34 35 struct move_op 36 { 37 template <class SourceIt, class DestinationIt> operator ()boost::movelib::move_op38 BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest) 39 { *dest = ::boost::move(*source); } 40 41 template <class SourceIt, class DestinationIt> operator ()boost::movelib::move_op42 BOOST_MOVE_FORCEINLINE DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin) 43 { return ::boost::move(first, last, dest_begin); } 44 45 template <class SourceIt, class DestinationIt> operator ()boost::movelib::move_op46 BOOST_MOVE_FORCEINLINE DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_last) 47 { return ::boost::move_backward(first, last, dest_last); } 48 49 template <class SourceIt, class DestinationIt1, class DestinationIt2> operator ()boost::movelib::move_op50 BOOST_MOVE_FORCEINLINE void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it) 51 { 52 *dest2it = boost::move(*dest1it); 53 *dest1it = boost::move(*srcit); 54 } 55 56 template <class SourceIt, class DestinationIt1, class DestinationIt2> operator ()boost::movelib::move_op57 DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it) 58 { 59 //Destination2 range can overlap SourceIt range so avoid boost::move 60 while(srcit != srcitend){ 61 this->operator()(three_way_t(), srcit++, dest1it++, dest2it++); 62 } 63 return dest2it; 64 } 65 66 template <class SourceIt, class DestinationIt1, class DestinationIt2, class DestinationIt3> operator ()boost::movelib::move_op67 BOOST_MOVE_FORCEINLINE void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it) 68 { 69 *dest3it = boost::move(*dest2it); 70 *dest2it = boost::move(*dest1it); 71 *dest1it = boost::move(*srcit); 72 } 73 }; 74 75 struct swap_op 76 { 77 template <class SourceIt, class DestinationIt> operator ()boost::movelib::swap_op78 BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest) 79 { boost::adl_move_swap(*dest, *source); } 80 81 template <class SourceIt, class DestinationIt> operator ()boost::movelib::swap_op82 BOOST_MOVE_FORCEINLINE DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin) 83 { return boost::adl_move_swap_ranges(first, last, dest_begin); } 84 85 template <class SourceIt, class DestinationIt> operator ()boost::movelib::swap_op86 BOOST_MOVE_FORCEINLINE DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_begin) 87 { return boost::adl_move_swap_ranges_backward(first, last, dest_begin); } 88 89 template <class SourceIt, class DestinationIt1, class DestinationIt2> operator ()boost::movelib::swap_op90 BOOST_MOVE_FORCEINLINE void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it) 91 { 92 typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest2it)); 93 *dest2it = boost::move(*dest1it); 94 *dest1it = boost::move(*srcit); 95 *srcit = boost::move(tmp); 96 } 97 98 template <class SourceIt, class DestinationIt1, class DestinationIt2> operator ()boost::movelib::swap_op99 DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it) 100 { 101 while(srcit != srcitend){ 102 this->operator()(three_way_t(), srcit++, dest1it++, dest2it++); 103 } 104 return dest2it; 105 } 106 107 template <class SourceIt, class DestinationIt1, class DestinationIt2, class DestinationIt3> operator ()boost::movelib::swap_op108 BOOST_MOVE_FORCEINLINE void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it) 109 { 110 typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest3it)); 111 *dest3it = boost::move(*dest2it); 112 *dest2it = boost::move(*dest1it); 113 *dest1it = boost::move(*srcit); 114 *srcit = boost::move(tmp); 115 } 116 }; 117 118 119 }} //namespace boost::movelib 120 121 #endif //BOOST_MOVE_ALGO_BASIC_OP 122