#ifndef __TOTILOG_H__ #define __TOTILOG_H__ #include #include #include #include #include #include #include "mars_util.h" namespace mars { enum LogSettings { Log_File = 1 << 0, Log_Function = 1 << 1, Log_Line = 1 << 2, Log_Time = 1 << 3, Log_Thread = 1 << 4 }; class Outputter { private: std::ofstream * _pOut; mutable boost::mutex * _pMutex; template< typename CTR > inline Outputter & writeContainer (const CTR & ctr) { if (_pOut != NULL) { *_pOut << "["; for (typename CTR::const_iterator i = ctr.begin(); i != ctr.end(); ++i) { if (i != ctr.begin()) *_pOut << ", "; *this << *i; } *_pOut << "]"; } return *this; } public: Outputter (); Outputter (std::ofstream * pOut, const unsigned int enSettings, boost::mutex * pMutex, const time_t & tTime, const char * szFile, const unsigned int nLine, const char * szFunction, const boost::thread::id & idThread); ~Outputter(); template< typename T > inline Outputter & operator << (const T & nVal) { if (_pOut != NULL) *_pOut << nVal; return *this; } template< typename T > inline Outputter & operator << (const BBox< T > & bbox) { if (_pOut != NULL) *_pOut << typeid(BBox< T >).name() << "[left=" << bbox.left << ", top=" << bbox.top << ", right=" << bbox.right << ", bottom=" << bbox.bottom << "]"; return *this; } template< typename T > inline Outputter & operator << (const Range< T > & rng) { if (_pOut != NULL) { *_pOut << typeid(Range< T >).name() << '[' << rng.minimum << " <= x <= " << rng.maximum << ']'; } return *this; } template< typename T > inline Outputter & operator << (const RangeX< T > & rng) { if (_pOut != NULL) { *_pOut << typeid(Range< T >).name() << '[' << rng.minimum << " <= x <= " << rng.maximum; if (rng.step != (std::numeric_limits::epsilon() == 0 ? 1 : std::numeric_limits::epsilon())) *_pOut << ", step=" << rng.step; *_pOut << ']'; } return *this; } template< typename T > inline Outputter & operator << (const T * ptr) { if (_pOut != NULL) *_pOut << typeid(T *).name() << "=0x" << std::setw(4) << std::setfill('0') << std::ios::hex << ptr; return *this; } inline Outputter & operator << (const std::string & str) { if (_pOut != NULL) *_pOut << str; return *this; } inline Outputter & operator << (const char * sz) { if (_pOut != NULL) *_pOut << sz; return *this; } template< typename A, typename B > inline Outputter & operator << (const std::pair< A, B > & pair) { if (_pOut != NULL) *_pOut << '(' << pair.first << ", " << pair.second << ')'; return *this; } template< typename V > inline Outputter & operator << (const std::set< V > & sett) { return writeContainer(sett); } template< typename V > inline Outputter & operator << (const std::vector< V > & vec) { return writeContainer(vec); } template< typename K, typename V > inline Outputter & operator << (const std::map< K, V > & map) { if (_pOut != NULL) { *_pOut << "["; for (typename std::map< K, V >::const_iterator i = map.begin(); i != map.end(); ++i) { if (i != map.begin()) *_pOut << ", "; *this << i->first << " -> " << i->second; } *_pOut << "]"; } return *this; } }; class Log { public: enum Level { Info = 0, Warn = 1, Fatal = 2, Debug = 3 }; #ifndef MARS_LOGLEVEL #define MARS_LOGLEVEL Fatal #endif Log (const std::string & sFilename = "mars.log", const Level enLevel = MARS_LOGLEVEL, const unsigned int enSettings = Log_Function | Log_Time); Outputter stream (const Level enLevel = Info, const char * szFile = NULL, const char * szFunction = NULL, const unsigned int nLine = 0); static Log & getSingleton (); inline void setLevel (const Level enLevel) { _enLevel = enLevel; } inline Level getLevel () const { return _enLevel; } inline void setSettings (const unsigned int enSettings) { _enSettings = enSettings; } inline unsigned int getSettings () const { return _enSettings; } inline void toggleSetting (const LogSettings enSetting) { _enSettings ^= enSetting; } inline void addSettings (const unsigned int enSettings) { _enSettings |= enSettings; } inline void removeSettings (const unsigned int enSettings) { _enSettings &= ~enSettings; } ~Log(); private: std::ofstream _outfile; boost::mutex _mutex; unsigned int _enSettings; Level _enLevel; const time_t _tTimeStart; }; extern Log g_log; } #define LOG(l) mars::g_log.stream(l, __FILE__, __FUNCTION__, __LINE__) #define LOGN LOG(mars::Log::Info) #define LOGD LOG(mars::Log::Debug) #endif