2
* Copyright 2008-2011 NVIDIA Corporation
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
18
/*! \file reverse_iterator.h
19
* \brief An iterator adaptor which adapts another iterator to traverse backwards.
23
* (C) Copyright David Abrahams 2002.
24
* (C) Copyright Jeremy Siek 2002.
25
* (C) Copyright Thomas Witt 2002.
27
* Distributed under the Boost Software License, Version 1.0.
28
* (See accompanying NOTICE file for the complete license)
30
* For more information, see http://www.boost.org
35
#include <thrust/detail/config.h>
36
#include <thrust/detail/type_traits.h>
37
#include <thrust/iterator/detail/reverse_iterator_base.h>
42
/*! \addtogroup iterators
46
/*! \addtogroup fancyiterator Fancy Iterators
51
/*! \p reverse_iterator is an iterator which represents a pointer into a
52
* reversed view of a given range. In this way, \p reverse_iterator allows
53
* backwards iteration through a bidirectional input range.
55
* It is important to note that although \p reverse_iterator is constructed
56
* from a given iterator, it points to the element preceding it. In this way,
57
* the past-the-end \p reverse_iterator of a given range points to the element
58
* preceding the first element of the input range. By the same token, the first
59
* \p reverse_iterator of a given range is constructed from a past-the-end iterator
60
* of the original range yet points to the last element of the input.
62
* The following code snippet demonstrates how to create a \p reverse_iterator
63
* which represents a reversed view of the contents of a \p device_vector.
66
* #include <thrust/iterator/reverse_iterator.h>
67
* #include <thrust/device_vector.h>
69
* thrust::device_vector<float> v(4);
75
* typedef thrust::device_vector<float>::iterator Iterator;
77
* // note that we point the iterator to the *end* of the device_vector
78
* thrust::reverse_iterator<Iterator> iter(values.end());
80
* *iter; // returns 3.0f;
81
* iter[0]; // returns 3.0f;
82
* iter[1]; // returns 2.0f;
83
* iter[2]; // returns 1.0f;
84
* iter[3]; // returns 0.0f;
86
* // iter[4] is an out-of-bounds error
89
* Since reversing a range is a common operation, containers like \p device_vector
90
* have nested typedefs for declaration shorthand and methods for constructing
91
* reverse_iterators. The following code snippet is equivalent to the previous:
94
* #include <thrust/device_vector.h>
96
* thrust::device_vector<float> v(4);
102
* // we use the nested type reverse_iterator to refer to a reversed view of
103
* // a device_vector and the method rbegin() to create a reverse_iterator pointing
104
* // to the beginning of the reversed device_vector
105
* thrust::device_iterator<float>::reverse_iterator iter = values.rbegin();
107
* *iter; // returns 3.0f;
108
* iter[0]; // returns 3.0f;
109
* iter[1]; // returns 2.0f;
110
* iter[2]; // returns 1.0f;
111
* iter[3]; // returns 0.0f;
113
* // iter[4] is an out-of-bounds error
115
* // similarly, rend() points to the end of the reversed sequence:
116
* assert(values.rend() == (iter + 4));
119
* Finally, the following code snippet demonstrates how to use reverse_iterator to
120
* perform a reversed prefix sum operation on the contents of a device_vector:
123
* #include <thrust/device_vector.h>
124
* #include <thrust/scan.h>
126
* thrust::device_vector<int> v(5);
133
* thrust::device_vector<int> result(5);
135
* // exclusive scan v into result in reverse
136
* thrust::exclusive_scan(v.rbegin(), v.rend(), result.begin());
138
* // result is now {0, 4, 7, 9, 10}
141
* \see make_reverse_iterator
143
template<typename BidirectionalIterator>
144
class reverse_iterator
145
: public detail::reverse_iterator_base<BidirectionalIterator>::type
150
typedef typename thrust::detail::reverse_iterator_base<
151
BidirectionalIterator
154
friend class thrust::experimental::iterator_core_access;
159
/*! Default constructor does nothing.
162
reverse_iterator(void) {}
164
/*! \p Constructor accepts a \c BidirectionalIterator pointing to a range
165
* for this \p reverse_iterator to reverse.
167
* \param x A \c BidirectionalIterator pointing to a range to reverse.
170
explicit reverse_iterator(BidirectionalIterator x);
172
/*! \p Copy constructor allows construction from a related compatible
173
* \p reverse_iterator.
175
* \param r A \p reverse_iterator to copy from.
177
template<typename OtherBidirectionalIterator>
179
reverse_iterator(reverse_iterator<OtherBidirectionalIterator> const &r
180
// XXX msvc screws this up
181
// XXX remove these guards when we have static_assert
183
, typename thrust::detail::enable_if<
184
thrust::detail::is_convertible<
185
OtherBidirectionalIterator,
186
BidirectionalIterator
195
typename super_t::reference dereference(void) const;
198
void increment(void);
201
void decrement(void);
204
void advance(typename super_t::difference_type n);
206
template<typename OtherBidirectionalIterator>
208
typename super_t::difference_type
209
distance_to(reverse_iterator<OtherBidirectionalIterator> const &y) const;
212
}; // end reverse_iterator
215
/*! \p make_reverse_iterator creates a \p reverse_iterator
216
* from a \c BidirectionalIterator pointing to a range of elements to reverse.
218
* \param x A \c BidirectionalIterator pointing to a range to reverse.
219
* \return A new \p reverse_iterator which reverses the range \p x.
221
template<typename BidirectionalIterator>
223
reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x);
226
/*! \} // end fancyiterators
229
/*! \} // end iterators
234
#include <thrust/iterator/detail/reverse_iterator.inl>