blob: 12339b0415577b11951161f92af188c004521746 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001//////////////////////////////////////////////////////////////////////////////
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_ITERATOR_HPP
15#define BOOST_MOVE_ITERATOR_HPP
16
17#include <ndnboost/move/detail/config_begin.hpp>
18#include <ndnboost/move/utility.hpp>
19#include <iterator> //std::iterator
20
21namespace ndnboost {
22
23//////////////////////////////////////////////////////////////////////////////
24//
25// move_iterator
26//
27//////////////////////////////////////////////////////////////////////////////
28
29//! Class template move_iterator is an iterator adaptor with the same behavior
30//! as the underlying iterator except that its dereference operator implicitly
31//! converts the value returned by the underlying iterator's dereference operator
32//! to an rvalue reference. Some generic algorithms can be called with move
33//! iterators to replace copying with moving.
34template <class It>
35class move_iterator
36{
37 public:
38 typedef It iterator_type;
39 typedef typename std::iterator_traits<iterator_type>::value_type value_type;
40 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
41 typedef value_type && reference;
42 #else
43 typedef typename ::ndnboost::move_detail::if_
44 < ::ndnboost::has_move_emulation_enabled<value_type>
45 , ::ndnboost::rv<value_type>&
46 , value_type & >::type reference;
47 #endif
48 typedef It pointer;
49 typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
50 typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
51
52 move_iterator()
53 {}
54
55 explicit move_iterator(It i)
56 : m_it(i)
57 {}
58
59 template <class U>
60 move_iterator(const move_iterator<U>& u)
61 : m_it(u.base())
62 {}
63
64 iterator_type base() const
65 { return m_it; }
66
67 reference operator*() const
68 {
69 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
70 return *m_it;
71 #else
72 return ::ndnboost::move(*m_it);
73 #endif
74 }
75
76 pointer operator->() const
77 { return m_it; }
78
79 move_iterator& operator++()
80 { ++m_it; return *this; }
81
82 move_iterator<iterator_type> operator++(int)
83 { move_iterator<iterator_type> tmp(*this); ++(*this); return tmp; }
84
85 move_iterator& operator--()
86 { --m_it; return *this; }
87
88 move_iterator<iterator_type> operator--(int)
89 { move_iterator<iterator_type> tmp(*this); --(*this); return tmp; }
90
91 move_iterator<iterator_type> operator+ (difference_type n) const
92 { return move_iterator<iterator_type>(m_it + n); }
93
94 move_iterator& operator+=(difference_type n)
95 { m_it += n; return *this; }
96
97 move_iterator<iterator_type> operator- (difference_type n) const
98 { return move_iterator<iterator_type>(m_it - n); }
99
100 move_iterator& operator-=(difference_type n)
101 { m_it -= n; return *this; }
102
103 reference operator[](difference_type n) const
104 {
105 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
106 return m_it[n];
107 #else
108 return ::ndnboost::move(m_it[n]);
109 #endif
110 }
111
112 friend bool operator==(const move_iterator& x, const move_iterator& y)
113 { return x.base() == y.base(); }
114
115 friend bool operator!=(const move_iterator& x, const move_iterator& y)
116 { return x.base() != y.base(); }
117
118 friend bool operator< (const move_iterator& x, const move_iterator& y)
119 { return x.base() < y.base(); }
120
121 friend bool operator<=(const move_iterator& x, const move_iterator& y)
122 { return x.base() <= y.base(); }
123
124 friend bool operator> (const move_iterator& x, const move_iterator& y)
125 { return x.base() > y.base(); }
126
127 friend bool operator>=(const move_iterator& x, const move_iterator& y)
128 { return x.base() >= y.base(); }
129
130 friend difference_type operator-(const move_iterator& x, const move_iterator& y)
131 { return x.base() - y.base(); }
132
133 friend move_iterator operator+(difference_type n, const move_iterator& x)
134 { return move_iterator(x.base() + n); }
135
136 private:
137 It m_it;
138};
139
140//is_move_iterator
141namespace move_detail {
142
143template <class I>
144struct is_move_iterator
145 : public ::ndnboost::move_detail::integral_constant<bool, false>
146{
147};
148
149template <class I>
150struct is_move_iterator< ::ndnboost::move_iterator<I> >
151 : public ::ndnboost::move_detail::integral_constant<bool, true>
152{
153};
154
155} //namespace move_detail {
156
157//////////////////////////////////////////////////////////////////////////////
158//
159// move_iterator
160//
161//////////////////////////////////////////////////////////////////////////////
162
163//!
164//! <b>Returns</b>: move_iterator<It>(i).
165template<class It>
166inline move_iterator<It> make_move_iterator(const It &it)
167{ return move_iterator<It>(it); }
168
169//////////////////////////////////////////////////////////////////////////////
170//
171// back_move_insert_iterator
172//
173//////////////////////////////////////////////////////////////////////////////
174
175
176//! A move insert iterator that move constructs elements at the
177//! back of a container
178template <typename C> // C models Container
179class back_move_insert_iterator
180 : public std::iterator<std::output_iterator_tag, void, void, void, void>
181{
182 C* container_m;
183
184 public:
185 typedef C container_type;
186 typedef typename C::value_type value_type;
187 typedef typename C::reference reference;
188
189 explicit back_move_insert_iterator(C& x) : container_m(&x) { }
190
191 back_move_insert_iterator& operator=(reference x)
192 { container_m->push_back(ndnboost::move(x)); return *this; }
193
194 back_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
195 { reference rx = x; return this->operator=(rx); }
196
197 back_move_insert_iterator& operator*() { return *this; }
198 back_move_insert_iterator& operator++() { return *this; }
199 back_move_insert_iterator& operator++(int) { return *this; }
200};
201
202//!
203//! <b>Returns</b>: back_move_insert_iterator<C>(x).
204template <typename C> // C models Container
205inline back_move_insert_iterator<C> back_move_inserter(C& x)
206{
207 return back_move_insert_iterator<C>(x);
208}
209
210//////////////////////////////////////////////////////////////////////////////
211//
212// front_move_insert_iterator
213//
214//////////////////////////////////////////////////////////////////////////////
215
216//! A move insert iterator that move constructs elements int the
217//! front of a container
218template <typename C> // C models Container
219class front_move_insert_iterator
220 : public std::iterator<std::output_iterator_tag, void, void, void, void>
221{
222 C* container_m;
223
224public:
225 typedef C container_type;
226 typedef typename C::value_type value_type;
227 typedef typename C::reference reference;
228
229 explicit front_move_insert_iterator(C& x) : container_m(&x) { }
230
231 front_move_insert_iterator& operator=(reference x)
232 { container_m->push_front(ndnboost::move(x)); return *this; }
233
234 front_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
235 { reference rx = x; return this->operator=(rx); }
236
237 front_move_insert_iterator& operator*() { return *this; }
238 front_move_insert_iterator& operator++() { return *this; }
239 front_move_insert_iterator& operator++(int) { return *this; }
240};
241
242//!
243//! <b>Returns</b>: front_move_insert_iterator<C>(x).
244template <typename C> // C models Container
245inline front_move_insert_iterator<C> front_move_inserter(C& x)
246{
247 return front_move_insert_iterator<C>(x);
248}
249
250//////////////////////////////////////////////////////////////////////////////
251//
252// insert_move_iterator
253//
254//////////////////////////////////////////////////////////////////////////////
255template <typename C> // C models Container
256class move_insert_iterator
257 : public std::iterator<std::output_iterator_tag, void, void, void, void>
258{
259 C* container_m;
260 typename C::iterator pos_;
261
262 public:
263 typedef C container_type;
264 typedef typename C::value_type value_type;
265 typedef typename C::reference reference;
266
267 explicit move_insert_iterator(C& x, typename C::iterator pos)
268 : container_m(&x), pos_(pos)
269 {}
270
271 move_insert_iterator& operator=(reference x)
272 {
273 pos_ = container_m->insert(pos_, ::ndnboost::move(x));
274 ++pos_;
275 return *this;
276 }
277
278 move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
279 { reference rx = x; return this->operator=(rx); }
280
281 move_insert_iterator& operator*() { return *this; }
282 move_insert_iterator& operator++() { return *this; }
283 move_insert_iterator& operator++(int) { return *this; }
284};
285
286//!
287//! <b>Returns</b>: move_insert_iterator<C>(x, it).
288template <typename C> // C models Container
289inline move_insert_iterator<C> move_inserter(C& x, typename C::iterator it)
290{
291 return move_insert_iterator<C>(x, it);
292}
293
294} //namespace ndnboost {
295
296#include <ndnboost/move/detail/config_end.hpp>
297
298#endif //#ifndef BOOST_MOVE_ITERATOR_HPP