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

Last change on this file since 1437 was 1437, checked in by Peter, 13 years ago

merge patch release 0.4.2 to trunk. Delta 0.4.2-0.4.1

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.2 KB
Line 
1#ifndef _theplu_yat_utility_container2d_iterator_
2#define _theplu_yat_utility_container2d_iterator_
3
4// $Id: Container2DIterator.h 1437 2008-08-25 17:55:00Z peter $
5
6/*
7  Copyright (C) 2007 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2008 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 2 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 this program; if not, write to the Free Software
24  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25  02111-1307, USA.
26*/
27
28#include "IteratorPolicy.h"
29#include "yat_assert.h"
30
31#include <iterator>
32#include <stddef.h>
33#include <stdexcept>
34#include <utility>
35
36namespace theplu {
37namespace yat {
38namespace utility {
39
40  /**
41     @brief Iterator
42  */
43  template<typename Container, typename value, 
44           typename pointer = value*, typename reference = value&,
45           class Policy = IteratorPolicy<Container, reference, value> > 
46  class Container2DIterator
47    : public std::iterator<std::random_access_iterator_tag, value, size_t, 
48                           pointer, reference>
49  {
50  public:
51    /**
52       Tells whether iterator is weighted or not.
53
54       \see weighted_iterator_tag and unweighted_iterator_tag
55     */
56    typedef typename Policy::weighted_iterator_type weighted_iterator_type;
57
58  private:
59    typedef Container2DIterator<Container, value, pointer,reference,Policy> self;
60
61  public:
62    /**
63       \brief Default Constructor
64    */
65    Container2DIterator(void) {};
66
67    /**
68       \brief Constructor
69
70       \param container iterator points to
71       \param row telling which row iterator points to
72       \param column telling which column iterator points to
73    */
74    Container2DIterator(Container& container, size_t row, size_t column)
75      : container_(&container), index_(row*container.columns()+column) {}
76
77    /**
78       \return data
79    */
80    typename Policy::data_type data(void) const 
81    { yat_assert<std::out_of_range>(index_<this->size(), 
82                                    "Container2DIterator::data"); 
83      return ip_.data(*container_, row(index_), column(index_)); 
84    }
85
86    /**
87       \return weight
88    */
89    typename Policy::weight_type weight(void) const 
90    { yat_assert<std::out_of_range>(index_<this->size(), 
91                                    "Container2DIterator::weight"); 
92      return ip_.weight(*container_, row(index_), column(index_)); 
93    }
94
95    /**
96       \return element
97     */
98    reference operator*(void) const 
99    { 
100      yat_assert<std::out_of_range>(index_ < this->size(), 
101                                    "Container2DIterator::operator*");
102      return ip_.dereference(*container_, row(index_), column(index_));
103    }
104
105    /**
106       \return element \a n steps forward
107     */
108    reference operator[](size_t n) const 
109    { 
110      yat_assert<std::out_of_range>(index_+n < this->size(),
111                                    "Container2DIterator::operator[]");
112      return ip_.dereference(*container_, row(index_+n), column(index_+n));
113    }
114
115    /**
116       \brief pre-increment
117
118       \return reference to *this
119     */
120    Container2DIterator& operator++(void) { ++index_; return *this; }
121
122    /**
123       \brief post-increment
124
125       \return copy of iterator prior increment
126     */
127    Container2DIterator operator++(int) 
128    { self tmp(*this); ++index_; return tmp;}
129
130    /**
131       \brief iterate \f$ n \f$ steps forward
132
133       \return reference to resulting iterator
134     */
135    Container2DIterator& operator+=(int n) { index_+=n; return *this; }
136
137    /**
138       \brief post-decrement
139
140       \return copy of iterator prior decrement
141     */
142    Container2DIterator operator--(int) 
143    { self tmp(*this); --index_; return tmp;}
144
145    /**
146       \brief pre-decrement
147
148       \return reference to resulting iterator
149     */
150    Container2DIterator& operator--(void) { --index_; return *this; }
151
152    /**
153       \brief iterate \f$ n \f$ steps backwards
154
155       \return reference to resulting iterator
156     */
157    Container2DIterator& operator-=(int n) { index_-=n; return *this; }
158
159    /**
160       \brief addition operator
161
162       \return copy of resulting iterator
163     */
164    friend Container2DIterator operator+(const Container2DIterator& lhs, 
165                                         size_t n) 
166    { return self(*lhs.container_, lhs.index_+n); }
167
168    /**
169       \brief subtraction operator
170
171       \return copy of resulting iterator
172     */
173    friend Container2DIterator operator-(const Container2DIterator& lhs,
174                                         size_t n) 
175    { return self(*lhs.container_, lhs.index_-n); }
176
177    /**
178       \brief difference operator
179
180       \return distance between \a lhs and \a rhs
181     */
182    friend size_t operator-(const Container2DIterator& lhs, \
183                            const Container2DIterator& rhs) 
184    { 
185      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
186                                     "Container2DIterator::operator-");
187      return lhs.index_-rhs.index_; 
188    }
189
190   
191    /**
192       \brief Equality operator
193
194       \return True if \a lhs and \a rhs are pointing to same element
195     */
196    friend bool operator==(const self& lhs, const self& rhs)
197    { 
198      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
199                                     "Container2DIterator::operator==");
200      return lhs.index_==rhs.index_; 
201    }
202   
203    /**
204       \brief Non-equality operator
205
206       \return False if \a lhs and \a rhs are pointing to same element
207     */
208    friend bool operator!=(const Container2DIterator& lhs, 
209                           const Container2DIterator& rhs)
210    { 
211      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
212                                     "Container2DIterator::operator!=");
213      return !(lhs==rhs); 
214    }
215   
216    /**
217       \brief Less operator
218     */
219    friend bool operator<(const self& lhs, const self& rhs)
220    { 
221      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
222                                     "Container2DIterator::operator<");
223      return lhs.index_<rhs.index_; 
224    }
225   
226    /**
227       \brief Less equal operator
228     */
229    friend bool operator<=(const self& lhs, const self& rhs)
230    { 
231      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
232                                     "Container2DIterator::operator<=");
233      return lhs.index_<=rhs.index_; 
234    }
235   
236    /**
237       \brief Larger operator
238     */
239    friend bool operator>(const self& lhs, const self& rhs)
240    { 
241      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
242                                     "Container2DIterator::operator>");
243      return lhs.index_>rhs.index_; 
244    }
245   
246    /**
247       \brief Larger equal operator
248     */
249    friend bool operator>=(const self& lhs, const self& rhs)
250    { 
251      yat_assert<std::runtime_error>(lhs.container_==rhs.container_, 
252                                     "Container2DIterator::operator>=");
253      return lhs.index_>=rhs.index_; 
254    }
255   
256  private:
257    Container* container_;
258    size_t index_;
259    Policy ip_;
260
261    size_t column(size_t i) const 
262    { return i % container_->columns(); }
263    size_t row(size_t i) const 
264    { return static_cast<size_t>(i/container_->columns()); }
265    size_t size() const 
266    { return container_->columns()*container_->rows(); }
267
268
269    // Using compiler generated copy
270    //Container2DIterator(const Container2DIterator&);
271    //Container2DIterator& operator=(const Container2DIterator&);
272  };
273
274  /**
275     Specialization for Container2DIterator
276   */
277  template<typename A, typename B, typename C, typename D, typename Policy> 
278  struct weighted_iterator_traits<Container2DIterator<A, B, C, D, Policy> > {
279    /**
280       Whether Container2DIterator is weighted is desiced by Policy.
281    */
282    typedef typename Policy::weighted_iterator_type type;
283  };
284
285  /**
286     Specialization for Container2DIterator
287   */
288  template<typename A, typename B, typename C, typename D, typename E> 
289  struct iterator_traits<Container2DIterator<A, B, C, D, E> > {
290    /**
291       data_reference is defined by Policy class E::data_type
292     */
293    typedef typename E::data_type data_reference;
294
295    /**
296       data_reference is defined by Policy class E::weight_type
297     */
298    typedef typename E::weight_type weight_reference;
299
300    /**
301       \return data
302    */
303    data_reference data(Container2DIterator<A, B, C, D, E> iter) const 
304    { return iter.data(); }
305
306    /**
307       \return weight
308    */
309    weight_reference weight(Container2DIterator<A, B, C, D, E> iter) const 
310    { return iter.weight(); }
311
312  };
313
314
315}}} // of namespace utility, yat, and theplu
316
317#endif
Note: See TracBrowser for help on using the repository browser.