~ubuntu-branches/ubuntu/trusty/libthrust/trusty

« back to all changes in this revision

Viewing changes to iterator/reverse_iterator.h

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Beckmann
  • Date: 2011-05-28 09:32:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110528093248-np3euv5sj7fw3nyv
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright 2008-2011 NVIDIA Corporation
 
3
 *
 
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
 
7
 *
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
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.
 
15
 */
 
16
 
 
17
 
 
18
/*! \file reverse_iterator.h
 
19
 *  \brief An iterator adaptor which adapts another iterator to traverse backwards.
 
20
 */
 
21
 
 
22
/*
 
23
 * (C) Copyright David Abrahams 2002.
 
24
 * (C) Copyright Jeremy Siek    2002.
 
25
 * (C) Copyright Thomas Witt    2002.
 
26
 * 
 
27
 * Distributed under the Boost Software License, Version 1.0.
 
28
 * (See accompanying NOTICE file for the complete license)
 
29
 *
 
30
 * For more information, see http://www.boost.org
 
31
 */
 
32
 
 
33
#pragma once
 
34
 
 
35
#include <thrust/detail/config.h>
 
36
#include <thrust/detail/type_traits.h>
 
37
#include <thrust/iterator/detail/reverse_iterator_base.h>
 
38
 
 
39
namespace thrust
 
40
{
 
41
 
 
42
/*! \addtogroup iterators
 
43
 *  \{
 
44
 */
 
45
 
 
46
/*! \addtogroup fancyiterator Fancy Iterators
 
47
 *  \ingroup iterators
 
48
 *  \{
 
49
 */
 
50
 
 
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.
 
54
 *
 
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.
 
61
 *
 
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.
 
64
 *
 
65
 *  \code
 
66
 *  #include <thrust/iterator/reverse_iterator.h>
 
67
 *  #include <thrust/device_vector.h>
 
68
 *  ...
 
69
 *  thrust::device_vector<float> v(4);
 
70
 *  v[0] = 0.0f;
 
71
 *  v[1] = 1.0f;
 
72
 *  v[2] = 2.0f;
 
73
 *  v[3] = 3.0f;
 
74
 *
 
75
 *  typedef thrust::device_vector<float>::iterator Iterator;
 
76
 *
 
77
 *  // note that we point the iterator to the *end* of the device_vector
 
78
 *  thrust::reverse_iterator<Iterator> iter(values.end());
 
79
 *
 
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;
 
85
 *
 
86
 *  // iter[4] is an out-of-bounds error
 
87
 *  \endcode
 
88
 *
 
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:
 
92
 *
 
93
 *  \code
 
94
 *  #include <thrust/device_vector.h>
 
95
 *  ...
 
96
 *  thrust::device_vector<float> v(4);
 
97
 *  v[0] = 0.0f;
 
98
 *  v[1] = 1.0f;
 
99
 *  v[2] = 2.0f;
 
100
 *  v[3] = 3.0f;
 
101
 *
 
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();
 
106
 *
 
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;
 
112
 *
 
113
 *  // iter[4] is an out-of-bounds error
 
114
 *
 
115
 *  // similarly, rend() points to the end of the reversed sequence:
 
116
 *  assert(values.rend() == (iter + 4));
 
117
 *  \endcode
 
118
 *
 
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:
 
121
 *
 
122
 *  \code
 
123
 *  #include <thrust/device_vector.h>
 
124
 *  #include <thrust/scan.h>
 
125
 *  ...
 
126
 *  thrust::device_vector<int> v(5);
 
127
 *  v[0] = 0;
 
128
 *  v[1] = 1;
 
129
 *  v[2] = 2;
 
130
 *  v[3] = 3;
 
131
 *  v[4] = 4;
 
132
 *
 
133
 *  thrust::device_vector<int> result(5);
 
134
 *
 
135
 *  // exclusive scan v into result in reverse
 
136
 *  thrust::exclusive_scan(v.rbegin(), v.rend(), result.begin());
 
137
 *
 
138
 *  // result is now {0, 4, 7, 9, 10}
 
139
 *  \endcode
 
140
 *
 
141
 *  \see make_reverse_iterator
 
142
 */
 
143
template<typename BidirectionalIterator>
 
144
  class reverse_iterator
 
145
    : public detail::reverse_iterator_base<BidirectionalIterator>::type
 
146
{
 
147
  /*! \cond
 
148
   */
 
149
  private:
 
150
    typedef typename thrust::detail::reverse_iterator_base<
 
151
      BidirectionalIterator
 
152
    >::type super_t;
 
153
 
 
154
    friend class thrust::experimental::iterator_core_access;
 
155
  /*! \endcond
 
156
   */
 
157
 
 
158
  public:
 
159
    /*! Default constructor does nothing.
 
160
     */
 
161
    __host__ __device__
 
162
    reverse_iterator(void) {}
 
163
 
 
164
    /*! \p Constructor accepts a \c BidirectionalIterator pointing to a range
 
165
     *  for this \p reverse_iterator to reverse.
 
166
     *
 
167
     *  \param x A \c BidirectionalIterator pointing to a range to reverse.
 
168
     */
 
169
    __host__ __device__
 
170
    explicit reverse_iterator(BidirectionalIterator x);
 
171
 
 
172
    /*! \p Copy constructor allows construction from a related compatible
 
173
     *  \p reverse_iterator.
 
174
     *
 
175
     *  \param r A \p reverse_iterator to copy from.
 
176
     */
 
177
    template<typename OtherBidirectionalIterator>
 
178
    __host__ __device__
 
179
    reverse_iterator(reverse_iterator<OtherBidirectionalIterator> const &r
 
180
// XXX msvc screws this up
 
181
// XXX remove these guards when we have static_assert
 
182
#ifndef _MSC_VER
 
183
                     , typename thrust::detail::enable_if<
 
184
                         thrust::detail::is_convertible<
 
185
                           OtherBidirectionalIterator,
 
186
                           BidirectionalIterator
 
187
                         >::value
 
188
                       >::type * = 0
 
189
#endif // _MSC_VER
 
190
                     );
 
191
 
 
192
  /*! \cond
 
193
   */
 
194
  private:
 
195
    typename super_t::reference dereference(void) const;
 
196
 
 
197
    __host__ __device__
 
198
    void increment(void);
 
199
 
 
200
    __host__ __device__
 
201
    void decrement(void);
 
202
 
 
203
    __host__ __device__
 
204
    void advance(typename super_t::difference_type n);
 
205
 
 
206
    template<typename OtherBidirectionalIterator>
 
207
    __host__ __device__
 
208
    typename super_t::difference_type
 
209
    distance_to(reverse_iterator<OtherBidirectionalIterator> const &y) const;
 
210
  /*! \endcond
 
211
   */
 
212
}; // end reverse_iterator
 
213
 
 
214
 
 
215
/*! \p make_reverse_iterator creates a \p reverse_iterator
 
216
 *  from a \c BidirectionalIterator pointing to a range of elements to reverse.
 
217
 *  
 
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.
 
220
 */
 
221
template<typename BidirectionalIterator>
 
222
__host__ __device__
 
223
reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x);
 
224
 
 
225
 
 
226
/*! \} // end fancyiterators
 
227
 */
 
228
 
 
229
/*! \} // end iterators
 
230
 */
 
231
 
 
232
} // end thrust
 
233
 
 
234
#include <thrust/iterator/detail/reverse_iterator.inl>
 
235