1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2012-2012.
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
12//! \file
13
14#ifndef BOOST_MOVE_ALGORITHM_HPP
15#define BOOST_MOVE_ALGORITHM_HPP
16
17#ifndef BOOST_CONFIG_HPP
18# include <boost/config.hpp>
19#endif
20#
21#if defined(BOOST_HAS_PRAGMA_ONCE)
22# pragma once
23#endif
24
25#include <boost/move/detail/config_begin.hpp>
26
27#include <boost/move/utility_core.hpp>
28#include <boost/move/iterator.hpp>
29#include <boost/detail/no_exceptions_support.hpp>
30
31#include <algorithm> //copy, copy_backward
32#include <memory> //uninitialized_copy
33
34namespace boost {
35
36//////////////////////////////////////////////////////////////////////////////
37//
38// move
39//
40//////////////////////////////////////////////////////////////////////////////
41
42#if !defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
43
44 //! <b>Effects</b>: Moves elements in the range [first,last) into the range [result,result + (last -
45 //! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first),
46 //! performs *(result + n) = ::boost::move (*(first + n)).
47 //!
48 //! <b>Effects</b>: result + (last - first).
49 //!
50 //! <b>Requires</b>: result shall not be in the range [first,last).
51 //!
52 //! <b>Complexity</b>: Exactly last - first move assignments.
53 template <typename I, // I models InputIterator
54 typename O> // O models OutputIterator
55 O move(I f, I l, O result)
56 {
57 while (f != l) {
58 *result = ::boost::move(*f);
59 ++f; ++result;
60 }
61 return result;
62 }
63
64 //////////////////////////////////////////////////////////////////////////////
65 //
66 // move_backward
67 //
68 //////////////////////////////////////////////////////////////////////////////
69
70 //! <b>Effects</b>: Moves elements in the range [first,last) into the range
71 //! [result - (last-first),result) starting from last - 1 and proceeding to
72 //! first. For each positive integer n <= (last - first),
73 //! performs *(result - n) = ::boost::move(*(last - n)).
74 //!
75 //! <b>Requires</b>: result shall not be in the range [first,last).
76 //!
77 //! <b>Returns</b>: result - (last - first).
78 //!
79 //! <b>Complexity</b>: Exactly last - first assignments.
80 template <typename I, // I models BidirectionalIterator
81 typename O> // O models BidirectionalIterator
82 O move_backward(I f, I l, O result)
83 {
84 while (f != l) {
85 --l; --result;
86 *result = ::boost::move(*l);
87 }
88 return result;
89 }
90
91#else
92
93 using ::std::move_backward;
94
95#endif //!defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
96
97//////////////////////////////////////////////////////////////////////////////
98//
99// uninitialized_move
100//
101//////////////////////////////////////////////////////////////////////////////
102
103//! <b>Effects</b>:
104//! \code
105//! for (; first != last; ++result, ++first)
106//! new (static_cast<void*>(&*result))
107//! typename iterator_traits<ForwardIterator>::value_type(boost::move(*first));
108//! \endcode
109//!
110//! <b>Returns</b>: result
111template
112 <typename I, // I models InputIterator
113 typename F> // F models ForwardIterator
114F uninitialized_move(I f, I l, F r
115 /// @cond
116// ,typename ::boost::move_detail::enable_if<has_move_emulation_enabled<typename std::iterator_traits<I>::value_type> >::type* = 0
117 /// @endcond
118 )
119{
120 typedef typename std::iterator_traits<I>::value_type input_value_type;
121
122 F back = r;
123 BOOST_TRY{
124 while (f != l) {
125 void * const addr = static_cast<void*>(::boost::move_detail::addressof(*r));
126 ::new(addr) input_value_type(::boost::move(*f));
127 ++f; ++r;
128 }
129 }
130 BOOST_CATCH(...){
131 for (; back != r; ++back){
132 back->~input_value_type();
133 }
134 BOOST_RETHROW;
135 }
136 BOOST_CATCH_END
137 return r;
138}
139
140/// @cond
141/*
142template
143 <typename I, // I models InputIterator
144 typename F> // F models ForwardIterator
145F uninitialized_move(I f, I l, F r,
146 typename ::boost::move_detail::disable_if<has_move_emulation_enabled<typename std::iterator_traits<I>::value_type> >::type* = 0)
147{
148 return std::uninitialized_copy(f, l, r);
149}
150*/
151
152//////////////////////////////////////////////////////////////////////////////
153//
154// uninitialized_copy_or_move
155//
156//////////////////////////////////////////////////////////////////////////////
157
158namespace move_detail {
159
160template
161<typename I, // I models InputIterator
162typename F> // F models ForwardIterator
163inline F uninitialized_move_move_iterator(I f, I l, F r
164// ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0
165)
166{
167 return ::boost::uninitialized_move(f, l, r);
168}
169/*
170template
171<typename I, // I models InputIterator
172typename F> // F models ForwardIterator
173F uninitialized_move_move_iterator(I f, I l, F r,
174 typename ::boost::move_detail::disable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0)
175{
176 return std::uninitialized_copy(f.base(), l.base(), r);
177}
178*/
179} //namespace move_detail {
180
181template
182<typename I, // I models InputIterator
183typename F> // F models ForwardIterator
184inline F uninitialized_copy_or_move(I f, I l, F r,
185 typename ::boost::move_detail::enable_if< move_detail::is_move_iterator<I> >::type* = 0)
186{
187 return ::boost::move_detail::uninitialized_move_move_iterator(f, l, r);
188}
189
190//////////////////////////////////////////////////////////////////////////////
191//
192// copy_or_move
193//
194//////////////////////////////////////////////////////////////////////////////
195
196namespace move_detail {
197
198template
199<typename I, // I models InputIterator
200typename F> // F models ForwardIterator
201inline F move_move_iterator(I f, I l, F r
202// ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0
203)
204{
205 return ::boost::move(f, l, r);
206}
207/*
208template
209<typename I, // I models InputIterator
210typename F> // F models ForwardIterator
211F move_move_iterator(I f, I l, F r,
212 typename ::boost::move_detail::disable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0)
213{
214 return std::copy(f.base(), l.base(), r);
215}
216*/
217
218} //namespace move_detail {
219
220template
221<typename I, // I models InputIterator
222typename F> // F models ForwardIterator
223inline F copy_or_move(I f, I l, F r,
224 typename ::boost::move_detail::enable_if< move_detail::is_move_iterator<I> >::type* = 0)
225{
226 return ::boost::move_detail::move_move_iterator(f, l, r);
227}
228
229/// @endcond
230
231//! <b>Effects</b>:
232//! \code
233//! for (; first != last; ++result, ++first)
234//! new (static_cast<void*>(&*result))
235//! typename iterator_traits<ForwardIterator>::value_type(*first);
236//! \endcode
237//!
238//! <b>Returns</b>: result
239//!
240//! <b>Note</b>: This function is provided because
241//! <i>std::uninitialized_copy</i> from some STL implementations
242//! is not compatible with <i>move_iterator</i>
243template
244<typename I, // I models InputIterator
245typename F> // F models ForwardIterator
246inline F uninitialized_copy_or_move(I f, I l, F r
247 /// @cond
248 ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator<I> >::type* = 0
249 /// @endcond
250 )
251{
252 return std::uninitialized_copy(f, l, r);
253}
254
255//! <b>Effects</b>:
256//! \code
257//! for (; first != last; ++result, ++first)
258//! *result = *first;
259//! \endcode
260//!
261//! <b>Returns</b>: result
262//!
263//! <b>Note</b>: This function is provided because
264//! <i>std::uninitialized_copy</i> from some STL implementations
265//! is not compatible with <i>move_iterator</i>
266template
267<typename I, // I models InputIterator
268typename F> // F models ForwardIterator
269inline F copy_or_move(I f, I l, F r
270 /// @cond
271 ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator<I> >::type* = 0
272 /// @endcond
273 )
274{
275 return std::copy(f, l, r);
276}
277
278} //namespace boost {
279
280#include <boost/move/detail/config_end.hpp>
281
282#endif //#ifndef BOOST_MOVE_ALGORITHM_HPP
283