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

Aus Wikibooks
#ifndef _mitrax_mitrax_dimension_hpp_INCLUDED_
#define _mitrax_mitrax_dimension_hpp_INCLUDED_
/// \file dimension.hpp
///
/// \brief Dimensionstyp für Matrizen
///
/// Diese Datei stellt einen Datentyp <code>dimension</code> bereit, welcher eine Anzahl von Zeilen
/// und Spalten zusammenfasst.

namespace mitrax{

/// \brief Speichert eine Anzahl von Zeilen und Spalten.
///
/// \param T Typ von dem die Anzahl von Zeilen und Spalten sein soll.
///
/// Ein Objekt einer <code>dimension</code> enthält eine Anzahl von Zeilen und Spalten. Die
/// Zusammenfassung dieser beiden Größen in einem Datentyp erhöht die Lesbarkeit des Codes.
/// Insbesondere Vergleiche von 2 Dimensionen lassen sich besser darstellen.
///
/// Innerhalb dieser Dokumentation wird dimension(„Zeilenanzahl“, „Spaltenanzahl“) geschrieben,
/// wenn eine <code>dimension</code> mit „Zeilenanzahl“ Zeilen und „Spaltenanzahl“ Spalten gemeint
/// ist.
template < typename T >
class dimension{
public:
    /// \brief Typ von dem die Anzahl von Zeilen und Spalten ist.
    typedef T value_type;


    /// \brief Standardkonstruktor
    ///
    /// Erstellt eine <code>dimension</code> mit dimension(<code>value_type()</code>,
    /// <code>value_type()</code>). Für eingebaute Datentypen entspricht das dimension(0, 0).
    ///
    /// Bedingung:
    ///   - <code>value_type</code> muss defaultkonstruierbar sein.
    dimension(): rows_(T()), columns_(T()){}
    /// \brief Erstellen mit dimension(<code>rows</code>, <code>columns</code>)
    dimension(value_type const& rows, value_type const& columns): rows_(rows), columns_(columns){}
    /// \brief Erstellung aus einem kompatiblen <code>SizeType</code>-Objekt mit
    ///        dimension(<code>size.height()</code>, <code>size.width()</code>)
    ///
    /// Oft existieren bereits Typen, die ebenfalls eine Breite (Anzahl Spalten) und Höhe (Anzahl
    /// Zeilen) bereitstellen. Falls <code>SizeType</code> die Methoden <code>width()</code> und
    /// <code>height()</code> anbietet, kann daraus ein <code>dimension</code>-Objekt konstruiert
    /// werden.
    ///
    /// Bedingungen:
    ///   - <code>width()</code> und <code>height()</code> müssen existieren,
    ///   - sie müssen konstante Methoden sein
    ///   - und einen implizit in <code>value_type</code> wandelbaren Rückgabetyp besitzen.
    ///
    /// <code>explicit</code> wird verwendet, um implizite Umwandlung nach <code>dimension</code>
    /// und die Schreibweise <code>dimension< T > name = SizeType();</code> zu verhindern, wobei
    /// <code>SizeType()</code> ein beliebiges Objekt vom Typ <code>SizeType</code> sein kann.
    template < typename SizeType >
    explicit dimension(SizeType const& size): rows_(size.height()), columns_(size.width()){}


    /// \brief Setzt die <code>dimension</code> auf dimension(rows, columns)
    void resize(value_type const& rows, value_type const& columns){
        rows_ = rows; columns_ = columns;
    }

    /// \brief Lesezugriff auf Anzahl der Zeilen
    value_type const rows()const{ return rows_; }
    /// \brief Lesezugriff auf Anzahl der Spalten
    value_type const columns()const{ return columns_; }

private:
    /// \brief Anzahl der Zeilen
    value_type rows_;
    /// \brief Anzahl der Spalten
    value_type columns_;
};


/// \brief Zeilen * Spalten
///
/// Gibt das Produkt aus Zeilen und Spalten der Dimension zurück.
template < typename T >
T elements(dimension< T > const& value){
    return value.rows() * value.columns();
}

/// \brief Liefert <code>true</code> wenn die Anzahl der Zeilen und Spalten übereinstimmt.
template < typename T >
bool operator==(dimension< T > const& lhs, dimension< T > const& rhs){
    return lhs.rows() == rhs.rows() && lhs.columns() == rhs.columns();
}

/// \brief Liefert <code>true</code> wenn die Anzahl der Zeilen oder Spalten nicht übereinstimmt.
template < typename T >
bool operator!=(dimension< T > const& lhs, dimension< T > const& rhs){
    return !(lhs == rhs);
}

}

#endif