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

#ifndef _mitrax_mitrax_iomanip_hpp_INCLUDED_
#define _mitrax_mitrax_iomanip_hpp_INCLUDED_
/// \file iomanip.hpp
///
/// \brief Ausgabemanipulatoren
///
/// In dieser Datei werden derzeit die beiden Ausgabemanipulatoren für die minimale Elementbreite
/// und den Mehrzeilenmodus implementiert.

namespace mitrax{

namespace detail{

/// \brief Eindeutige Speicherposition für Mindestausgabebreite
long& element_width_flag(std::ios_base& s){
    static int const unique_index = std::ios_base::xalloc();
    return s.iword(unique_index);
}

/// \brief Positionen verschiedener <code>bool</code>-Ausgabeflags innerhalb der entsprechenden
///        Speicherposition
struct format_flags{
    /// \brief Gesetzt für mehrzeilige Ausgabe
    static long const multi_line = 0x01;
};

/// \brief Eindeutige Speicherposition für <code>bool</code>-Flags
///
/// Erzeugt eine neue, eindeutige Speicherposition innerhalb eines Streams <code>s</code>,
/// in der mehrere <code>bool</code>-Werte Platz finden können.
///
/// siehe format_flags
long& format_flags_flag(std::ios_base& s){
    static int const unique_index = std::ios_base::xalloc();
    return s.iword(unique_index);
}


}

/// \brief Lesezugriff auf die Mindestausgabebreite eines Elements
long get_element_width_flag(std::ios_base& s){
    return detail::element_width_flag(s);
}

/// \brief Schreibzugriff auf die Mindestausgabebreite eines Elements
void set_element_width_flag(std::ios_base& s, long n){
    detail::element_width_flag(s) = n;
}


/// \brief Lesezugriff auf das Flag für mehrzeilige Ausgabe
bool get_multi_line_flag(std::ios_base& s){
    return detail::format_flags_flag(s) & detail::format_flags::multi_line;
}

/// \brief Schreibzugriff auf das Flag für mehrzeilige Ausgabe
void set_multi_line_flag(std::ios_base& s, bool f){
    if(f){
        detail::format_flags_flag(s) |= detail::format_flags::multi_line;
    }else{
        detail::format_flags_flag(s) &= ~static_cast< long >(detail::format_flags::multi_line);
    }
}



/// \brief Klasse für ein Objekt, das für einen Ausgabestream die Mindestausgabebreite setzt
///
/// Verwendung:
///   - <code>os << set_element_width(Ganzzahl);</code>
class set_element_width{
/// \brief Setzten der Mindestausgabebreite <code>f</code> eines Elements für einen beliebigen
///        Ausgabestream <code>os</code>
template < class charT, class traits >
friend std::basic_ostream< charT, traits >&
operator<<(std::basic_ostream< charT, traits >& os, set_element_width const& f){
    set_element_width_flag(os, f.width_);
    return os;
}
public:
    /// \brief Erzeugt ein Objekt, dass die gewünschte Mindestausgabebreite enthält
    set_element_width(long width):width_(width){}
private:
    /// \brief Die Mindestausgabebreite
    long const width_;
};

/// \brief Klasse für ein Objekt, das für einen Ausgabestream das <code>multi_line</code>-Flag
///        setzt
///
/// Verwendung:
///   - <code>os << set_multi_line(bool);</code>
class set_multi_line{
/// \brief Setzten des multi_line-Flags f für einen beliebigen Ausgabestream os
template < class charT, class traits >
friend std::basic_ostream< charT, traits >&
operator<<(std::basic_ostream< charT, traits >& os, set_multi_line const& f){
    set_multi_line_flag(os, f.on_);
    return os;
}
public:
    /// \brief Erzeugt ein Objekt, welches den Zustand des <code>multi_line</code>-Flags enthält
    set_multi_line(bool on):on_(on){}
private:
    /// \brief Das <code>multi_line</code>-Flag
    bool const on_;
};

/// \brief Mehrzeilige Ausgabe aktivieren
///
/// Verwendung:
///   - <code>os << multi_line;</code>
set_multi_line multi_line = true;
/// \brief Mehrzeilige Ausgabe deaktivieren
///
/// Verwendung:
///   - <code>os << single_line;</code>
set_multi_line single_line = false;

}

#endif