1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
|
/*
* 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/iterator_adaptor.h
* \brief An iterator which adapts a base iterator
*/
/*
* (C) Copyright David Abrahams 2002.
* (C) Copyright Jeremy Siek 2002.
* (C) Copyright Thomas Witt 2002.
*
* 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 <thrust/detail/config.h>
#include <thrust/iterator/iterator_facade.h>
#include <thrust/detail/use_default.h>
#include <thrust/iterator/detail/iterator_adaptor_base.h>
THRUST_NAMESPACE_BEGIN
/*! \addtogroup iterators
* \{
*/
/*! \addtogroup fancyiterator Fancy Iterators
* \ingroup iterators
* \{
*/
/*! \p iterator_adaptor is an iterator which adapts an existing type of iterator to create a new type of
* iterator. Most of Thrust's fancy iterators are defined via inheritance from \p iterator_adaptor.
* While composition of these existing Thrust iterators is often sufficient for expressing the desired
* functionality, it is occasionally more straightforward to derive from \p iterator_adaptor directly.
*
* To see how to use \p iterator_adaptor to create a novel iterator type, let's examine how to use it to
* define \p repeat_iterator, a fancy iterator which repeats elements from another range a given number of time:
*
* \code
* #include <thrust/iterator/iterator_adaptor.h>
*
* // derive repeat_iterator from iterator_adaptor
* template<typename Iterator>
* class repeat_iterator
* : public thrust::iterator_adaptor<
* repeat_iterator<Iterator>, // the first template parameter is the name of the iterator we're creating
* Iterator // the second template parameter is the name of the iterator we're adapting
* // we can use the default for the additional template parameters
* >
* {
* public:
* // shorthand for the name of the iterator_adaptor we're deriving from
* typedef thrust::iterator_adaptor<
* repeat_iterator<Iterator>,
* Iterator
* > super_t;
*
* __host__ __device__
* repeat_iterator(const Iterator &x, int n) : super_t(x), begin(x), n(n) {}
*
* // befriend thrust::iterator_core_access to allow it access to the private interface below
* friend class thrust::iterator_core_access;
*
* private:
* // repeat each element of the adapted range n times
* unsigned int n;
*
* // used to keep track of where we began
* const Iterator begin;
*
* // it is private because only thrust::iterator_core_access needs access to it
* __host__ __device__
* typename super_t::reference dereference() const
* {
* return *(begin + (this->base() - begin) / n);
* }
* };
* \endcode
*
* Except for the first two, \p iterator_adaptor's template parameters are optional. When omitted, or when the
* user specifies \p thrust::use_default in its place, \p iterator_adaptor will use a default type inferred from \p Base.
*
* \p iterator_adaptor's functionality is derived from and generally equivalent to \p boost::iterator_adaptor.
* The exception is Thrust's addition of the template parameter \p System, which is necessary to allow Thrust
* to dispatch an algorithm to one of several parallel backend systems.
*
* \p iterator_adaptor is a powerful tool for creating custom iterators directly. However, the large set of iterator semantics which must be satisfied
* for algorithm compatibility can make \p iterator_adaptor difficult to use correctly. Unless you require the full expressivity of \p iterator_adaptor,
* consider building a custom iterator through composition of existing higher-level fancy iterators instead.
*
* Interested users may refer to <tt>boost::iterator_adaptor</tt>'s documentation for further usage examples.
*/
template<typename Derived,
typename Base,
typename Value = use_default,
typename System = use_default,
typename Traversal = use_default,
typename Reference = use_default,
typename Difference = use_default>
class iterator_adaptor:
public detail::iterator_adaptor_base<
Derived, Base, Value, System, Traversal, Reference, Difference
>::type
{
/*! \cond
*/
friend class thrust::iterator_core_access;
protected:
typedef typename detail::iterator_adaptor_base<
Derived, Base, Value, System, Traversal, Reference, Difference
>::type super_t;
/*! \endcond
*/
public:
/*! \p iterator_adaptor's default constructor does nothing.
*/
__host__ __device__
iterator_adaptor(){}
/*! This constructor copies from a given instance of the \p Base iterator.
*/
__thrust_exec_check_disable__
__host__ __device__
explicit iterator_adaptor(Base const& iter)
: m_iterator(iter)
{}
/*! The type of iterator this \p iterator_adaptor's \p adapts.
*/
typedef Base base_type;
/*! \cond
*/
typedef typename super_t::reference reference;
typedef typename super_t::difference_type difference_type;
/*! \endcond
*/
/*! \return A \p const reference to the \p Base iterator this \p iterator_adaptor adapts.
*/
__host__ __device__
Base const& base() const
{ return m_iterator; }
protected:
/*! \return A \p const reference to the \p Base iterator this \p iterator_adaptor adapts.
*/
__host__ __device__
Base const& base_reference() const
{ return m_iterator; }
/*! \return A mutable reference to the \p Base iterator this \p iterator_adaptor adapts.
*/
__host__ __device__
Base& base_reference()
{ return m_iterator; }
/*! \cond
*/
private: // Core iterator interface for iterator_facade
__thrust_exec_check_disable__
__host__ __device__
typename iterator_adaptor::reference dereference() const
{ return *m_iterator; }
__thrust_exec_check_disable__
template<typename OtherDerived, typename OtherIterator, typename V, typename S, typename T, typename R, typename D>
__host__ __device__
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, S, T, R, D> const& x) const
{ return m_iterator == x.base(); }
__thrust_exec_check_disable__
__host__ __device__
void advance(typename iterator_adaptor::difference_type n)
{
// XXX statically assert on random_access_traversal_tag
// counting_iterator will pick eg. diff_t=int64 when base=int32.
// Explicitly cast to avoid static conversion warnings.
m_iterator = static_cast<base_type>(m_iterator + n);
}
__thrust_exec_check_disable__
__host__ __device__
void increment()
{ ++m_iterator; }
__thrust_exec_check_disable__
__host__ __device__
void decrement()
{
// XXX statically assert on bidirectional_traversal_tag
--m_iterator;
}
__thrust_exec_check_disable__
template<typename OtherDerived, typename OtherIterator, typename V, typename S, typename T, typename R, typename D>
__host__ __device__
typename iterator_adaptor::difference_type distance_to(iterator_adaptor<OtherDerived, OtherIterator, V, S, T, R, D> const& y) const
{ return y.base() - m_iterator; }
private:
Base m_iterator;
/*! \endcond
*/
}; // end iterator_adaptor
/*! \} // end fancyiterators
*/
/*! \} // end iterators
*/
THRUST_NAMESPACE_END
|