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

Last change on this file since 2992 was 2992, checked in by Peter, 6 years ago

set svndigest:ignore proprty to reflect when files were initially copied from other file (and early history should be ignored). closes #750

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svndigest:ignore set to 1037
File size: 4.2 KB
Line 
1#ifndef _theplu_yat_utility_stride_iterator_
2#define _theplu_yat_utility_stride_iterator_
3
4// $Id: StrideIterator.h 2992 2013-03-03 05:03:44Z peter $
5
6/*
7  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2010 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
29namespace theplu {
30namespace yat {
31namespace utility {
32
33  /**
34     @brief Adaptor using a stride on underlying iterator
35
36     Works as underlying iterator except that all arithmetic uses the
37     stride, so e.g., ++StrideIterator returns underlying
38     _iterator+stride
39
40     The stride must be positive. Negative stride can be accomplished
41     by combining StrideIterator with a reverse_iterator (from
42     e.g. std or boost).
43  */
44  template<typename RandomAccessIterator>
45  class StrideIterator 
46    : public boost::iterator_adaptor<StrideIterator<RandomAccessIterator>
47                                     , RandomAccessIterator
48                                     , boost::use_default
49      , typename std::iterator_traits<RandomAccessIterator>::iterator_category>
50  {
51    typedef boost::iterator_adaptor<StrideIterator<RandomAccessIterator>,
52                                    RandomAccessIterator,
53                                    boost::use_default,
54      typename std::iterator_traits<RandomAccessIterator>::iterator_category>
55    super_t;
56
57  public:
58    /// type of underlying iterator
59    typedef RandomAccessIterator iterator_type;
60
61    /**
62       \brief default constructor
63
64       Using default constructor of BASE iterator.
65     */
66    explicit StrideIterator(size_t stride=1)
67      : StrideIterator::iterator_adaptor_(), stride_(stride) 
68    {
69      BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<RandomAccessIterator>));
70    }
71
72    /**
73       \brief Constructor
74    */
75    explicit StrideIterator(RandomAccessIterator p, size_t stride=1)
76      : StrideIterator::iterator_adaptor_(p), stride_(stride) {}
77
78   
79    /**
80       \brief Copy constructor
81     */
82    StrideIterator(const StrideIterator& other)
83      : StrideIterator::iterator_adaptor_(other.base()), stride_(other.stride()) 
84    {}
85
86    /**
87       \brief Conversion constructor.
88
89       Create a StrideIterator<RandomAccessIterator> from a
90       StrideIterator<I2>. Possible if I2 is convertible to a
91       RandomAccessIterator. Constructor allows implicit conversions
92       such as iterator to const_iterator.
93     */
94    template<typename I2>
95    StrideIterator(StrideIterator<I2> other,
96                   typename boost::enable_if_convertible<I2
97                   , RandomAccessIterator>::type* = 0 )
98      : StrideIterator::iterator_adaptor_(other.base()), 
99        stride_(other.stride()) {}
100
101    /**
102        \brief Assignment operator
103     */
104    StrideIterator& operator=(const StrideIterator& rhs)
105    {
106      stride_ = rhs.stride();
107      this->base_reference() = rhs.base();
108      return *this;
109    }
110
111    /**
112       \return stride
113     */
114    inline size_t stride(void) const { return stride_; }
115
116  private:
117    // to give base class access to private parts
118    friend class boost::iterator_core_access;
119   
120    size_t stride_;
121
122    //typedef typename StrideIterator::iterator_adaptor_::difference_type
123    typedef typename StrideIterator::iterator_adaptor_::difference_type
124    difference_t;
125
126    void advance(typename super_t::difference_type n)
127    { this->base_reference() += stride_*n; }
128
129    void decrement(void) { this->base_reference()-=stride_; }
130
131    template <class OtherIterator>
132    typename super_t::difference_type
133    distance_to(const StrideIterator<OtherIterator>& other) const
134    { 
135      // casting to int to avoid loss of sign in numerator
136      return (other.base() - this->base() )/static_cast<int>(stride_); 
137    }
138
139    void increment(void) { this->base_reference()+=stride_; }
140  };
141
142}}} // of namespace utility, yat, and theplu
143
144#endif
Note: See TracBrowser for help on using the repository browser.