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> |
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 | |
75 | struct 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 | |