Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:41

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2021 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIKERNEL_MSGSTREAM_H
0012 #define GAUDIKERNEL_MSGSTREAM_H
0013 
0014 // Include files
0015 #include "GaudiKernel/IMessageSvc.h"
0016 #include "GaudiKernel/SerializeSTL.h"
0017 // Standard C++ classes
0018 #include <cstdio>
0019 #include <iomanip>
0020 #include <sstream>
0021 #include <string>
0022 #include <vector>
0023 
0024 /**
0025  * @class MsgStream MsgStream.h GaudiKernel/MsgStream.h
0026  *
0027  * Definition of the MsgStream class used to transmit messages.
0028  * This class is intended to ease the use of error logging to the message
0029  * service
0030  *
0031  * @author M.Frank
0032  * @author Sebastien Ponce
0033  */
0034 class MsgStream {
0035 private:
0036   /** Error return code in case ios modification is requested for inactive
0037    *  streams
0038    */
0039   typedef std::ios_base::fmtflags FLAG_TYPE;
0040   typedef std::ios_base::iostate  STATE_TYPE;
0041 
0042 protected:
0043   /// Pointer to message service if buffer has send
0044   IMessageSvc* m_service;
0045   /// Use standard string for information buffering
0046   std::string m_buffer;
0047   /// Use std::string for source information to be passed to the message service
0048   std::string m_source;
0049   /// String MsgStream associated to buffer
0050   std::ostringstream m_stream;
0051   /// Flag set to true if formatting engine is active
0052   bool m_active = false;
0053   /// Debug level of the message service
0054   MSG::Level m_level;
0055   /// Current debug level
0056   MSG::Level m_currLevel;
0057   /// use colors
0058   bool m_useColors;
0059   /// Pointer to service counting messages prepared but not printed because of
0060   /// wrong level.
0061   IInactiveMessageCounter* m_inactCounter = nullptr;
0062   /// Flag to state if the inactive messages has to be counted.
0063   static bool m_countInactive;
0064 
0065 public:
0066   /// Standard constructor: Connect to message service for output
0067   GAUDI_API MsgStream( IMessageSvc* svc, int buffer_length = 128 );
0068   /// Standard constructor: Connect to message service for output
0069   GAUDI_API MsgStream( IMessageSvc* svc, std::string source, int buffer_length = 128 );
0070   /// Copy constructor
0071   MsgStream( const MsgStream& msg )
0072       : m_service( msg.m_service )
0073       , m_active( msg.m_active )
0074       , m_level( msg.m_level )
0075       , m_currLevel( msg.m_currLevel )
0076       , m_useColors( msg.m_useColors )
0077       , m_inactCounter( msg.m_inactCounter ) {
0078     try { // ignore exception if we cannot copy the string
0079       m_source = msg.m_source;
0080     } catch ( ... ) {}
0081   }
0082   /// Standard destructor
0083   GAUDI_API virtual ~MsgStream() = default;
0084   /// Initialize report of new message: activate if print level is sufficient.
0085   MsgStream& report( int lvl ) {
0086     lvl = ( lvl >= MSG::NUM_LEVELS ) ? MSG::ALWAYS : ( lvl < MSG::NIL ) ? MSG::NIL : lvl;
0087     if ( ( m_currLevel = MSG::Level( lvl ) ) >= level() ) {
0088       activate();
0089     } else {
0090       deactivate();
0091 #ifndef NDEBUG
0092       if ( MsgStream::countInactive() && m_inactCounter ) {
0093         m_inactCounter->incrInactiveCount( MSG::Level( lvl ), m_source );
0094       }
0095 #endif
0096     }
0097     return *this;
0098   }
0099   /// Output method
0100   virtual GAUDI_API MsgStream& doOutput();
0101   /// Access string buffer
0102   const std::string& buffer() const { return m_buffer; }
0103   /// Access string MsgStream
0104   std::ostringstream& stream() { return m_stream; }
0105   /// Update @c IMessageSvc pointer
0106   void setMsgSvc( IMessageSvc* svc ) { m_service = svc; }
0107   /// Update outputlevel
0108   void setLevel( int level ) {
0109     level   = ( level >= MSG::NUM_LEVELS ) ? MSG::ALWAYS : ( level < MSG::NIL ) ? MSG::NIL : level;
0110     m_level = MSG::Level( level );
0111   }
0112   /// Retrieve output level
0113   MSG::Level level() const { return m_level; }
0114   /// Retrieve current stream output level
0115   MSG::Level currentLevel() const { return m_currLevel; }
0116   /// Activate MsgStream
0117   void activate() { m_active = true; }
0118   /// Deactivate MsgStream
0119   void deactivate() { m_active = false; }
0120   /// Accessor: is MsgStream active
0121   bool isActive() const { return m_active; }
0122   // oMsgStream flush emulation
0123   MsgStream& flush() {
0124     if ( isActive() ) m_stream.flush();
0125     return *this;
0126   }
0127   // oMsgStream write emulation
0128   MsgStream& write( const char* buff, int len ) {
0129     if ( isActive() ) m_stream.write( buff, len );
0130     return *this;
0131   }
0132   /// Accept MsgStream modifiers
0133   MsgStream& operator<<( MsgStream& ( *_f )(MsgStream&)) {
0134     if ( isActive() ) _f( *this );
0135     return *this;
0136   }
0137   /// Accept oMsgStream modifiers
0138   MsgStream& operator<<( std::ostream& ( *_f )(std::ostream&)) {
0139     if ( isActive() ) _f( m_stream );
0140     return *this;
0141   }
0142   /// Accept ios modifiers
0143   MsgStream& operator<<( std::ios& ( *_f )(std::ios&)) {
0144     if ( isActive() ) _f( m_stream );
0145     return *this;
0146   }
0147   /// Accept MsgStream activation using MsgStreamer operator
0148   MsgStream& operator<<( MSG::Level level ) { return report( level ); }
0149   MsgStream& operator<<( long long arg ) {
0150     try {
0151       // this may throw, and we cannot afford it if the stream is used in a catch block
0152       if ( isActive() ) { m_stream << arg; }
0153     } catch ( ... ) {}
0154     return *this;
0155   }
0156 
0157   /// Accept ios base class modifiers
0158   MsgStream& operator<<( std::ios_base& ( *_f )(std::ios_base&)) {
0159     if ( isActive() ) _f( m_stream );
0160     return *this;
0161   }
0162 
0163   /// IOS emulation
0164   std::streamsize width() const { return isActive() ? m_stream.width() : 0; }
0165   std::streamsize width( std::streamsize v ) { return isActive() ? m_stream.width( v ) : 0; }
0166   std::streamsize precision() const { return isActive() ? m_stream.precision() : 0; }
0167   std::streamsize precision( int v ) { return isActive() ? m_stream.precision( v ) : 0; }
0168 
0169   long flags() const { return isActive() ? m_stream.flags() : 0; }
0170   long flags( FLAG_TYPE v ) { return isActive() ? m_stream.flags( v ) : 0; }
0171   long setf( FLAG_TYPE v ) { return isActive() ? m_stream.setf( v ) : 0; }
0172   char fill() const { return isActive() ? m_stream.fill() : (char)-1; }
0173   char fill( char v ) { return isActive() ? m_stream.fill( v ) : (char)-1; }
0174   int  rdstate() const { return isActive() ? m_stream.rdstate() : std::ios_base::failbit; }
0175   bool good() const { return isActive() && m_stream.good(); }
0176   bool eof() const { return isActive() && m_stream.eof(); }
0177   bool bad() const { return isActive() && m_stream.bad(); }
0178   int  setf( FLAG_TYPE _f, FLAG_TYPE _m ) { return isActive() ? m_stream.setf( _f, _m ) : 0; }
0179   void unsetf( FLAG_TYPE _l ) {
0180     if ( isActive() ) m_stream.unsetf( _l );
0181   }
0182   void clear( STATE_TYPE _i = std::ios_base::failbit ) {
0183     if ( isActive() ) m_stream.clear( _i );
0184   }
0185 
0186   /// Set the text color
0187   GAUDI_API void setColor( MSG::Color col );
0188   /// Set the foreground and background colors
0189   GAUDI_API void setColor( MSG::Color fg, MSG::Color bg );
0190 
0191   /// Reset the colors to defaults
0192   GAUDI_API void resetColor();
0193 
0194   /// Enable/disable the count of inactive messages.
0195   /// Returns the previous state.
0196   static GAUDI_API bool enableCountInactive( bool value = true );
0197 
0198   /// Returns the state of the counting of inactive messages (enabled/disabled).
0199   static GAUDI_API bool countInactive();
0200 };
0201 
0202 /// MsgStream Modifier: endmsg. Calls the output method of the MsgStream
0203 inline MsgStream& endmsg( MsgStream& s ) { return s.doOutput(); }
0204 
0205 /// MsgStream format utility "a la sprintf(...)"
0206 GAUDI_API std::string format( const char*, ... );
0207 
0208 #ifdef _WIN32
0209 template <class _E>
0210 inline MsgStream& operator<<( MsgStream& s, const std::_Fillobj<_E>& obj ) {
0211 #  if _MSC_VER > 1300
0212   if ( s.isActive() ) s.stream().fill( obj._Fill );
0213 #  else
0214   if ( s.isActive() ) s.stream().fill( obj._Ch );
0215 #  endif
0216   return s;
0217 }
0218 template <class _Tm>
0219 inline MsgStream& operator<<( MsgStream& s, const std::_Smanip<_Tm>& manip ) {
0220 #  if _MSC_VER > 1300
0221   if ( s.isActive() ) ( *manip._Pfun )( s.stream(), manip._Manarg );
0222 #  else
0223   if ( s.isActive() ) ( *manip._Pf )( s.stream(), manip._Manarg );
0224 #  endif
0225   return s;
0226 }
0227 #elif defined( __GNUC__ )
0228 #  ifndef __APPLE__
0229 inline MsgStream& operator<<( MsgStream& s, const std::_Setiosflags& manip ) {
0230   try {
0231     // this may throw, and we cannot afford it if the stream is used in a catch block
0232     if ( s.isActive() ) s.stream() << manip;
0233   } catch ( ... ) {}
0234   return s;
0235 }
0236 inline MsgStream& operator<<( MsgStream& s, const std::_Resetiosflags& manip ) {
0237   try {
0238     // this may throw, and we cannot afford it if the stream is used in a catch block
0239     if ( s.isActive() ) s.stream() << manip;
0240   } catch ( ... ) {}
0241   return s;
0242 }
0243 inline MsgStream& operator<<( MsgStream& s, const std::_Setbase& manip ) {
0244   try {
0245     // this may throw, and we cannot afford it if the stream is used in a catch block
0246     if ( s.isActive() ) s.stream() << manip;
0247   } catch ( ... ) {}
0248   return s;
0249 }
0250 inline MsgStream& operator<<( MsgStream& s, const std::_Setprecision& manip ) {
0251   try {
0252     // this may throw, and we cannot afford it if the stream is used in a catch block
0253     if ( s.isActive() ) s.stream() << manip;
0254   } catch ( ... ) {}
0255   return s;
0256 }
0257 inline MsgStream& operator<<( MsgStream& s, const std::_Setw& manip ) {
0258   try {
0259     // this may throw, and we cannot afford it if the stream is used in a catch block
0260     if ( s.isActive() ) s.stream() << manip;
0261   } catch ( ... ) {}
0262   return s;
0263 }
0264 #  endif // not __APPLE__
0265 #else    // GCC, version << 3
0266 /// I/O Manipulator for setfill
0267 template <class _Tm>
0268 inline MsgStream& operator<<( MsgStream& s, const std::smanip<_Tm>& manip ) {
0269   try {
0270     // this may throw, and we cannot afford it if the stream is used in a catch block
0271     if ( s.isActive() ) s.stream() << manip;
0272   } catch ( ... ) {}
0273   return s;
0274 }
0275 #endif   // WIN32 or (__GNUC__)
0276 
0277 namespace MSG {
0278   inline MsgStream& dec( MsgStream& log ) {
0279     log << std::dec;
0280     return log;
0281   }
0282   inline MsgStream& hex( MsgStream& log ) {
0283     log << std::hex;
0284     return log;
0285   }
0286 } // namespace MSG
0287 
0288 /// Specialization to avoid the generation of implementations for char[].
0289 /// \see {<a href="https://savannah.cern.ch/bugs/?87340">bug #87340</a>}
0290 inline MsgStream& operator<<( MsgStream& s, const char* arg ) {
0291   try {
0292     // this may throw, and we cannot afford it if the stream is used in a catch block
0293     if ( s.isActive() ) s.stream() << arg;
0294   } catch ( ... ) {}
0295   return s;
0296 }
0297 
0298 /// General templated stream operator
0299 template <typename T>
0300 MsgStream& operator<<( MsgStream& lhs, const T& arg ) {
0301   using namespace GaudiUtils;
0302   if ( lhs.isActive() ) try {
0303       // this may throw, and we cannot afford it if the stream is used in a catch block
0304       lhs.stream() << arg;
0305     } catch ( ... ) {}
0306   return lhs;
0307 }
0308 
0309 #if defined( __GNUC__ ) and not defined( __APPLE__ )
0310 /// compiler is stupid. Must specialize
0311 template <typename T>
0312 MsgStream& operator<<( MsgStream& lhs, const std::_Setfill<T>& manip ) {
0313   if ( lhs.isActive() ) try {
0314       // this may throw, and we cannot afford it if the stream is used in a catch block
0315       lhs.stream() << manip;
0316     } catch ( ... ) {}
0317   return lhs;
0318 }
0319 #endif
0320 
0321 #endif // GAUDIKERNEL_MSGSTREAM_H