yat/utility/StrideIterator.h

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