yat/utility/Container2DIterator.h

Code
Comments
Other
Rev Date Author Line
1110 19 Feb 08 peter 1 #ifndef _theplu_yat_utility_container2d_iterator_
1110 19 Feb 08 peter 2 #define _theplu_yat_utility_container2d_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
4207 26 Aug 22 peter 9   Copyright (C) 2009, 2010, 2015, 2022 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
2373 12 Dec 10 peter 27 #include "concept_check.h"
1565 10 Oct 08 peter 28 #include "iterator_traits.h"
916 30 Sep 07 peter 29 #include "yat_assert.h"
916 30 Sep 07 peter 30
2373 12 Dec 10 peter 31 #include <boost/concept_check.hpp>
4135 21 Jan 22 peter 32 #include <boost/iterator/iterator_adaptor.hpp>
1539 30 Sep 08 peter 33 #include <boost/iterator/iterator_facade.hpp>
1539 30 Sep 08 peter 34
2094 26 Oct 09 peter 35 #include <cstddef>
880 21 Sep 07 peter 36 #include <iterator>
936 05 Oct 07 peter 37 #include <stdexcept>
1027 02 Feb 08 peter 38 #include <utility>
880 21 Sep 07 peter 39
880 21 Sep 07 peter 40 namespace theplu {
880 21 Sep 07 peter 41 namespace yat {
880 21 Sep 07 peter 42 namespace utility {
880 21 Sep 07 peter 43
880 21 Sep 07 peter 44   /**
1566 10 Oct 08 peter 45      @brief Iterator for a \ref concept_container_2d
1566 10 Oct 08 peter 46
1566 10 Oct 08 peter 47      The iterator can be used to traverse through a \ref
4200 19 Aug 22 peter 48      concept_container_2d row by row.
1566 10 Oct 08 peter 49
2373 12 Dec 10 peter 50      Type Requirements:
2373 12 Dec 10 peter 51      - \c Container must be a \ref concept_container_2d
2373 12 Dec 10 peter 52      - \c value is typically \c Container::value_type if
2373 12 Dec 10 peter 53        Container2DIterator is mutable or \c const \c
2373 12 Dec 10 peter 54        Container::value_type otherwise.
2373 12 Dec 10 peter 55      - \c reference, typically \c value&, must be convertible to \c
2373 12 Dec 10 peter 56        value
2373 12 Dec 10 peter 57      - \c Container must have an \c operator()(size_t, size_t) that
2373 12 Dec 10 peter 58        returns a type that is convertible to \c reference.
2373 12 Dec 10 peter 59
1566 10 Oct 08 peter 60      \see StrideIterator
880 21 Sep 07 peter 61   */
1565 10 Oct 08 peter 62   template<typename Container, typename value, typename reference = value&>
1110 19 Feb 08 peter 63   class Container2DIterator
1539 30 Sep 08 peter 64     : public boost::iterator_facade<
1565 10 Oct 08 peter 65     Container2DIterator<Container, value, reference>
1539 30 Sep 08 peter 66     , value
3393 17 Mar 15 peter 67     , boost::random_access_traversal_tag
1539 30 Sep 08 peter 68     , reference>
880 21 Sep 07 peter 69   {
1027 02 Feb 08 peter 70   private:
1565 10 Oct 08 peter 71     typedef Container2DIterator<Container, value, reference> self;
1027 02 Feb 08 peter 72
1027 02 Feb 08 peter 73   public:
880 21 Sep 07 peter 74     /**
884 22 Sep 07 peter 75        \brief Default Constructor
880 21 Sep 07 peter 76     */
4200 19 Aug 22 peter 77     Container2DIterator(void)
2373 12 Dec 10 peter 78     {
2373 12 Dec 10 peter 79       BOOST_CONCEPT_ASSERT((Container2D<Container>));
2373 12 Dec 10 peter 80     };
884 22 Sep 07 peter 81
884 22 Sep 07 peter 82     /**
884 22 Sep 07 peter 83        \brief Constructor
884 22 Sep 07 peter 84
884 22 Sep 07 peter 85        \param container iterator points to
1062 10 Feb 08 peter 86        \param row telling which row iterator points to
1125 22 Feb 08 peter 87        \param column telling which column iterator points to
884 22 Sep 07 peter 88     */
1110 19 Feb 08 peter 89     Container2DIterator(Container& container, size_t row, size_t column)
4200 19 Aug 22 peter 90       : container_(&container), index_(row*container.columns()+column)
2373 12 Dec 10 peter 91     {
2373 12 Dec 10 peter 92       BOOST_CONCEPT_ASSERT((Container2D<Container>));
2373 12 Dec 10 peter 93     }
880 21 Sep 07 peter 94
4135 21 Jan 22 peter 95
4135 21 Jan 22 peter 96     /**
4135 21 Jan 22 peter 97        Conversion constructor allowing conversion between different
4135 21 Jan 22 peter 98        Container2DIterators. Requires that C2 is convertible to
4135 21 Jan 22 peter 99        Container.
4135 21 Jan 22 peter 100
4135 21 Jan 22 peter 101        \since New in yat 0.20
4135 21 Jan 22 peter 102      */
4135 21 Jan 22 peter 103     template<typename C2, typename V2, typename R2>
4135 21 Jan 22 peter 104     Container2DIterator(Container2DIterator<C2,V2,R2> other,
4135 21 Jan 22 peter 105           typename boost::enable_if_convertible<C2*, Container*>::type* = 0,
4135 21 Jan 22 peter 106           typename boost::enable_if_convertible<R2, reference>::type* = 0)
4135 21 Jan 22 peter 107       : container_(&other.container()),
4135 21 Jan 22 peter 108         index_(other.row() * other.container().columns()+other.column())
4135 21 Jan 22 peter 109     {}
4135 21 Jan 22 peter 110
4135 21 Jan 22 peter 111
4135 21 Jan 22 peter 112     /**
4135 21 Jan 22 peter 113        \return reference to underlying Container
4135 21 Jan 22 peter 114
4135 21 Jan 22 peter 115        \since New in yat 0.20
4135 21 Jan 22 peter 116      */
4135 21 Jan 22 peter 117     Container& container(void) const { return *container_; }
4135 21 Jan 22 peter 118
4135 21 Jan 22 peter 119     /**
4135 21 Jan 22 peter 120        \return the row of the element the iterator points to
4135 21 Jan 22 peter 121
4135 21 Jan 22 peter 122        \since New in yat 0.20
4135 21 Jan 22 peter 123      */
4135 21 Jan 22 peter 124     size_t row(void) const { return row(index_); }
4135 21 Jan 22 peter 125
4135 21 Jan 22 peter 126     /**
4135 21 Jan 22 peter 127        \return the column of the element the iterator points to
4135 21 Jan 22 peter 128
4135 21 Jan 22 peter 129        \since New in yat 0.20
4135 21 Jan 22 peter 130      */
4135 21 Jan 22 peter 131     size_t column(void) const { return column(index_); }
4135 21 Jan 22 peter 132
1539 30 Sep 08 peter 133   private:
1539 30 Sep 08 peter 134     friend class boost::iterator_core_access;
884 22 Sep 07 peter 135
1539 30 Sep 08 peter 136     Container* container_;
1539 30 Sep 08 peter 137     size_t index_;
932 05 Oct 07 peter 138
1539 30 Sep 08 peter 139     void advance(int n) { index_+=n; }
884 22 Sep 07 peter 140
1539 30 Sep 08 peter 141     void decrement(void) { --index_; }
884 22 Sep 07 peter 142
1539 30 Sep 08 peter 143     int distance_to(const Container2DIterator& other) const
1539 30 Sep 08 peter 144     { return other.index_ - index_; }
884 22 Sep 07 peter 145
4135 21 Jan 22 peter 146     reference dereference(void) const
4135 21 Jan 22 peter 147     {
4135 21 Jan 22 peter 148       yat_assert<std::out_of_range>(index_ < this->size(),
1539 30 Sep 08 peter 149                                     "Container2DIterator::dereference");
4135 21 Jan 22 peter 150       return container_->operator()(row(), column());
1062 10 Feb 08 peter 151     }
884 22 Sep 07 peter 152
1539 30 Sep 08 peter 153     bool equal(const Container2DIterator& other) const
1539 30 Sep 08 peter 154     { return index_ == other.index_; }
883 22 Sep 07 peter 155
1539 30 Sep 08 peter 156     void increment(void) { ++index_; }
884 22 Sep 07 peter 157
4200 19 Aug 22 peter 158     size_t column(size_t i) const
1062 10 Feb 08 peter 159     { return i % container_->columns(); }
4200 19 Aug 22 peter 160     size_t row(size_t i) const
1067 10 Feb 08 peter 161     { return static_cast<size_t>(i/container_->columns()); }
4200 19 Aug 22 peter 162     size_t size() const
1062 10 Feb 08 peter 163     { return container_->columns()*container_->rows(); }
1062 10 Feb 08 peter 164
1080 13 Feb 08 peter 165
884 22 Sep 07 peter 166     // Using compiler generated copy
1110 19 Feb 08 peter 167     //Container2DIterator(const Container2DIterator&);
1110 19 Feb 08 peter 168     //Container2DIterator& operator=(const Container2DIterator&);
880 21 Sep 07 peter 169   };
1088 14 Feb 08 peter 170
880 21 Sep 07 peter 171 }}} // of namespace utility, yat, and theplu
880 21 Sep 07 peter 172
880 21 Sep 07 peter 173 #endif