C++-Programmierung/ Eine Matrix-Bibliothek – mitrax/ proxy iterator.hpp
Erscheinungsbild
#ifndef _mitrax_mitrax_detail_proxy_iterator_hpp_INCLUDED_
#define _mitrax_mitrax_detail_proxy_iterator_hpp_INCLUDED_
/// \file proxy_iterator.hpp
///
/// \brief Proxyiteratorklassen
///
/// Diese Datei stellt allgemeine Basisklassen für Forward-, Bidirectional- und
/// Random-Access-Iteratoren bereit. Von dieses sind die vier Proxyiteratorklassen abgleitet.
/// Ein Nutzer von mitrax sollte keinen direkten Kontakt mit diesen Klassen haben, daher stehen
/// alle im Namensraum <code>detail</code>.
#include <iterator>
#include <memory>
namespace mitrax { namespace detail {
/// \brief Basisklasse für alle Forward-Iteratoren
template < typename Derived >
class forward_iterator_base{
protected:
/// \brief Standardkonstruktor nur für abgeleitete Klassen
forward_iterator_base(){}
/// \brief Kopierkonstruktor nur für abgeleitete Klassen
forward_iterator_base(forward_iterator_base const&){}
public:
/// \brief Postfix-Inkrement-Operator
friend Derived const operator++(Derived& self, int){Derived tmp(self); ++self; return tmp;}
/// \brief Vergleichsoperator auf Ungleichheit
friend bool operator!=(Derived const& lhs, Derived const& rhs){return !(lhs == rhs);}
};
/// \brief Basisklasse für alle Bidirectional-Iteratoren
template < typename Derived >
class bidirectional_iterator_base:
public forward_iterator_base< Derived >{
protected:
/// \brief Standardkonstruktor nur für abgeleitete Klassen
bidirectional_iterator_base(){}
/// \brief Kopierkonstruktor nur für abgeleitete Klassen
///
/// Expliziter Basisklassen-Konstruktoraufruf vermeidet beim Kopierkonstruktor Compilerwarnung
bidirectional_iterator_base(bidirectional_iterator_base const&):
forward_iterator_base< Derived >(){}
public:
/// \brief Postfix-Dekrement-Operator
friend Derived const operator--(Derived& self, int){Derived tmp(self); --self; return tmp;}
};
/// \brief Basisklasse für alle Random-Access-Iteratoren
template < typename Derived, typename DifferenceType >
class random_access_iterator_base:
public bidirectional_iterator_base< Derived >{
protected:
/// \brief Standardkonstruktor nur für abgeleitete Klassen
random_access_iterator_base(){}
/// \brief Kopierkonstruktor nur für abgeleitete Klassen
///
/// Expliziter Basisklassen-Konstruktoraufruf vermeidet beim Kopierkonstruktor Compilerwarnung
random_access_iterator_base(random_access_iterator_base const&):
bidirectional_iterator_base< Derived >(){}
public:
/// \brief Vergleichsoperator kleiner
friend bool operator<(Derived const& lhs, Derived const& rhs){
return rhs - lhs > DifferenceType();
}
/// \brief Vergleichsoperator größer
friend bool operator>(Derived const& lhs, Derived const& rhs){return rhs < lhs;}
/// \brief Vergleichsoperator kleiner-gleich
friend bool operator<=(Derived const& lhs, Derived const& rhs){return !(lhs > rhs);}
/// \brief Vergleichsoperator größer-gleich
friend bool operator>=(Derived const& lhs, Derived const& rhs){return !(lhs < rhs);}
/// \brief Negative Positionsverschiebung
Derived& operator-=(DifferenceType const& difference){
return static_cast< Derived& >(*this) += -difference;
}
/// \brief Positive Positionsverschiebung als neues Objekt
friend Derived const operator+(Derived lhs, DifferenceType const& rhs){return lhs += rhs;}
/// \brief Positive Positionsverschiebung als neues Objekt
friend Derived const operator+(DifferenceType const& rhs, Derived lhs){return lhs += rhs;}
/// \brief Negative Positionsverschiebung als neues Objekt
friend Derived const operator-(Derived lhs, DifferenceType const& rhs){return lhs -= rhs;}
};
template < typename Matrix >
class row_const_iterator;
template < typename Matrix >
class row_iterator;
template < typename Matrix >
class column_const_iterator;
template < typename Matrix >
class column_iterator;
/// \brief Basisklasse für alle Zeilen-Iteratoren
template < typename Derived, typename MatrixIterator >
class row_iterator_base:
public random_access_iterator_base< Derived, typename MatrixIterator::difference_type >
{
public:
// types
/// \brief Iterator-Trait <code>value_type</code>
typedef typename MatrixIterator::value_type value_type;
/// \brief Iterator-Trait <code>difference_type</code>
typedef typename MatrixIterator::difference_type difference_type;
/// \brief Iterator-Trait <code>pointer</code>
typedef typename MatrixIterator::pointer pointer;
/// \brief Iterator-Trait <code>reference</code>
typedef typename MatrixIterator::reference reference;
/// \brief Iterator-Trait <code>iterator_category</code> ist
/// <code>std::random_access_iterator_tag</code>
typedef std::random_access_iterator_tag iterator_category;
// operators
/// \brief Dereferenzierungsoperator
reference operator*()const{return *pos_;}
/// \brief Member-Zugriffsoperator
pointer operator->()const{return pos_;}
/// \brief Präfix-Inkrement-Operator
Derived& operator++(){++pos_; return static_cast< Derived& >(*this);}
/// \brief Präfix-Dekrement-Operator
Derived& operator--(){--pos_; return static_cast< Derived& >(*this);}
/// \brief Vergleichsoperator auf Gleichheit
friend bool operator==(Derived const& lhs, Derived const& rhs){return lhs.pos_ == rhs.pos_;}
/// \brief Positive Positionsverschiebung
Derived& operator+=(difference_type const& difference){
pos_ += difference; return static_cast< Derived& >(*this);
}
/// \brief Differenzoperator
friend difference_type const operator-(Derived const& lhs, Derived const& rhs){
return lhs.pos_ - rhs.pos_;
}
/// \brief Indexoperator
reference operator[](difference_type const& index)const{return *(pos_ + index);}
protected:
// construct/copy/destroy:
/// \brief Standardkonstruktor nur für abgeleitete Klassen
row_iterator_base(): pos_(MatrixIterator()){}
/// \brief Konstruktor zur Erstellung eines gültigen Iterators nur für abgeleitete Klassen
row_iterator_base(MatrixIterator const& pos): pos_(pos){}
/// \brief Kopierkonstruktor nur für abgeleitete Klassen
///
/// Expliziter Basisklassen-Konstruktoraufruf vermeidet beim Kopierkonstruktor Compilerwarnung
row_iterator_base(row_iterator_base const& iter): base(), pos_(iter.pos_) {}
// data
/// \brief Matrixiterator an den Operatoraktionen durchgereicht werden
MatrixIterator pos_;
private:
/// \brief Abkürzung für direkte Basisklasse
typedef random_access_iterator_base< Derived, typename MatrixIterator::difference_type > base;
};
/// \brief Klasse für Zeilen-Iteratoren auf konstanten Matrizen
template < typename Matrix >
class row_const_iterator:
public row_iterator_base< row_const_iterator< Matrix >, typename Matrix::const_iterator >
{
private:
/// \brief Kürzel für die Basisklasse
typedef
row_iterator_base< row_const_iterator< Matrix >, typename Matrix::const_iterator > base;
public:
/// \brief Standardkonstruktor
row_const_iterator(){}
/// \brief Konstruktor zur Erstellung eines gültigen Iterators
row_const_iterator(typename Matrix::const_iterator const& pos): base(pos){}
};
/// \brief Klasse für Zeilen-Iteratoren auf Matrizen
template < typename Matrix >
class row_iterator:
public row_iterator_base< row_iterator< Matrix >, typename Matrix::iterator >
{
private:
/// \brief Kürzel für die Basisklasse
typedef row_iterator_base< row_iterator< Matrix >, typename Matrix::iterator > base;
public:
/// \brief Standardkonstruktor
row_iterator(){}
/// \brief Konstruktor zur Erstellung eines gültigen Iterators
row_iterator(typename Matrix::iterator const& pos): base(pos){}
/// \brief Typumwandlung nach <code>row_const_iterator< Matrix ></code>
operator row_const_iterator< Matrix >()const{
return row_const_iterator< Matrix >(this->pos_);
}
};
/// \brief Basisklasse für alle Spalten-Iteratoren
template < typename Derived, typename Matrix, typename MatrixIterator >
class column_iterator_base:
public random_access_iterator_base< Derived, typename MatrixIterator::difference_type >
{
public:
// types
/// \brief Iterator-Trait <code>value_type</code>
typedef typename MatrixIterator::value_type value_type;
/// \brief Iterator-Trait <code>difference_type</code>
typedef typename MatrixIterator::difference_type difference_type;
/// \brief Iterator-Trait <code>pointer</code>
typedef typename MatrixIterator::pointer pointer;
/// \brief Iterator-Trait <code>reference</code>
typedef typename MatrixIterator::reference reference;
/// \brief Iterator-Trait <code>iterator_category</code> ist
/// <code>std::random_access_iterator_tag</code>
typedef std::random_access_iterator_tag iterator_category;
// operators
/// \brief Dereferenzierungsoperator
reference operator*()const{ return *(matrix_->begin() + pos_); }
/// \brief Member-Zugriffsoperator
pointer operator->()const{ return matrix_->begin() + pos_; }
/// \brief Präfix-Inkrement-Operator
Derived& operator++(){
pos_ += step_width();
return static_cast< Derived& >(*this);
}
/// \brief Präfix-Dekrement-Operator
Derived& operator--(){
pos_ -= step_width();
return static_cast< Derived& >(*this);
}
/// \brief Vergleichsoperator auf Gleichheit
friend bool operator==(Derived const& lhs, Derived const& rhs){
return lhs.pos_ == rhs.pos_ && lhs.matrix_ == rhs.matrix_;
}
/// \brief Positive Positionsverschiebung
Derived& operator+=(difference_type const& difference){
pos_ += difference * step_width();
return static_cast< Derived& >(*this);
}
/// \brief Differenzoperator
friend difference_type const operator-(Derived const& lhs, Derived const& rhs){
return (rhs.pos_ - lhs.pos_) / lhs.step_width();
}
/// \brief Indexoperator
reference operator[](difference_type const& index)const{
return *(static_cast< Derived const& >(*this) + index);
}
protected:
// construct/copy/destroy:
/// \brief Standardkonstruktor nur für abgeleitete Klassen
column_iterator_base():
matrix_(0), pos_(difference_type()){}
/// \brief Konstruktor zur Erstellung eines gültigen Iterators nur für abgeleitete Klassen
column_iterator_base(Matrix& matrix, difference_type const& pos):
matrix_(&matrix), pos_(pos){}
/// \brief Kopierkonstruktor nur für abgeleitete Klassen
///
/// Expliziter Basisklassen-Konstruktoraufruf vermeidet beim Kopierkonstruktor Compilerwarnung
column_iterator_base(column_iterator_base const& iter):
base(), matrix_(iter.matrix_), pos_(iter.pos_){}
// data
/// \brief Verweis auf ein <code>matrix</code>-Objekt
Matrix* matrix_;
/// \brief Position des Iterators gemessen von <code>matrix_.begin()</code> in
/// Matrixiterator-Einheiten
difference_type pos_;
private:
// helper
/// \brief Gibt die Zeilenlänge zurück
difference_type const step_width(){ return matrix_->columns(); }
/// \brief Abkürzung für direkte Basisklasse
typedef random_access_iterator_base< Derived, typename MatrixIterator::difference_type > base;
};
/// \brief Klasse für Spalten-Iteratoren auf konstanten Matrizen
template < typename Matrix >
class column_const_iterator:
public column_iterator_base<
column_const_iterator< Matrix >, Matrix const, typename Matrix::const_iterator
>
{
private:
/// \brief Kürzel für die Basisklasse
typedef column_iterator_base<
column_const_iterator< Matrix >, Matrix const, typename Matrix::const_iterator
> base;
public:
/// \brief Standardkonstruktor
column_const_iterator(){}
/// \brief Konstruktor zur Erstellung eines gültigen Iterators
column_const_iterator(Matrix const& matrix, typename base::difference_type const& pos):
base(matrix, pos){}
};
/// \brief Klasse für Spalten-Iteratoren auf Matrizen
template < typename Matrix >
class column_iterator:
public column_iterator_base< column_iterator< Matrix >, Matrix, typename Matrix::iterator >
{
private:
/// \brief Kürzel für die Basisklasse
typedef
column_iterator_base< column_iterator< Matrix >, Matrix, typename Matrix::iterator > base;
public:
/// \brief Standardkonstruktor
column_iterator(){}
/// \brief Konstruktor zur Erstellung eines gültigen Iterators
column_iterator(Matrix& matrix, typename base::difference_type const& pos): base(matrix, pos){}
/// \brief Typumwandlung nach <code>column_const_iterator< Matrix ></code>
operator column_const_iterator< Matrix >()const{
return column_const_iterator< Matrix >(*this->matrix_, this->pos_);
}
};
} }
#endif