/* * Copyright 2008-2013 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 #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header #include #include #include // #include the details first #include THRUST_NAMESPACE_BEGIN /*! \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() * { * // 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 */ /*! Default constructor initializes this \p counting_iterator's counter to * `Incrementable{}`. */ _CCCL_HOST_DEVICE counting_iterator() : super_t(Incrementable{}) {} /*! Copy constructor copies the value of another counting_iterator * with related System type. * * \param rhs The \p counting_iterator to copy. */ template < class OtherSystem, detail::enable_if_convertible_t< typename thrust::iterator_system>::type, typename thrust::iterator_system::type, int> = 0> _CCCL_HOST_DEVICE counting_iterator(counting_iterator const& rhs) : 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. */ _CCCL_HOST_DEVICE explicit counting_iterator(Incrementable x) : super_t(x) {} /*! \cond */ private: _CCCL_HOST_DEVICE reference dereference() const { return this->base_reference(); } // note that we implement equal specially for floating point counting_iterator template _CCCL_HOST_DEVICE bool equal(counting_iterator const& y) const { typedef thrust::detail::counting_iterator_equal e; return e::equal(this->base(), y.base()); } template _CCCL_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_< thrust::detail::iterator_distance>>::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 _CCCL_HOST_DEVICE counting_iterator make_counting_iterator(Incrementable x) { return counting_iterator(x); } /*! \} // end fancyiterators */ /*! \} // end iterators */ THRUST_NAMESPACE_END