source: trunk/yat/utility/Container2DIterator.h @ 3393

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

refs #803

The std::random_access_iterator promises that iterator provides random
traversal and that reference_type is an lvalue (i.e. not proxy). If
reference_type is a proxy, it is therefore incorrect to tag the
iterator with std::random_access_iterator. To reflect that we do the
following two changes:

1) Container2DIterator now carries tag
boost::random_access_traversal_tag rather than
std::random_access_iterator. This means that in std:: speak a
Container2DIterator is a random access iterator, if reference is an
lvalue and an input iterator otherwise.

2) The BASE of StrideIterator? is no longer required to be a random
access iterator, instead we require random access traversal.
Therefore, StrideIterator? now uses the default tag rather than
std::iterator_traits<BASE>::iterator_category. This means that the
traversal tag is boost::random_access_traversal_tag (as BASE is
required to provide random access traversal), and in std:: speak the
same rule applies as for Container2DIterator.

3) The concept check for Container2D now requires that iterators
::const_iterator, ::const_row_iterator, ::const_column_iterator are
readable iterator (the random access requirement is removed).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.6 KB
Line 
1#ifndef _theplu_yat_utility_container2d_iterator_
2#define _theplu_yat_utility_container2d_iterator_
3
4// $Id: Container2DIterator.h 3393 2015-03-17 03:38:36Z peter $
5
6/*
7  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2009, 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 "concept_check.h"
27#include "iterator_traits.h"
28#include "yat_assert.h"
29
30#include <boost/concept_check.hpp>
31#include <boost/iterator/iterator_facade.hpp>
32
33#include <cstddef>
34#include <iterator>
35#include <stdexcept>
36#include <utility>
37
38namespace theplu {
39namespace yat {
40namespace utility {
41
42  /**
43     @brief Iterator for a \ref concept_container_2d
44
45     The iterator can be used to traverse through a \ref
46     concept_container_2d row by row.
47
48     Type Requirements:
49     - \c Container must be a \ref concept_container_2d
50     - \c value is typically \c Container::value_type if
51       Container2DIterator is mutable or \c const \c
52       Container::value_type otherwise.
53     - \c reference, typically \c value&, must be convertible to \c
54       value
55     - \c Container must have an \c operator()(size_t, size_t) that
56       returns a type that is convertible to \c reference.
57
58     \see StrideIterator
59  */
60  template<typename Container, typename value, typename reference = value&>
61  class Container2DIterator
62    : public boost::iterator_facade<
63    Container2DIterator<Container, value, reference>
64    , value
65    , boost::random_access_traversal_tag
66    , reference>
67  {
68  private:
69    typedef Container2DIterator<Container, value, reference> self;
70
71  public:
72    /**
73       \brief Default Constructor
74    */
75    Container2DIterator(void) 
76    {
77      BOOST_CONCEPT_ASSERT((Container2D<Container>));
78    };
79
80    /**
81       \brief Constructor
82
83       \param container iterator points to
84       \param row telling which row iterator points to
85       \param column telling which column iterator points to
86    */
87    Container2DIterator(Container& container, size_t row, size_t column)
88      : container_(&container), index_(row*container.columns()+column) 
89    {
90      BOOST_CONCEPT_ASSERT((Container2D<Container>));
91    }
92
93  private:
94    friend class boost::iterator_core_access;
95
96    Container* container_;
97    size_t index_;
98
99    void advance(int n) { index_+=n; }
100
101    void decrement(void) { --index_; }
102
103    int distance_to(const Container2DIterator& other) const
104    { return other.index_ - index_; }
105
106    reference dereference(void) const 
107    { 
108      yat_assert<std::out_of_range>(index_ < this->size(), 
109                                    "Container2DIterator::dereference");
110      return container_->operator()(row(index_), column(index_));
111    }
112
113    bool equal(const Container2DIterator& other) const
114    { return index_ == other.index_; }
115
116    void increment(void) { ++index_; }
117
118    size_t column(size_t i) const 
119    { return i % container_->columns(); }
120    size_t row(size_t i) const 
121    { return static_cast<size_t>(i/container_->columns()); }
122    size_t size() const 
123    { return container_->columns()*container_->rows(); }
124
125
126    // Using compiler generated copy
127    //Container2DIterator(const Container2DIterator&);
128    //Container2DIterator& operator=(const Container2DIterator&);
129  };
130
131}}} // of namespace utility, yat, and theplu
132
133#endif
Note: See TracBrowser for help on using the repository browser.