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

Last change on this file since 1110 was 1110, checked in by Peter, 15 years ago

changing name of Iterator and some left-over from prev commit

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
1#ifndef _theplu_yat_utility_container2d_iterator_
2#define _theplu_yat_utility_container2d_iterator_
3
4// $Id: Container2DIterator.h 1110 2008-02-19 22:03:34Z peter $
5
6/*
7  Copyright (C) 2007, 2008 Peter Johansson
8
9  This file is part of the yat library, http://trac.thep.lu.se/yat
10
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 2 of the
14  License, or (at your option) any later version.
15
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24  02111-1307, USA.
25*/
26
27#include "IteratorPolicy.h"
28#include "yat_assert.h"
29
30#include <iterator>
31#include <stddef.h>
32#include <stdexcept>
33#include <utility>
34
35namespace theplu {
36namespace yat {
37namespace utility {
38
39  /**
40     @brief Iterator
41  */
42  template<typename Container, typename value, 
43           typename pointer = value*, typename reference = value&,
44           class Policy = IteratorPolicy<Container, reference, value> > 
45  class Container2DIterator
46    : public std::iterator<std::random_access_iterator_tag, value, size_t, 
47                           pointer, reference>
48  {
49  public:
50    typedef typename Policy::weighted_iterator_type weighted_iterator_type;
51
52  private:
53    typedef Container2DIterator<Container, value, pointer,reference,Policy> self;
54
55  public:
56    /**
57       \brief Default Constructor
58    */
59    Container2DIterator(void) {};
60
61    /**
62       \brief Constructor
63
64       \param container iterator points to
65       \param row telling which row iterator points to
66       \param colun telling which column iterator points to
67    */
68    Container2DIterator(Container& container, size_t row, size_t column)
69      : container_(&container), index_(row*container.columns()+column) {}
70
71    /**
72       \return data
73    */
74    typename Policy::data_type data(void) const 
75    { yat_assert<std::out_of_range>(index_<this->size(), 
76                                    "Container2DIterator::data"); 
77      return ip_.data(*container_, row(index_), column(index_)); 
78    }
79
80    /**
81       \return weight
82    */
83    typename Policy::weight_type weight(void) const 
84    { yat_assert<std::out_of_range>(index_<this->size(), 
85                                    "Container2DIterator::weight"); 
86      return ip_.weight(*container_, row(index_), column(index_)); 
87    }
88
89    /**
90       \return element
91     */
92    reference operator*(void) const 
93    { 
94      yat_assert<std::out_of_range>(index_ < this->size(), 
95                                    "Container2DIterator::operator*");
96      return ip_.dereference(*container_, row(index_), column(index_));
97    }
98
99    /**
100       \return element \a n steps forward
101     */
102    reference operator[](size_t n) const 
103    { 
104      yat_assert<std::out_of_range>(index_+n < this->size(),
105                                    "Container2DIterator::operator[]");
106      return ip_.dereference(*container_, row(index_+n), column(index_+n));
107    }
108
109    /**
110       \brief pre-increment
111
112       \return reference to *this
113     */
114    Container2DIterator& operator++(void) { ++index_; return *this; }
115
116    /**
117       \brief post-increment
118
119       \return copy of iterator prior increment
120     */
121    Container2DIterator operator++(int) 
122    { self tmp(*this); ++index_; return tmp;}
123
124    /**
125       \brief iterate \f$ n \f$ steps forward
126
127       \return reference to resulting iterator
128     */
129    Container2DIterator& operator+=(int n) { index_+=n; return *this; }
130
131    /**
132       \brief post-decrement
133
134       \return copy of iterator prior decrement
135     */
136    Container2DIterator operator--(int) 
137    { self tmp(*this); --index_; return tmp;}
138
139    /**
140       \brief pre-decrement
141
142       \return reference to resulting iterator
143     */
144    Container2DIterator& operator--(void) { --index_; return *this; }
145
146    /**
147       \brief iterate \f$ n \f$ steps backwards
148
149       \return reference to resulting iterator
150     */
151    Container2DIterator& operator-=(int n) { index_-=n; return *this; }
152
153    /**
154       \brief addition operator
155
156       \return copy of resulting iterator
157     */
158    friend Container2DIterator operator+(const Container2DIterator& lhs, 
159                                         size_t n) 
160    { return self(*lhs.container_, lhs.index_+n); }
161
162    /**
163       \brief subtraction operator
164
165       \return copy of resulting iterator
166     */
167    friend Container2DIterator operator-(const Container2DIterator& lhs,
168                                         size_t n) 
169    { return self(*lhs.container_, lhs.index_-n); }
170
171    /**
172       \brief difference operator
173
174       \return distance between \a lhs and \a rhs
175     */
176    friend size_t operator-(const Container2DIterator& lhs, \
177                            const Container2DIterator& rhs) 
178    { 
179      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
180                                     "Container2DIterator::operator-");
181      return lhs.index_-rhs.index_; 
182    }
183
184   
185    /**
186       \brief Equality operator
187
188       \return True if \a lhs and \a rhs are pointing to same element
189     */
190    friend bool operator==(const self& lhs, const self& rhs)
191    { 
192      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
193                                     "Container2DIterator::operator==");
194      return lhs.index_==rhs.index_; 
195    }
196   
197    /**
198       \brief Non-equality operator
199
200       \return False if \a lhs and \a rhs are pointing to same element
201     */
202    friend bool operator!=(const Container2DIterator& lhs, 
203                           const Container2DIterator& rhs)
204    { 
205      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
206                                     "Container2DIterator::operator!=");
207      return !(lhs==rhs); 
208    }
209   
210    /**
211       \brief Less operator
212     */
213    friend bool operator<(const self& lhs, const self& rhs)
214    { 
215      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
216                                     "Container2DIterator::operator<");
217      return lhs.index_<rhs.index_; 
218    }
219   
220    /**
221       \brief Less equal operator
222     */
223    friend bool operator<=(const self& lhs, const self& rhs)
224    { 
225      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
226                                     "Container2DIterator::operator<=");
227      return lhs.index_<=rhs.index_; 
228    }
229   
230    /**
231       \brief Larger operator
232     */
233    friend bool operator>(const self& lhs, const self& rhs)
234    { 
235      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
236                                     "Container2DIterator::operator>");
237      return lhs.index_>rhs.index_; 
238    }
239   
240    /**
241       \brief Larger equal operator
242     */
243    friend bool operator>=(const self& lhs, const self& rhs)
244    { 
245      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
246                                     "Container2DIterator::operator>=");
247      return lhs.index_>=rhs.index_; 
248    }
249   
250  private:
251    Container* container_;
252    size_t index_;
253    Policy ip_;
254
255    size_t column(size_t i) const 
256    { return i % container_->columns(); }
257    size_t row(size_t i) const 
258    { return static_cast<size_t>(i/container_->columns()); }
259    size_t size() const 
260    { return container_->columns()*container_->rows(); }
261
262
263    // Using compiler generated copy
264    //Container2DIterator(const Container2DIterator&);
265    //Container2DIterator& operator=(const Container2DIterator&);
266  };
267
268  /**
269     Whether Container2DIterator is weighted is desiced by Policy.
270   */
271  template<typename A, typename B, typename C, typename D, typename Policy> 
272  struct weighted_iterator_traits<Container2DIterator<A, B, C, D, Policy> > {
273    typedef typename Policy::weighted_iterator_type type;
274  };
275
276  template<typename A, typename B, typename C, typename D, typename E> 
277  struct iterator_traits<Container2DIterator<A, B, C, D, E> > {
278    /**
279       \return data
280    */
281    double data(Container2DIterator<A, B, C, D, E> iter) const 
282    { return iter.data(); }
283
284    /**
285       \return weight
286    */
287    double weight(Container2DIterator<A, B, C, D, E> iter) const 
288    { return iter.weight(); }
289
290  };
291
292
293}}} // of namespace utility, yat, and theplu
294
295#endif
Note: See TracBrowser for help on using the repository browser.