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

#ifndef _mitrax_mitrax_exception_hpp_INCLUDED_
#define _mitrax_mitrax_exception_hpp_INCLUDED_
/// \file exception.hpp
///
/// \brief Ausnahmeklassen von mitrax
///
/// Diese Datei stellt die Klassen bereit, die innerhalb von mitrax als Ausnahmen geworfen werden.
/// Sie sind von den Ausnahmeklassen der C++-Standardbibliothek abgeleitet.

#include "dimension.hpp"
#include "matrix.hpp"

#include <stdexcept>
#include <sstream>

namespace mitrax{ namespace error {

/// \brief Zugriff auf ungültige Position
class access: public std::out_of_range{
public:
    explicit access(std::string const& what):std::out_of_range(what){}
    explicit access(char const* what):std::out_of_range(what){}
};

/// \brief Zugriff auf ungültige Zeile
class row_access: public access{
public:
    template < typename SizeType >
    row_access(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        SizeType const& row_number
    ):
        access(make_text(text, size, row_number))
        {}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        SizeType const& row_number
    ){
        std::ostringstream error;
        error << text << ": Dimension(" << size.rows() << ", " << size.columns()
            << "): access in row " << row_number << " not allowed";
        return error.str();
    }
};

/// \brief Zugriff auf ungültige Spalte
class column_access: public access{
public:
    template < typename SizeType >
    column_access(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        SizeType const& column_number
    ):
        access(make_text(text, size, column_number))
        {}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        SizeType const& column_number
    ){
        std::ostringstream error;
        error << text << ": Dimension(" << size.rows() << ", " << size.columns()
            << "): access in column " << column_number << " not allowed";
        return error.str();
    }
};

/// \brief Container mit ungültiger Größe
class data_size: public std::logic_error{
public:
    template < typename SizeType, typename Container >
    data_size(std::string const& text, dimension< SizeType > const& size, Container const& data):
        std::logic_error(make_text(text, size, data))
        {}

private:
    template < typename SizeType, typename Container >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        Container const& data
    ){
        std::ostringstream error;
        error << text << ": Dimension(" << size.rows() << ", " << size.columns()
            << ") not compatible with data-size " << data.size();
        return error.str();
    }
};

/// \brief Fehler in Zusammenhang mit einer Dimension
class dimension: public std::logic_error{
public:
    explicit dimension(std::string const& what):std::logic_error(what){}
    explicit dimension(char const* what):std::logic_error(what){}
};

/// \brief Dimensionen müssen gleich sein
class dimension_unequal: public dimension{
public:
    template < typename SizeType >
    dimension_unequal(
        std::string const& text,
        mitrax::dimension< SizeType > const& lhs,
        mitrax::dimension< SizeType > const& rhs
    ):
        dimension(make_text(text, lhs, rhs)){}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& lhs,
        mitrax::dimension< SizeType > const& rhs
    ){
        std::ostringstream error;
        error << text << ": lhs.dimension(" << lhs.rows() << ", " << lhs.columns()
            << ") != rhs.dimension(" << rhs.rows() << ", " << rhs.columns() << ")";
        return error.str();
    }
};

/// \brief Dimensionen müssen kompatibel sein
class dimension_incompatible: public dimension{
public:
    template < typename SizeType >
    dimension_incompatible(
        std::string const& text,
        mitrax::dimension< SizeType > const& lhs,
        mitrax::dimension< SizeType > const& rhs
    ):
        dimension(make_text(text, lhs, rhs)){}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& lhs,
        mitrax::dimension< SizeType > const& rhs
    ){
        std::ostringstream error;
        error << text << ": lhs.dimension(" << lhs.rows() << ", " << lhs.columns()
            << "), rhs.dimension(" << rhs.rows() << ", " << rhs.columns() << ")";
        return error.str();
    }
};

/// \brief Anzahl der Zeilen und Spalten muss gleich sein
class not_quadratic: public dimension{
public:
    template < typename SizeType >
    not_quadratic(std::string const& text, mitrax::dimension< SizeType > const& dim):
        dimension(make_text(text, dim)){}

private:
    template < typename SizeType >
    static std::string const
    make_text(std::string const& text, mitrax::dimension< SizeType > const& dim){
        std::ostringstream error;
        error << text << ": dimension(" << dim.rows() << ", " << dim.columns() << ")";
        return error.str();
    }
};

/// \brief Operation für singuläre Matrizen nicht durchführbar
class singular_matrix: public std::logic_error{
public:
    explicit singular_matrix(std::string const& what):std::logic_error(what){}
    explicit singular_matrix(char const* what):std::logic_error(what){}
};

/// \brief Größen müssen gleich sein
class size_unequal: public std::logic_error{
public:
    template < typename SizeType >
    size_unequal(std::string const& text, SizeType const& lhs, SizeType const& rhs):
        std::logic_error(make_text(text, lhs, rhs)){}

private:
    template < typename SizeType >
    static std::string const
    make_text(std::string const& text, SizeType const& lhs, SizeType const& rhs){
        std::ostringstream error;
        error << text << ": " << lhs << " != " << rhs;
        return error.str();
    }
};

} }

#endif