C++-Programmierung/ Eine Matrix-Bibliothek – mitrax/ proxy iterator.hpp

Aus Wikibooks
Zur Navigation springen Zur Suche springen
Nuvola-inspired-terminal.svg
  1 #ifndef _mitrax_mitrax_detail_proxy_iterator_hpp_INCLUDED_
  2 #define _mitrax_mitrax_detail_proxy_iterator_hpp_INCLUDED_
  3 /// \file proxy_iterator.hpp
  4 ///
  5 /// \brief Proxyiteratorklassen
  6 ///
  7 /// Diese Datei stellt allgemeine Basisklassen für Forward-, Bidirectional- und
  8 /// Random-Access-Iteratoren bereit. Von dieses sind die vier Proxyiteratorklassen abgleitet.
  9 /// Ein Nutzer von mitrax sollte keinen direkten Kontakt mit diesen Klassen haben, daher stehen
 10 /// alle im Namensraum <code>detail</code>.
 11 
 12 #include <iterator>
 13 #include <memory>
 14 
 15 namespace mitrax { namespace detail {
 16 
 17 /// \brief Basisklasse für alle Forward-Iteratoren
 18 template < typename Derived >
 19 class forward_iterator_base{
 20 protected:
 21     /// \brief Standardkonstruktor nur für abgeleitete Klassen
 22     forward_iterator_base(){}
 23     /// \brief Kopierkonstruktor nur für abgeleitete Klassen
 24     forward_iterator_base(forward_iterator_base const&){}
 25 
 26 public:
 27     /// \brief Postfix-Inkrement-Operator
 28     friend Derived const operator++(Derived& self, int){Derived tmp(self); ++self; return tmp;}
 29     /// \brief Vergleichsoperator auf Ungleichheit
 30     friend bool operator!=(Derived const& lhs, Derived const& rhs){return !(lhs == rhs);}
 31 };
 32 
 33 
 34 /// \brief Basisklasse für alle Bidirectional-Iteratoren
 35 template < typename Derived >
 36 class bidirectional_iterator_base:
 37     public forward_iterator_base< Derived >{
 38 protected:
 39     /// \brief Standardkonstruktor nur für abgeleitete Klassen
 40     bidirectional_iterator_base(){}
 41     /// \brief Kopierkonstruktor nur für abgeleitete Klassen
 42     ///
 43     /// Expliziter Basisklassen-Konstruktoraufruf vermeidet beim Kopierkonstruktor Compilerwarnung
 44     bidirectional_iterator_base(bidirectional_iterator_base const&):
 45         forward_iterator_base< Derived >(){}
 46 
 47 public:
 48     /// \brief Postfix-Dekrement-Operator
 49     friend Derived const operator--(Derived& self, int){Derived tmp(self); --self; return tmp;}
 50 };
 51 
 52 
 53 /// \brief Basisklasse für alle Random-Access-Iteratoren
 54 template < typename Derived, typename DifferenceType >
 55 class random_access_iterator_base:
 56     public bidirectional_iterator_base< Derived >{
 57 protected:
 58     /// \brief Standardkonstruktor nur für abgeleitete Klassen
 59     random_access_iterator_base(){}
 60     /// \brief Kopierkonstruktor nur für abgeleitete Klassen
 61     ///
 62     /// Expliziter Basisklassen-Konstruktoraufruf vermeidet beim Kopierkonstruktor Compilerwarnung
 63     random_access_iterator_base(random_access_iterator_base const&):
 64         bidirectional_iterator_base< Derived >(){}
 65 
 66 public:
 67     /// \brief Vergleichsoperator kleiner
 68     friend bool operator<(Derived const& lhs, Derived const& rhs){
 69         return rhs - lhs > DifferenceType();
 70     }
 71     /// \brief Vergleichsoperator größer
 72     friend bool operator>(Derived const& lhs, Derived const& rhs){return rhs < lhs;}
 73     /// \brief Vergleichsoperator kleiner-gleich
 74     friend bool operator<=(Derived const& lhs, Derived const& rhs){return !(lhs > rhs);}
 75     /// \brief Vergleichsoperator größer-gleich
 76     friend bool operator>=(Derived const& lhs, Derived const& rhs){return !(lhs < rhs);}
 77 
 78     /// \brief Negative Positionsverschiebung
 79     Derived& operator-=(DifferenceType const& difference){
 80         return static_cast< Derived& >(*this) += -difference;
 81     }
 82 
 83     /// \brief Positive Positionsverschiebung als neues Objekt
 84     friend Derived const operator+(Derived lhs, DifferenceType const& rhs){return lhs += rhs;}
 85     /// \brief Positive Positionsverschiebung als neues Objekt
 86     friend Derived const operator+(DifferenceType const& rhs, Derived lhs){return lhs += rhs;}
 87     /// \brief Negative Positionsverschiebung als neues Objekt
 88     friend Derived const operator-(Derived lhs, DifferenceType const& rhs){return lhs -= rhs;}
 89 };
 90 
 91 
 92 
 93 template < typename Matrix >
 94 class row_const_iterator;
 95 
 96 template < typename Matrix >
 97 class row_iterator;
 98 
 99 template < typename Matrix >
100 class column_const_iterator;
101 
102 template < typename Matrix >
103 class column_iterator;
104 
105 
106 
107 /// \brief Basisklasse für alle Zeilen-Iteratoren
108 template < typename Derived, typename MatrixIterator >
109 class row_iterator_base:
110     public random_access_iterator_base< Derived, typename MatrixIterator::difference_type >
111 {
112 public:
113     // types
114     /// \brief Iterator-Trait <code>value_type</code>
115     typedef typename MatrixIterator::value_type      value_type;
116     /// \brief Iterator-Trait <code>difference_type</code>
117     typedef typename MatrixIterator::difference_type difference_type;
118     /// \brief Iterator-Trait <code>pointer</code>
119     typedef typename MatrixIterator::pointer         pointer;
120     /// \brief Iterator-Trait <code>reference</code>
121     typedef typename MatrixIterator::reference       reference;
122     /// \brief Iterator-Trait <code>iterator_category</code> ist
123     ///        <code>std::random_access_iterator_tag</code>
124     typedef std::random_access_iterator_tag          iterator_category;
125 
126     // operators
127     /// \brief Dereferenzierungsoperator
128     reference operator*()const{return *pos_;}
129     /// \brief Member-Zugriffsoperator
130     pointer operator->()const{return pos_;}
131 
132     /// \brief Präfix-Inkrement-Operator
133     Derived& operator++(){++pos_; return static_cast< Derived& >(*this);}
134     /// \brief Präfix-Dekrement-Operator
135     Derived& operator--(){--pos_; return static_cast< Derived& >(*this);}
136 
137     /// \brief Vergleichsoperator auf Gleichheit
138     friend bool operator==(Derived const& lhs, Derived const& rhs){return lhs.pos_ == rhs.pos_;}
139 
140     /// \brief Positive Positionsverschiebung
141     Derived& operator+=(difference_type const& difference){
142         pos_ += difference; return static_cast< Derived& >(*this);
143     }
144 
145     /// \brief Differenzoperator
146     friend difference_type const operator-(Derived const& lhs, Derived const& rhs){
147         return lhs.pos_ - rhs.pos_;
148     }
149 
150     /// \brief Indexoperator
151     reference operator[](difference_type const& index)const{return *(pos_ + index);}
152 
153 protected:
154     // construct/copy/destroy:
155     /// \brief Standardkonstruktor nur für abgeleitete Klassen
156     row_iterator_base(): pos_(MatrixIterator()){}
157     /// \brief Konstruktor zur Erstellung eines gültigen Iterators nur für abgeleitete Klassen
158     row_iterator_base(MatrixIterator const& pos): pos_(pos){}
159     /// \brief Kopierkonstruktor nur für abgeleitete Klassen
160     ///
161     /// Expliziter Basisklassen-Konstruktoraufruf vermeidet beim Kopierkonstruktor Compilerwarnung
162     row_iterator_base(row_iterator_base const& iter): base(), pos_(iter.pos_) {}
163 
164     // data
165     /// \brief Matrixiterator an den Operatoraktionen durchgereicht werden
166     MatrixIterator pos_;
167 
168 private:
169     /// \brief Abkürzung für direkte Basisklasse
170     typedef random_access_iterator_base< Derived, typename MatrixIterator::difference_type > base;
171 };
172 
173 
174 /// \brief Klasse für Zeilen-Iteratoren auf konstanten Matrizen
175 template < typename Matrix >
176 class row_const_iterator:
177     public row_iterator_base< row_const_iterator< Matrix >, typename Matrix::const_iterator >
178 {
179 private:
180     /// \brief Kürzel für die Basisklasse
181     typedef
182     row_iterator_base< row_const_iterator< Matrix >, typename Matrix::const_iterator > base;
183 
184 public:
185     /// \brief Standardkonstruktor
186     row_const_iterator(){}
187     /// \brief Konstruktor zur Erstellung eines gültigen Iterators
188     row_const_iterator(typename Matrix::const_iterator const& pos): base(pos){}
189 };
190 
191 
192 
193 /// \brief Klasse für Zeilen-Iteratoren auf Matrizen
194 template < typename Matrix >
195 class row_iterator:
196     public row_iterator_base< row_iterator< Matrix >, typename Matrix::iterator >
197 {
198 private:
199     /// \brief Kürzel für die Basisklasse
200     typedef row_iterator_base< row_iterator< Matrix >, typename Matrix::iterator > base;
201 
202 public:
203     /// \brief Standardkonstruktor
204     row_iterator(){}
205     /// \brief Konstruktor zur Erstellung eines gültigen Iterators
206     row_iterator(typename Matrix::iterator const& pos): base(pos){}
207 
208     /// \brief Typumwandlung nach <code>row_const_iterator< Matrix ></code>
209     operator row_const_iterator< Matrix >()const{
210         return row_const_iterator< Matrix >(this->pos_);
211     }
212 };
213 
214 
215 
216 /// \brief Basisklasse für alle Spalten-Iteratoren
217 template < typename Derived, typename Matrix, typename MatrixIterator >
218 class column_iterator_base:
219     public random_access_iterator_base< Derived, typename MatrixIterator::difference_type >
220 {
221 public:
222     // types
223     /// \brief Iterator-Trait <code>value_type</code>
224     typedef typename MatrixIterator::value_type      value_type;
225     /// \brief Iterator-Trait <code>difference_type</code>
226     typedef typename MatrixIterator::difference_type difference_type;
227     /// \brief Iterator-Trait <code>pointer</code>
228     typedef typename MatrixIterator::pointer         pointer;
229     /// \brief Iterator-Trait <code>reference</code>
230     typedef typename MatrixIterator::reference       reference;
231     /// \brief Iterator-Trait <code>iterator_category</code> ist
232     ///        <code>std::random_access_iterator_tag</code>
233     typedef std::random_access_iterator_tag          iterator_category;
234 
235     // operators
236     /// \brief Dereferenzierungsoperator
237     reference operator*()const{ return *(matrix_->begin() + pos_); }
238     /// \brief Member-Zugriffsoperator
239     pointer operator->()const{ return matrix_->begin() + pos_; }
240 
241     /// \brief Präfix-Inkrement-Operator
242     Derived& operator++(){
243         pos_ += step_width();
244         return static_cast< Derived& >(*this);
245     }
246     /// \brief Präfix-Dekrement-Operator
247     Derived& operator--(){
248         pos_ -= step_width();
249         return static_cast< Derived& >(*this);
250     }
251 
252     /// \brief Vergleichsoperator auf Gleichheit
253     friend bool operator==(Derived const& lhs, Derived const& rhs){
254         return lhs.pos_ == rhs.pos_ && lhs.matrix_ == rhs.matrix_;
255     }
256 
257     /// \brief Positive Positionsverschiebung
258     Derived& operator+=(difference_type const& difference){
259         pos_ += difference * step_width();
260         return static_cast< Derived& >(*this);
261     }
262 
263     /// \brief Differenzoperator
264     friend difference_type const operator-(Derived const& lhs, Derived const& rhs){
265         return (rhs.pos_ - lhs.pos_) / lhs.step_width();
266     }
267 
268     /// \brief Indexoperator
269     reference operator[](difference_type const& index)const{
270         return *(static_cast< Derived const& >(*this) + index);
271     }
272 
273 protected:
274     // construct/copy/destroy:
275     /// \brief Standardkonstruktor nur für abgeleitete Klassen
276     column_iterator_base():
277         matrix_(0), pos_(difference_type()){}
278 
279     /// \brief Konstruktor zur Erstellung eines gültigen Iterators nur für abgeleitete Klassen
280     column_iterator_base(Matrix& matrix, difference_type const& pos):
281         matrix_(&matrix), pos_(pos){}
282 
283     /// \brief Kopierkonstruktor nur für abgeleitete Klassen
284     ///
285     /// Expliziter Basisklassen-Konstruktoraufruf vermeidet beim Kopierkonstruktor Compilerwarnung
286     column_iterator_base(column_iterator_base const& iter):
287         base(), matrix_(iter.matrix_), pos_(iter.pos_){}
288 
289     // data
290     /// \brief Verweis auf ein <code>matrix</code>-Objekt
291     Matrix*         matrix_;
292     /// \brief Position des Iterators gemessen von <code>matrix_.begin()</code> in
293     ///        Matrixiterator-Einheiten
294     difference_type pos_;
295 
296 private:
297     // helper
298     /// \brief Gibt die Zeilenlänge zurück
299     difference_type const step_width(){ return matrix_->columns(); }
300 
301     /// \brief Abkürzung für direkte Basisklasse
302     typedef random_access_iterator_base< Derived, typename MatrixIterator::difference_type > base;
303 };
304 
305 /// \brief Klasse für Spalten-Iteratoren auf konstanten Matrizen
306 template < typename Matrix >
307 class column_const_iterator:
308     public column_iterator_base<
309         column_const_iterator< Matrix >, Matrix const, typename Matrix::const_iterator
310     >
311 {
312 private:
313     /// \brief Kürzel für die Basisklasse
314     typedef column_iterator_base<
315         column_const_iterator< Matrix >, Matrix const, typename Matrix::const_iterator
316     > base;
317 
318 public:
319     /// \brief Standardkonstruktor
320     column_const_iterator(){}
321     /// \brief Konstruktor zur Erstellung eines gültigen Iterators
322     column_const_iterator(Matrix const& matrix, typename base::difference_type const& pos):
323         base(matrix, pos){}
324 };
325 
326 
327 
328 /// \brief Klasse für Spalten-Iteratoren auf Matrizen
329 template < typename Matrix >
330 class column_iterator:
331     public column_iterator_base< column_iterator< Matrix >, Matrix, typename Matrix::iterator >
332 {
333 private:
334     /// \brief Kürzel für die Basisklasse
335     typedef
336     column_iterator_base< column_iterator< Matrix >, Matrix, typename Matrix::iterator > base;
337 
338 public:
339     /// \brief Standardkonstruktor
340     column_iterator(){}
341     /// \brief Konstruktor zur Erstellung eines gültigen Iterators
342     column_iterator(Matrix& matrix, typename base::difference_type const& pos): base(matrix, pos){}
343 
344     /// \brief Typumwandlung nach <code>column_const_iterator< Matrix ></code>
345     operator column_const_iterator< Matrix >()const{
346         return column_const_iterator< Matrix >(*this->matrix_, this->pos_);
347     }
348 };
349 
350 
351 } }
352 
353 #endif