/* * Copyright 2008-2012 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*! \file thrust/iterator/counting_iterator.h * \brief An iterator which returns an increasing incrementable value * when dereferenced */ /* * Copyright David Abrahams 2003. * * Distributed under the Boost Software License, Version 1.0. * (See accompanying NOTICE file for the complete license) * * For more information, see http://www.boost.org */ #pragma once #include #include #include #include // #include the details first #include namespace thrust { /*! \addtogroup iterators * \{ */ /*! \addtogroup fancyiterator Fancy Iterators * \ingroup iterators * \{ */ /*! \p counting_iterator is an iterator which represents a pointer into a range * of sequentially changing values. This iterator is useful for creating a range * filled with a sequence without explicitly storing it in memory. Using * \p counting_iterator saves memory capacity and bandwidth. * * The following code snippet demonstrates how to create a \p counting_iterator whose * \c value_type is \c int and which sequentially increments by \c 1. * * \code * #include * ... * // create iterators * thrust::counting_iterator first(10); * thrust::counting_iterator last = first + 3; * * first[0] // returns 10 * first[1] // returns 11 * first[100] // returns 110 * * // sum of [first, last) * thrust::reduce(first, last); // returns 33 (i.e. 10 + 11 + 12) * * // initialize vector to [0,1,2,..] * thrust::counting_iterator iter(0); * thrust::device_vector vec(500); * thrust::copy(iter, iter + vec.size(), vec.begin()); * \endcode * * This next example demonstrates how to use a \p counting_iterator with the * \p thrust::copy_if function to compute the indices of the non-zero elements * of a \p device_vector. In this example, we use the \p make_counting_iterator * function to avoid specifying the type of the \p counting_iterator. * * \code * #include * #include * #include * #include * * int main(void) * { * // this example computes indices for all the nonzero values in a sequence * * // sequence of zero and nonzero values * thrust::device_vector stencil(8); * stencil[0] = 0; * stencil[1] = 1; * stencil[2] = 1; * stencil[3] = 0; * stencil[4] = 0; * stencil[5] = 1; * stencil[6] = 0; * stencil[7] = 1; * * // storage for the nonzero indices * thrust::device_vector indices(8); * * // compute indices of nonzero elements * typedef thrust::device_vector::iterator IndexIterator; * * // use make_counting_iterator to define the sequence [0, 8) * IndexIterator indices_end = thrust::copy_if(thrust::make_counting_iterator(0), * thrust::make_counting_iterator(8), * stencil.begin(), * indices.begin(), * thrust::identity()); * // indices now contains [1,2,5,7] * * return 0; * } * \endcode * * \see make_counting_iterator */ template class counting_iterator : public detail::counting_iterator_base::type { /*! \cond */ typedef typename detail::counting_iterator_base::type super_t; friend class thrust::iterator_core_access; public: typedef typename super_t::reference reference; typedef typename super_t::difference_type difference_type; /*! \endcond */ /*! Null constructor initializes this \p counting_iterator's \c Incrementable * counter using its null constructor. */ __host__ __device__ counting_iterator(void){}; /*! Copy constructor copies the value of another \p counting_iterator into a * new \p counting_iterator. * * \p rhs The \p counting_iterator to copy. */ __host__ __device__ counting_iterator(counting_iterator const &rhs):super_t(rhs.base()){} /*! Copy constructor copies the value of another counting_iterator * with related System type. * * \param rhs The \p counting_iterator to copy. */ template __host__ __device__ counting_iterator(counting_iterator const &rhs, typename thrust::detail::enable_if_convertible< typename thrust::iterator_system >::type, typename thrust::iterator_system::type >::type * = 0) : super_t(rhs.base()){} /*! This \c explicit constructor copies the value of an \c Incrementable * into a new \p counting_iterator's \c Incrementable counter. * * \param x The initial value of the new \p counting_iterator's \c Incrementable * counter. */ __host__ __device__ explicit counting_iterator(Incrementable x):super_t(x){} /*! \cond */ private: __host__ __device__ reference dereference(void) const { return this->base_reference(); } // note that we implement equal specially for floating point counting_iterator template __host__ __device__ bool equal(counting_iterator const& y) const { typedef thrust::detail::counting_iterator_equal e; return e::equal(this->base(), y.base()); } template __host__ __device__ difference_type distance_to(counting_iterator const& y) const { typedef typename thrust::detail::eval_if< thrust::detail::is_numeric::value, thrust::detail::identity_ >, thrust::detail::identity_ > >::type d; return d::distance(this->base(), y.base()); } /*! \endcond */ }; // end counting_iterator /*! \p make_counting_iterator creates a \p counting_iterator * using an initial value for its \c Incrementable counter. * * \param x The initial value of the new \p counting_iterator's counter. * \return A new \p counting_iterator whose counter has been initialized to \p x. */ template inline __host__ __device__ counting_iterator make_counting_iterator(Incrementable x) { return counting_iterator(x); } /*! \} // end fancyiterators */ /*! \} // end iterators */ } // end thrust