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
26namespace boost {
27namespace movelib {
28
29struct forward_t{};
30struct backward_t{};
31struct three_way_t{};
32struct three_way_forward_t{};
33struct four_way_t{};
34
35struct move_op
36{
37 template <class SourceIt, class DestinationIt>
38 BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest)
39 { *dest = ::boost::move(*source); }
40
41 template <class SourceIt, class DestinationIt>
42 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>
46 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>
50 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>
57 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>
67 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
75struct swap_op
76{
77 template <class SourceIt, class DestinationIt>
78 BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest)
79 { boost::adl_move_swap(*dest, *source); }
80
81 template <class SourceIt, class DestinationIt>
82 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>
86 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>
90 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>
99 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>
108 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