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