Program Listing for File output_text_stream.hpp

Return to documentation for file (/tmp/ws/src/ecl_core/ecl_streams/include/ecl/streams/text_streams/output_text_stream.hpp)

/*****************************************************************************
** Ifdefs
*****************************************************************************/

#ifndef ECL_STREAMS_OUTPUT_TEXT_STREAM_HPP_
#define ECL_STREAMS_OUTPUT_TEXT_STREAM_HPP_

/*****************************************************************************
** Includes
*****************************************************************************/

#include <cstring>
#include <string>
#include <ecl/config/macros.hpp>
#include <ecl/exceptions/standard_exception.hpp>
#include <ecl/converters.hpp>
#include <ecl/concepts/devices.hpp>
#include "../manipulators/manipulator.hpp"
#include "../macros.hpp"

/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace ecl {
namespace interfaces {

/*****************************************************************************
** Interface [OutputTextStream]
*****************************************************************************/

template <typename Device, bool OutputDevice = true >
class ECL_PUBLIC OutputTextStream {};

template <typename Device>
class ECL_PUBLIC OutputTextStream<Device,true> : public virtual BaseTextStream<Device> {
    public:
        OutputTextStream() :
            toCharString(30) // character buffer size
        {
            ecl_compile_time_concept_check(OutputCharDeviceConcept<Device>);
        };

        virtual ~OutputTextStream() {}

        OutputTextStream<Device>& operator << ( const char &c );
        OutputTextStream<Device>& operator << ( const char *s );
        OutputTextStream<Device>& operator << ( const std::string &s );
        OutputTextStream<Device>& operator << ( const short &i );
        OutputTextStream<Device>& operator << ( const int &i );
        OutputTextStream<Device>& operator << ( const long &i );
        OutputTextStream<Device>& operator << ( const long long &i );
        OutputTextStream<Device>& operator << ( const unsigned short &i );
        OutputTextStream<Device>& operator << ( const unsigned int &i );
        OutputTextStream<Device>& operator << ( const unsigned long &i );
        OutputTextStream<Device>& operator << ( const unsigned long long &i );
        OutputTextStream<Device>& operator << ( const bool b );
        OutputTextStream<Device>& operator << ( const float &f );
        OutputTextStream<Device>& operator << ( const double &d );

        /*********************
         * Friend Manipulators
         *********************/
        template <typename Action>
        OutputTextStream<Device>& operator << ( ecl::Manipulator<Action> &manipulator )
        {
            manipulator.insert(*this);
            return *this;
        }

//        friend interfaces::OutputTextStream& operator << (interfaces::OutputTextStream& ostream, void (*manipulator)(interfaces::OutputTextStream&) )
//        {
//            (*manipulator)(ostream);
//            return ostream;
//        }

        /*********************
          ** Buffer functionality
        **********************/
         void flush();

    private:
        ecl::Converter<char*> toCharString;
};

/*****************************************************************************
** Implementation [OutputTextStream]
*****************************************************************************/

template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator<< ( const char& c ) {
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    this->io_device.write(c);
    return *this;
}
template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const char *s ) {
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    this->io_device.write(s,strlen(s));
    return *this;
}

template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const std::string &s ) {
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    this->io_device.write(&s[0],s.size());
    return *this;
}
template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const short &i )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(i);
    return *this;
}
template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const int &i )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(i);
    return *this;
}

template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const long &i )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(i);
    return *this;
}

template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const long long &i )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(i);
    return *this;
}

template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const unsigned short &i )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(i);
    return *this;
}

template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const unsigned int &i )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(i);
    return *this;
}

template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const unsigned long &i )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(i);
    return *this;
}
template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const unsigned long long &i )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(i);
    return *this;
}
template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const bool b )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    if ( b ) { *this << "true"; } else { *this << "false"; };
    return *this;
}

template <typename Device>
OutputTextStream<Device>& OutputTextStream<Device,true>::operator << ( const float &f )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(f);
    return *this;
}

template <typename Device>
OutputTextStream<Device>&  OutputTextStream<Device,true>::operator << ( const double &d )
{
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    *this << toCharString(d);
    return *this;
}

template <typename Device>
void OutputTextStream<Device,true>::flush() {
    ecl_assert_throw(this->io_device.open(),ecl::StandardException(LOC,OpenError,"The underlying stream device is not open."));
    this->io_device.flush();
}

} // namespace interfaces
} // namespace ecl

#endif /* ECL_STREAMS_OUTPUT_TEXT_STREAM_HPP_ */