lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
log.h
00001 /*****************************************************/
00002 /* lean Logging                 (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_LOGGING_LOG
00006 #define LEAN_LOGGING_LOG
00007 
00008 #include "../lean.h"
00009 #include "../tags/noncopyable.h"
00010 #include "../strings/types.h"
00011 #include "../strings/conversions.h"
00012 #include "../concurrent/spin_lock.h"
00013 #include "../concurrent/shareable_spin_lock.h"
00014 #include "log_target.h"
00015 #include <vector>
00016 #include <iosfwd>
00017 #include <ostream>
00018 #include "streamconv.h"
00019 
00020 namespace lean
00021 {
00022 namespace logging
00023 {
00024 
00025 class log_stream_out;
00026 
00028 class log : public noncopyable
00029 {
00030 friend class log_stream_out;
00031 
00032 private:
00033     typedef std::basic_ostream<char> output_stream;
00034     typedef std::basic_ostringstream<char> string_stream;
00035     typedef std::vector<string_stream*> stream_vector;
00036     stream_vector m_streams;
00037 
00038     typedef std::vector<output_stream*> free_stream_vector;
00039     free_stream_vector m_freeStreams;
00040     spin_lock<> m_streamLock;
00041 
00042     typedef std::vector<log_target*> target_vector;
00043     target_vector m_targets;
00044     shareable_spin_lock<> m_targetLock;
00045 
00047     LEAN_MAYBE_EXPORT output_stream& acquireStream();
00049     LEAN_MAYBE_EXPORT void flushAndReleaseStream(output_stream &stream);
00050 
00051 public:
00053     LEAN_MAYBE_EXPORT log(log_target *initialTarget = nullptr);
00055     LEAN_MAYBE_EXPORT ~log();
00056 
00058     LEAN_MAYBE_EXPORT void add_target(log_target *target);
00060     LEAN_MAYBE_EXPORT void remove_target(log_target *target);
00061 
00063     LEAN_MAYBE_EXPORT void print(const char_ntri &message);
00064 };
00065 
00067 class log_stream_out : public noncopyable
00068 {
00069 private:
00070     log &m_log;
00071     log::output_stream &m_stream;
00072 
00073 public:
00075     typedef log::output_stream output_stream;
00077     typedef std::basic_ostream<output_stream::char_type, output_stream::traits_type> basic_output_stream;
00079     typedef std::basic_ios<output_stream::char_type, output_stream::traits_type> basic_output_ios;
00080 
00082     explicit log_stream_out(log &log)
00083         : m_log(log),
00084         m_stream(log.acquireStream()) { }
00086     ~log_stream_out()
00087     {
00088         m_log.flushAndReleaseStream(m_stream);
00089     }
00090 
00092     template <class Value>
00093     log_stream_out& operator <<(const Value &value)
00094     {
00095         m_stream << value;
00096         return *this;
00097     }
00098     // Passes the given manipulator to this log stream.
00099     log_stream_out& operator <<(std::ios_base& (*manip)(::std::ios_base&))
00100     {
00101         m_stream << manip;
00102         return *this;
00103     }
00104     // Passes the given manipulator to this log stream.
00105     log_stream_out& operator<<(basic_output_stream& (*manip)(basic_output_stream&))
00106     {
00107         m_stream << manip;
00108         return *this;
00109     }
00110     // Passes the given manipulator to this log stream.
00111     log_stream_out& operator<<(basic_output_ios& (*manip)(basic_output_ios&))
00112     {
00113         m_stream << manip;
00114         return *this;
00115     }
00116 
00118     output_stream& std()
00119     {
00120         return m_stream;
00121     }
00122 };
00123 
00125 LEAN_MAYBE_EXPORT log& error_log();
00127 LEAN_MAYBE_EXPORT log& info_log();
00128 
00129 } // namespace
00130 
00131 using logging::log;
00132 using logging::log_stream_out;
00133 
00134 using logging::error_log;
00135 using logging::info_log;
00136 
00137 } // namespace
00138 
00142 
00144 #define LEAN_LOG(msg) ::lean::log_stream_out(::lean::info_log()) << LEAN_SOURCE_STRING << ": " << msg << ::std::endl
00145 
00146 #define LEAN_LOG_BREAK() ::lean::log_stream_out(::lean::info_log()) << ::std::endl
00147 
00149 #define LEAN_LOG_ERROR(msg) ::lean::log_stream_out(::lean::error_log()) << LEAN_SOURCE_STRING << ": " << msg << ::std::endl
00150 
00151 #define LEAN_LOG_ERROR_BREAK() ::lean::log_stream_out(::lean::error_log()) << ::std::endl
00152 
00154 
00155 #ifdef LEAN_INCLUDE_LINKED
00156 #include "source/log.cpp"
00157 #endif
00158 
00159 #endif