• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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