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 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
27
* Copyright David Abrahams 2003.
29
* Distributed under the Boost Software License, Version 1.0.
30
* (See accompanying NOTICE file for the complete license)
32
* For more information, see http://www.boost.org
37
#include <thrust/detail/config.h>
38
#include <thrust/iterator/iterator_adaptor.h>
39
#include <thrust/iterator/iterator_categories.h>
41
// #include the details first
42
#include <thrust/iterator/detail/counting_iterator.inl>
47
/*! \addtogroup iterators
51
/*! \addtogroup fancyiterator Fancy Iterators
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.
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.
65
* #include <thrust/iterator/counting_iterator.h>
68
* thrust::counting_iterator<int> first(10);
69
* thrust::counting_iterator<int> last = first + 3;
71
* first[0] // returns 10
72
* first[1] // returns 11
73
* first[100] // returns 110
75
* // sum of [first, last)
76
* thrust::reduce(first, last); // returns 33 (i.e. 10 + 11 + 12)
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());
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.
90
* #include <thrust/iterator/counting_iterator.h>
91
* #include <thrust/copy.h>
92
* #include <thrust/functional.h>
93
* #include <thrust/device_vector.h>
97
* // this example computes indices for all the nonzero values in a sequence
99
* // sequence of zero and nonzero values
100
* thrust::device_vector<int> stencil(8);
110
* // storage for the nonzero indices
111
* thrust::device_vector<int> indices(8);
113
* // compute indices of nonzero elements
114
* typedef thrust::device_vector<int>::iterator IndexIterator;
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),
121
* thrust::identity<int>());
122
* // indices now contains [1,2,5,7]
128
* \see make_counting_iterator
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
139
typedef typename detail::counting_iterator_base<Incrementable, Space, Traversal, Difference>::type super_t;
141
friend class thrust::experimental::iterator_core_access;
144
typedef typename super_t::reference reference;
145
typedef typename super_t::difference_type difference_type;
150
/*! Null constructor initializes this \p counting_iterator's \c Incrementable
151
* counter using its null constructor.
154
counting_iterator(void){};
156
/*! Copy constructor copies the value of another \p counting_iterator into a
157
* new \p counting_iterator.
159
* \p rhs The \p counting_iterator to copy.
162
counting_iterator(counting_iterator const &rhs):super_t(rhs.base()){}
164
/*! Copy constructor copies the value of another counting_iterator
165
* with related Space type.
167
* \param rhs The \p counting_iterator to copy.
169
template<typename OtherSpace>
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
176
: super_t(rhs.base()){}
178
/*! This \c explicit constructor copies the value of an \c Incrementable
179
* into a new \p counting_iterator's \c Incrementable counter.
181
* \param x The initial value of the new \p counting_iterator's \c Incrementable
185
explicit counting_iterator(Incrementable x):super_t(x){}
190
reference dereference(void) const
192
return this->base_reference();
195
template <class OtherIncrementable>
198
distance_to(counting_iterator<OtherIncrementable, Space, Traversal, Difference> const& y) const
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> >
207
return d::distance(this->base(), y.base());
212
}; // end counting_iterator
215
/*! \p make_counting_iterator creates a \p counting_iterator
216
* using an initial value for its \c Incrementable counter.
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.
221
template <typename Incrementable>
222
inline __host__ __device__
223
counting_iterator<Incrementable> make_counting_iterator(Incrementable x)
225
return counting_iterator<Incrementable>(x);
228
/*! \} // end fancyiterators
231
/*! \} // end iterators