You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
7.9 KiB
240 lines
7.9 KiB
11 years ago
|
/*
|
||
|
* 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/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>
|
||
|
|
||
|
namespace thrust
|
||
|
{
|
||
|
|
||
|
/*! \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.
|
||
|
*/
|
||
|
__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_hd_warning_disable__
|
||
|
__host__ __device__
|
||
|
typename iterator_adaptor::reference dereference() const
|
||
|
{ return *m_iterator; }
|
||
|
|
||
|
__thrust_hd_warning_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_hd_warning_disable__
|
||
|
__host__ __device__
|
||
|
void advance(typename iterator_adaptor::difference_type n)
|
||
|
{
|
||
|
// XXX statically assert on random_access_traversal_tag
|
||
|
m_iterator += n;
|
||
|
}
|
||
|
|
||
|
__thrust_hd_warning_disable__
|
||
|
__host__ __device__
|
||
|
void increment()
|
||
|
{ ++m_iterator; }
|
||
|
|
||
|
__thrust_hd_warning_disable__
|
||
|
__host__ __device__
|
||
|
void decrement()
|
||
|
{
|
||
|
// XXX statically assert on bidirectional_traversal_tag
|
||
|
--m_iterator;
|
||
|
}
|
||
|
|
||
|
__thrust_hd_warning_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
|
||
|
*/
|
||
|
|
||
|
} // end thrust
|
||
|
|