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

« back to all changes in this revision

Viewing changes to iterator/counting_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 counting_iterator.h
 
19
 *  \brief Defines the interface to an iterator
 
20
 *         which adapts an incrementable type
 
21
 *         to return the current value of the incrementable
 
22
 *         upon operator*(). Based on Boost's counting_iterator
 
23
 *         class.
 
24
 */
 
25
 
 
26
/*
 
27
 * Copyright David Abrahams 2003.
 
28
 * 
 
29
 * Distributed under the Boost Software License, Version 1.0.
 
30
 * (See accompanying NOTICE file for the complete license)
 
31
 *
 
32
 * For more information, see http://www.boost.org
 
33
 */
 
34
 
 
35
#pragma once
 
36
 
 
37
#include <thrust/detail/config.h>
 
38
#include <thrust/iterator/iterator_adaptor.h>
 
39
#include <thrust/iterator/iterator_categories.h>
 
40
 
 
41
// #include the details first
 
42
#include <thrust/iterator/detail/counting_iterator.inl>
 
43
 
 
44
namespace thrust
 
45
{
 
46
 
 
47
/*! \addtogroup iterators
 
48
 *  \{
 
49
 */
 
50
 
 
51
/*! \addtogroup fancyiterator Fancy Iterators
 
52
 *  \ingroup iterators
 
53
 *  \{
 
54
 */
 
55
 
 
56
/*! \p counting_iterator is an iterator which represents a pointer into a range
 
57
 *  of sequentially changing values. This iterator is useful for creating a range
 
58
 *  filled with a sequence without explicitly storing it in memory. Using
 
59
 *  \p counting_iterator saves memory capacity and bandwidth.
 
60
 *
 
61
 *  The following code snippet demonstrates how to create a \p counting_iterator whose
 
62
 *  \c value_type is \c int and which sequentially increments by \c 1.
 
63
 *
 
64
 *  \code
 
65
 *  #include <thrust/iterator/counting_iterator.h>
 
66
 *  ...
 
67
 *  // create iterators
 
68
 *  thrust::counting_iterator<int> first(10);
 
69
 *  thrust::counting_iterator<int> last = first + 3;
 
70
 *   
 
71
 *  first[0]   // returns 10
 
72
 *  first[1]   // returns 11
 
73
 *  first[100] // returns 110
 
74
 *   
 
75
 *  // sum of [first, last)
 
76
 *  thrust::reduce(first, last);   // returns 33 (i.e. 10 + 11 + 12)
 
77
 *   
 
78
 *  // initialize vector to [0,1,2,..]
 
79
 *  thrust::counting_iterator<int> iter(0);
 
80
 *  thrust::device_vector<int> vec(500);
 
81
 *  thrust::copy(iter, iter + vec.size(), vec.begin());
 
82
 *  \endcode
 
83
 *
 
84
 *  This next example demonstrates how to use a \p counting_iterator with the
 
85
 *  \p thrust::copy_if function to compute the indices of the non-zero elements
 
86
 *  of a \p device_vector. In this example, we use the \p make_counting_iterator
 
87
 *  function to avoid specifying the type of the \p counting_iterator.
 
88
 *
 
89
 *  \code
 
90
 *  #include <thrust/iterator/counting_iterator.h>
 
91
 *  #include <thrust/copy.h>
 
92
 *  #include <thrust/functional.h>
 
93
 *  #include <thrust/device_vector.h>
 
94
 *   
 
95
 *  int main(void)
 
96
 *  {
 
97
 *   // this example computes indices for all the nonzero values in a sequence
 
98
 *   
 
99
 *   // sequence of zero and nonzero values
 
100
 *   thrust::device_vector<int> stencil(8);
 
101
 *   stencil[0] = 0;
 
102
 *   stencil[1] = 1;
 
103
 *   stencil[2] = 1;
 
104
 *   stencil[3] = 0;
 
105
 *   stencil[4] = 0;
 
106
 *   stencil[5] = 1;
 
107
 *   stencil[6] = 0;
 
108
 *   stencil[7] = 1;
 
109
 *   
 
110
 *   // storage for the nonzero indices
 
111
 *   thrust::device_vector<int> indices(8);
 
112
 *   
 
113
 *   // compute indices of nonzero elements
 
114
 *   typedef thrust::device_vector<int>::iterator IndexIterator;
 
115
 *   
 
116
 *   // use make_counting_iterator to define the sequence [0, 8)
 
117
 *   IndexIterator indices_end = thrust::copy_if(thrust::make_counting_iterator(0),
 
118
 *                                               thrust::make_counting_iterator(8),
 
119
 *                                               stencil.begin(),
 
120
 *                                               indices.begin(),
 
121
 *                                               thrust::identity<int>());
 
122
 *   // indices now contains [1,2,5,7]
 
123
 *   
 
124
 *   return 0;
 
125
 *  }
 
126
 *  \endcode
 
127
 *
 
128
 *  \see make_counting_iterator
 
129
 */
 
130
template<typename Incrementable,
 
131
         typename Space = use_default,
 
132
         typename Traversal = use_default,
 
133
         typename Difference = use_default>
 
134
  class counting_iterator
 
135
    : public detail::counting_iterator_base<Incrementable, Space, Traversal, Difference>::type
 
136
{
 
137
    /*! \cond
 
138
     */
 
139
    typedef typename detail::counting_iterator_base<Incrementable, Space, Traversal, Difference>::type super_t;
 
140
 
 
141
    friend class thrust::experimental::iterator_core_access;
 
142
 
 
143
  public:
 
144
    typedef typename super_t::reference       reference;
 
145
    typedef typename super_t::difference_type difference_type;
 
146
 
 
147
    /*! \endcond
 
148
     */
 
149
 
 
150
    /*! Null constructor initializes this \p counting_iterator's \c Incrementable
 
151
     *  counter using its null constructor.
 
152
     */
 
153
    __host__ __device__
 
154
    counting_iterator(void){};
 
155
 
 
156
    /*! Copy constructor copies the value of another \p counting_iterator into a
 
157
     *  new \p counting_iterator.
 
158
     *
 
159
     *  \p rhs The \p counting_iterator to copy.
 
160
     */
 
161
    __host__ __device__
 
162
    counting_iterator(counting_iterator const &rhs):super_t(rhs.base()){}
 
163
 
 
164
    /*! Copy constructor copies the value of another counting_iterator 
 
165
     *  with related Space type.
 
166
     *
 
167
     *  \param rhs The \p counting_iterator to copy.
 
168
     */
 
169
    template<typename OtherSpace>
 
170
    __host__ __device__
 
171
    counting_iterator(counting_iterator<Incrementable, OtherSpace, Traversal, Difference> const &rhs,
 
172
                      typename thrust::detail::enable_if_convertible<
 
173
                        typename thrust::iterator_space<counting_iterator<Incrementable,OtherSpace,Traversal,Difference> >::type,
 
174
                        typename thrust::iterator_space<super_t>::type
 
175
                      >::type * = 0)
 
176
      : super_t(rhs.base()){}
 
177
 
 
178
    /*! This \c explicit constructor copies the value of an \c Incrementable
 
179
     *  into a new \p counting_iterator's \c Incrementable counter.
 
180
     *  
 
181
     *  \param x The initial value of the new \p counting_iterator's \c Incrementable
 
182
     *         counter.
 
183
     */
 
184
    __host__ __device__
 
185
    explicit counting_iterator(Incrementable x):super_t(x){}
 
186
 
 
187
    /*! \cond
 
188
     */
 
189
  private:
 
190
    reference dereference(void) const
 
191
    {
 
192
      return this->base_reference();
 
193
    }
 
194
 
 
195
    template <class OtherIncrementable>
 
196
    __host__ __device__
 
197
    difference_type
 
198
    distance_to(counting_iterator<OtherIncrementable, Space, Traversal, Difference> const& y) const
 
199
    {
 
200
      typedef typename
 
201
      thrust::detail::eval_if<
 
202
        thrust::detail::is_numeric<Incrementable>::value,
 
203
        thrust::detail::identity_<thrust::detail::number_distance<difference_type, Incrementable, OtherIncrementable> >,
 
204
        thrust::detail::identity_<thrust::detail::iterator_distance<difference_type, Incrementable, OtherIncrementable> >
 
205
      >::type d;
 
206
 
 
207
      return d::distance(this->base(), y.base());
 
208
    }
 
209
 
 
210
    /*! \endcond
 
211
     */
 
212
}; // end counting_iterator
 
213
 
 
214
 
 
215
/*! \p make_counting_iterator creates a \p counting_iterator
 
216
 *  using an initial value for its \c Incrementable counter.
 
217
 *
 
218
 *  \param x The initial value of the new \p counting_iterator's counter.
 
219
 *  \return A new \p counting_iterator whose counter has been initialized to \p x.
 
220
 */
 
221
template <typename Incrementable>
 
222
inline __host__ __device__
 
223
counting_iterator<Incrementable> make_counting_iterator(Incrementable x)
 
224
{
 
225
  return counting_iterator<Incrementable>(x);
 
226
}
 
227
 
 
228
/*! \} // end fancyiterators
 
229
 */
 
230
 
 
231
/*! \} // end iterators
 
232
 */
 
233
 
 
234
} // end thrust
 
235