source: trunk/yat/utility/StrideIterator.h @ 3417

Last change on this file since 3417 was 3417, checked in by Peter, 4 years ago

updating copyright statements

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svndigest:ignore set to 1037
File size: 4.3 KB
Line 
1#ifndef _theplu_yat_utility_stride_iterator_
2#define _theplu_yat_utility_stride_iterator_
3
4// $Id: StrideIterator.h 3417 2015-05-25 01:35:59Z peter $
5
6/*
7  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2010, 2015 Peter Johansson
9
10  This file is part of the yat library, http://dev.thep.lu.se/yat
11
12  The yat library is free software; you can redistribute it and/or
13  modify it under the terms of the GNU General Public License as
14  published by the Free Software Foundation; either version 3 of the
15  License, or (at your option) any later version.
16
17  The yat library is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  General Public License for more details.
21
22  You should have received a copy of the GNU General Public License
23  along with yat. If not, see <http://www.gnu.org/licenses/>.
24*/
25
26#include <boost/concept_check.hpp>
27#include <boost/iterator/iterator_adaptor.hpp>
28#include <boost/iterator/iterator_concepts.hpp>
29
30namespace theplu {
31namespace yat {
32namespace utility {
33
34  /**
35     @brief Adaptor using a stride on underlying iterator
36
37     Works as underlying iterator except that all arithmetic uses the
38     stride, so e.g., ++StrideIterator returns underlying
39     _iterator+stride
40
41     The stride must be positive. Negative stride can be accomplished
42     by combining StrideIterator with a reverse_iterator (from
43     e.g. std or boost).
44
45     Type Requirements:
46     - \c RandomAccessIterator must be a \readable_iterator
47     - \c RandomAccessIterator must be a \random_access_traversal_iterator
48  */
49  template<typename RandomAccessIterator>
50  class StrideIterator 
51    : public boost::iterator_adaptor<StrideIterator<RandomAccessIterator>
52                                     , RandomAccessIterator>
53  {
54    typedef boost::iterator_adaptor<StrideIterator<RandomAccessIterator>,
55                                    RandomAccessIterator>
56    super_t;
57
58  public:
59    /// type of underlying iterator
60    typedef RandomAccessIterator iterator_type;
61
62    /**
63       \brief default constructor
64
65       Using default constructor of BASE iterator.
66     */
67    explicit StrideIterator(size_t stride=1)
68      : StrideIterator::iterator_adaptor_(), stride_(stride) 
69    {
70      using boost_concepts::RandomAccessTraversal;
71      using boost_concepts::ReadableIterator;
72      BOOST_CONCEPT_ASSERT((ReadableIterator<RandomAccessIterator>));
73      BOOST_CONCEPT_ASSERT((RandomAccessTraversal<RandomAccessIterator>));
74    }
75
76    /**
77       \brief Constructor
78    */
79    explicit StrideIterator(RandomAccessIterator p, size_t stride=1)
80      : StrideIterator::iterator_adaptor_(p), stride_(stride) {}
81
82   
83    /**
84       \brief Copy constructor
85     */
86    StrideIterator(const StrideIterator& other)
87      : StrideIterator::iterator_adaptor_(other.base()), stride_(other.stride()) 
88    {}
89
90    /**
91       \brief Conversion constructor.
92
93       Create a StrideIterator<RandomAccessIterator> from a
94       StrideIterator<I2>. Possible if I2 is convertible to a
95       RandomAccessIterator. Constructor allows implicit conversions
96       such as iterator to const_iterator.
97     */
98    template<typename I2>
99    StrideIterator(StrideIterator<I2> other,
100                   typename boost::enable_if_convertible<I2
101                   , RandomAccessIterator>::type* = 0 )
102      : StrideIterator::iterator_adaptor_(other.base()), 
103        stride_(other.stride()) {}
104
105    /**
106        \brief Assignment operator
107     */
108    StrideIterator& operator=(const StrideIterator& rhs)
109    {
110      stride_ = rhs.stride();
111      this->base_reference() = rhs.base();
112      return *this;
113    }
114
115    /**
116       \return stride
117     */
118    inline size_t stride(void) const { return stride_; }
119
120  private:
121    // to give base class access to private parts
122    friend class boost::iterator_core_access;
123   
124    size_t stride_;
125
126    //typedef typename StrideIterator::iterator_adaptor_::difference_type
127    typedef typename StrideIterator::iterator_adaptor_::difference_type
128    difference_t;
129
130    void advance(typename super_t::difference_type n)
131    { this->base_reference() += stride_*n; }
132
133    void decrement(void) { this->base_reference()-=stride_; }
134
135    template <class OtherIterator>
136    typename super_t::difference_type
137    distance_to(const StrideIterator<OtherIterator>& other) const
138    { 
139      // casting to int to avoid loss of sign in numerator
140      return (other.base() - this->base() )/static_cast<int>(stride_); 
141    }
142
143    void increment(void) { this->base_reference()+=stride_; }
144  };
145
146}}} // of namespace utility, yat, and theplu
147
148#endif
Note: See TracBrowser for help on using the repository browser.