0
namespace Log {
#include <ctime>
#include <string>
#include <boost\scoped_ptr.hpp>

#ifndef LOG_PREPEND_TIMESTAMP_DEFAULT
    #define LOG_PREPEND_TIMESTAMP_DEFAULT false
#endif

enum LogLevel_t { logFatal = 0, logError = 1, logWarning = 2, logVerbose = 3, logDebug = 4 };

std::string LogLevelToString( const LogLevel_t level ) {
    static const char* const buffer[] = { "Fatal", "Error", "Warning", "Verbose", "Debug" };
    return buffer[level];
}
class Log: public boost::noncopyable {
protected:
    boost::scoped_ptr< std::ostringstream > Output_String;
    bool m_Prepending_Timestamp;
    size_t m_LinesOutputted;
public:
    Log():
          Output_String( new std::ostringstream ),
          m_Prepending_Timestamp( LOG_PREPEND_TIMESTAMP_DEFAULT ),
          m_LinesOutputted( 0 ) {}

    void UsingTimestamp( bool Prepending_Timestamp = true ) {
        m_Prepending_Timestamp = Prepending_Timestamp;
    }

    std::ostringstream& Get( const LogLevel_t level ) {
        // Write line number
        ++m_LinesOutputted;
        *Output_String << m_LinesOutputted << " | ";

        if( m_Prepending_Timestamp == true ) {
            //prepare a timestamp
            time_t now = time( NULL );
            std::string formatted_time( asctime( localtime( &now ) ) ); /* &now can be replaced with the above call when r-value references work (maybe) saving a stack var */
            formatted_time.erase(( formatted_time.length( ) - 1 ), 1 );  /* Removes the \n(newline) that asctime adds for better formatting */
            // Write timestamp to stream
            *Output_String << formatted_time << " || ";
        }

        // Write Logging level(severity) to stream
        *Output_String << LogLevelToString( level ) << " || ";
        return *Output_String;
    }

    void Flush() {
        *Output_String << std::endl;
        fprintf( stdout, "%s", Output_String->str( ).c_str( ) );
        fflush( stdout );

        Output_String.reset( new std::ostringstream ); /* streams have lots of internal state clean streams are good */
    }

    ~Log() {
        *Output_String << std::endl;
        fprintf( stdout, "%s", Output_String->str( ).c_str( ) );
        fflush( stdout );
    }
};

如果没有宏,我将如何实现阈值?

如果我用支票包裹 get 的主体,我仍然必须返回字符串流。

我可以将返回类型更改为指针而不是引用,然后返回 NULL 但是每个记录器语句都必须对返回的字符串流进行空检查

4

0 回答 0