Back to home page

EIC code displayed by LXR

 
 

    


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

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 GAUDIALG_GAUDICOMMON_H
0012 #define GAUDIALG_GAUDICOMMON_H 1
0013 // ============================================================================
0014 // Include files
0015 // ============================================================================
0016 // from STL
0017 // ============================================================================
0018 #include <algorithm>
0019 #include <functional>
0020 #include <list>
0021 #include <map>
0022 #include <mutex>
0023 #include <string>
0024 #include <vector>
0025 // ============================================================================
0026 // GaudiKernel
0027 // ============================================================================
0028 #include "GaudiAlg/FixTESPath.h"
0029 #include "GaudiKernel/DataObjectHandle.h"
0030 #include "GaudiKernel/GaudiException.h"
0031 #include "GaudiKernel/HashMap.h"
0032 #include "GaudiKernel/IAlgContextSvc.h"
0033 #include "GaudiKernel/IAlgTool.h"
0034 #include "GaudiKernel/IAlgorithm.h"
0035 #include "GaudiKernel/IChronoStatSvc.h"
0036 #include "GaudiKernel/ICounterSummarySvc.h"
0037 #include "GaudiKernel/IDataProviderSvc.h"
0038 #include "GaudiKernel/IMessageSvc.h"
0039 #include "GaudiKernel/IToolSvc.h"
0040 #include "GaudiKernel/IUpdateManagerSvc.h"
0041 #include "GaudiKernel/SmartDataPtr.h"
0042 #include "GaudiKernel/StatEntity.h"
0043 #include "GaudiKernel/StatusCode.h"
0044 #include "GaudiKernel/System.h"
0045 
0046 // ============================================================================
0047 // forward declarations
0048 // ============================================================================
0049 namespace Gaudi {
0050   class Algorithm; // GaudiKernel
0051 }
0052 class AlgTool; // GaudiKernel
0053 class ISvcLocator;
0054 namespace Gaudi {
0055   namespace Utils {
0056     template <class TYPE>
0057     struct GetData;
0058   }
0059 } // namespace Gaudi
0060 
0061 namespace GaudiCommon_details {
0062   constexpr const struct svc_eq_t {
0063     bool operator()( std::string_view n, const SmartIF<IService>& s ) const { return n == s->name(); };
0064     bool operator()( const SmartIF<IService>& s, std::string_view n ) const { return s->name() == n; };
0065     bool operator()( const SmartIF<IService>& s, const SmartIF<IService>& n ) const { return s->name() == n->name(); };
0066   } svc_eq{};
0067   constexpr const struct svc_lt_t {
0068     bool operator()( std::string_view n, const SmartIF<IService>& s ) const { return n < s->name(); };
0069     bool operator()( const SmartIF<IService>& s, std::string_view n ) const { return s->name() < n; };
0070     bool operator()( const SmartIF<IService>& s, const SmartIF<IService>& n ) const { return s->name() < n->name(); };
0071   } svc_lt{};
0072 } // namespace GaudiCommon_details
0073 // ============================================================================
0074 /*  @file GaudiCommon.h
0075  *
0076  *  Header file for class : GaudiCommon
0077  *
0078  *  @author Chris Jones   Christopher.Rob.Jones@cern.ch
0079  *  @author Vanya BELYAEV Ivan.Belyaev@itep.ru
0080  *  @author Rob Lambert Rob.Lambert@cern.ch
0081  *  @date   2009-08-04
0082  */
0083 // ============================================================================
0084 /** @class GaudiCommon GaudiCommon.h GaudiAlg/GaudiCommon.h
0085  *
0086  *  Implements the common functionality between GaudiTools and GaudiAlgorithms
0087  *
0088  *  @author Chris Jones   Christopher.Rob.Jones@cern.ch
0089  *  @author Vanya BELYAEV Ivan.Belyaev@itep.ru
0090  *  @author Rob Lambert Rob.Lambert@cern.ch
0091  *  @date   2009-08-04
0092  */
0093 // ============================================================================
0094 template <class PBASE>
0095 class GAUDI_API GaudiCommon : public FixTESPath<PBASE> {
0096 protected: // definitions
0097   using base_class = FixTESPath<PBASE>;
0098 
0099   /** Simple definition to be used with the new useRootInTES argument get<TYPE>
0100    *  and put methods. If used with cause the RootInTES option to be IGNORED.
0101    *
0102    *  Useful to aid with code readability. e.g.
0103    *  @code
0104    *  // Get data, ignoring the setting of rootInTES()
0105    *  MyData * data = get<MyData>( "/Event/MyData", IgnoreRootInTES );
0106    *  @endcode
0107    */
0108   static const bool IgnoreRootInTES = false;
0109   /** Simple definition to be used with the new useRootInTES argument get<TYPE>
0110    *  and put methods. If used with cause the RootInTES option to be USED
0111    *
0112    *  Useful to aid with code readability. e.g.
0113    *  @code
0114    *  // Get data, using the setting of rootInTES()
0115    *  MyData * data = get<MyData>( "/Event/MyData", UseRootInTES );
0116    *  // note the default setting is true, so this is equivalent to
0117    *  MyData * data = get<MyData>( "/Event/MyData" );
0118    *  @endcode
0119    */
0120   static const bool UseRootInTES = true;
0121   // ==========================================================================
0122 protected: // few actual data types
0123   // ==========================================================================
0124   /// the actual type of general counters
0125   typedef std::map<std::string, StatEntity, std::less<>> StatisticsOwn;
0126   typedef std::map<std::string, std::reference_wrapper<Gaudi::Accumulators::PrintableCounter>, std::less<>> Statistics;
0127   /// the actual type error/warning counter
0128   typedef std::map<std::string, unsigned int, std::less<>> Counter;
0129   /// storage for active tools
0130   typedef std::vector<IAlgTool*> AlgTools;
0131   /// storage for active services
0132   typedef std::vector<SmartIF<IService>> Services;
0133 
0134   // ==========================================================================
0135   // protected members such that they can be used in the derived classes
0136   /// a pointer to the CounterSummarySvc
0137   SmartIF<ICounterSummarySvc> m_counterSummarySvc;
0138 
0139 public:
0140   // ==========================================================================
0141   /** @brief Templated access to the data in Gaudi Transient Store
0142    *
0143    *  Quick and safe access to the data in Gaudi transient store.
0144    *  The method located the data at given address and perform the
0145    *  debug printout about located data
0146    *
0147    *  @code
0148    *
0149    *  // Will access MCHits from the given location
0150    *  MCHits* hits = get<MCHits>( evtSvc () , "MC/Hits" );
0151    *
0152    *  @endcode
0153    *
0154    *  @attention The method respects the setting of the job option
0155    *             RootInTES by prepending the value of this to the
0156    *             data location that is passed.
0157    *             The default setting for RootInTES is "" so has no effect.
0158    *             This behavior can be suppressed by passing the argument
0159    *             useRootInTES = false
0160    *
0161    *  @see IDataProviderSvc
0162    *  @see SmartDataPtr
0163    *
0164    *  @exception      GaudiException for Invalid Data Provider Service
0165    *  @exception      GaudiException for invalid/unavailable data
0166    *
0167    *  @param svc      Pointer to data service (data provider)
0168    *  @param location data location/address in Gaudi Transient Store
0169    *  @param useRootInTES Flag to turn on(TRUE) off(FALSE) the use of
0170    *                      the RootInTES location property
0171    *
0172    *  @return pointer to the data object
0173    */
0174   template <class TYPE>
0175   typename Gaudi::Utils::GetData<TYPE>::return_type get( IDataProviderSvc* svc, std::string_view location,
0176                                                          const bool useRootInTES = true ) const;
0177   /** Quicker version of the get function which bypasses the check on the
0178    *  retrieved data.
0179    */
0180   template <class TYPE>
0181   typename Gaudi::Utils::GetData<TYPE>::return_type getIfExists( IDataProviderSvc* svc, std::string_view location,
0182                                                                  const bool useRootInTES = true ) const;
0183   /** @brief Check the existence of a data object or container
0184    *         in the Gaudi Transient Event Store
0185    *
0186    *  @code
0187    *
0188    *  bool a1 = exist<DataObject>( evtSvc() , "/Event/MyObject" ) ;
0189    *  bool a2 = exist<MyHits>    ( evtSvc() , "/Event/MyHits" ) ;
0190    *
0191    *  @endcode
0192    *
0193    *  @attention The method respects the setting of the job option
0194    *             RootInTES by prepending the value of this to the
0195    *             data location that is passed.
0196    *             The default setting for RootInTES is "" so has no effect.
0197    *             This behavior can be suppressed by passing the argument
0198    *             useRootInTES = false
0199    *
0200    *  @param  svc      Pointer to data provider service
0201    *  @param  location Address in Gaudi Transient Store
0202    *  @param useRootInTES Flag to turn on(TRUE) off(FALSE) the use of
0203    *                      the RootInTES location property
0204    *
0205    *  @return          Boolean indicating status of the request
0206    *  @retval true     Data object or container exists and implements a proper interface
0207    *  @retval true     Failed to locate the data object or container
0208    */
0209   template <class TYPE>
0210   bool exist( IDataProviderSvc* svc, std::string_view location, const bool useRootInTES = true ) const;
0211   /** @brief Get the existing data object from Gaudi Event Transient store.
0212    *        Alternatively, create new object and register it in TES
0213    *        and return if object does not exist.
0214    *
0215    *  @code
0216    *
0217    *  MyHits* hits = getOrCreate<MyHits,MyHits>( evtSvc() , "/Event/MyHits" ) ;
0218    *
0219    *  @endcode
0220    *
0221    *  @attention The method respects the setting of the job option
0222    *             RootInTES by prepending the value of this to the
0223    *             data location that is passed.
0224    *             The default setting for RootInTES is "" so has no effect.
0225    *             This behavior can be suppressed by passing the argument
0226    *             useRootInTES = false
0227    *
0228    *  @exception GaudiException for Invalid Data Provider Service
0229    *  @exception GaudiException for invalid/unavailable  data
0230    *
0231    *  @param  svc      Pointer to data provider service
0232    *  @param  location  Location in Gaudi Transient Event Store
0233    *  @param useRootInTES Flag to turn on(TRUE) off(FALSE) the use of
0234    *                      the RootInTES location property
0235    *
0236    *  @return A valid pointer to the data object
0237    */
0238   template <class TYPE, class TYPE2>
0239   typename Gaudi::Utils::GetData<TYPE>::return_type getOrCreate( IDataProviderSvc* svc, std::string_view location,
0240                                                                  const bool useRootInTES = true ) const;
0241   /** @brief Register a data object or container into Gaudi Event Transient Store
0242    *
0243    *  @see IDataProviderSvc
0244    *
0245    *  @attention The method respects the setting of the job option
0246    *             RootInTES by prepending the value of this to the
0247    *             data location that is passed.
0248    *             The default setting for RootInTES is "" so has no effect.
0249    *             This behavior can be suppressed by passing the argument
0250    *             useRootInTES = false
0251    *
0252    *  @param svc        Pointer to data provider service
0253    *  @param object     Data object or container to be registered
0254    *  @param location   Location in Gaudi Event Transient Store ("/Event" could be omitted )
0255    *  @param useRootInTES Flag to turn on(TRUE) off(FALSE) the use of
0256    *                      the RootInTES location property
0257    *
0258    *  @exception        GaudiException for invalid event data service
0259    *  @exception        GaudiException for invalid object
0260    *  @exception        GaudiException for error result from event data service
0261    *
0262    *  @return StatusCode
0263    *  @retval StatusCode::SUCCESS Data was successfully placed in the TES.
0264    *  @retval StatusCode::FAILURE Failed to store data in the TES.
0265    */
0266   DataObject* put( IDataProviderSvc* svc, std::unique_ptr<DataObject> object, std::string_view location,
0267                    const bool useRootInTES = true ) const;
0268   // [[deprecated( "please pass std::unique_ptr as 2nd argument" )]]
0269   DataObject* put( IDataProviderSvc* svc, DataObject* object, std::string_view location,
0270                    const bool useRootInTES = true ) const {
0271     return put( svc, std::unique_ptr<DataObject>( object ), location, useRootInTES );
0272   }
0273   /** Useful method for the easy location of tools.
0274    *
0275    *  @code
0276    *
0277    *  IMyTool* myTool =
0278    *      tool<IMyTool>( "MyToolType", "MyToolName", this );
0279    *
0280    *  @endcode
0281    *
0282    *  @attention The tools located with this method
0283    *             will be released automatically
0284    *
0285    *  @see IToolSvc
0286    *  @see IAlgTool
0287    *
0288    *  @exception GaudiException for invalid Tool Service
0289    *  @exception GaudiException for error from Tool Service
0290    *  @exception GaudiException for invalid tool
0291    *
0292    *  @param type   Tool type
0293    *  @param name   Tool name
0294    *  @param parent Tool parent
0295    *  @param create Flag for creation of nonexisting tools
0296    *  @return       A pointer to the tool
0297    */
0298   template <class TOOL>
0299   TOOL* tool( std::string_view type, std::string_view name, const IInterface* parent = 0, bool create = true ) const;
0300   /** A useful method for the easy location of tools.
0301    *
0302    *  @code
0303    *
0304    *  IMyTool* myTool = tool<IMyTool>( "PublicToolType" );
0305    *
0306    *  @endcode
0307    *
0308    *  @attention The tools located with this method
0309    *             will be released automatically
0310    *
0311    *  @see IToolSvc
0312    *  @see IAlgTool
0313    *
0314    *  @exception    GaudiException for invalid Tool Service
0315    *  @exception    GaudiException for error from Tool Service
0316    *  @exception    GaudiException for invalid tool
0317    *  @param type   Tool type, could be of "Type/Name" format
0318    *  @param parent Tool parent
0319    *  @param create Flag for creation of non-existing tools
0320    *  @return       A pointer to the tool
0321    */
0322   template <class TOOL>
0323   TOOL* tool( std::string_view type, const IInterface* parent = 0, bool create = true ) const;
0324   /** A useful method for the easy location of services
0325    *
0326    *  @code
0327    *
0328    *  IMyService* mySvc = svc<IMyService>( "MyServiceType" );
0329    *
0330    *  @endcode
0331    *
0332    *  @attention The services located with this method
0333    *             will be released automatically
0334    *
0335    *  @see IService
0336    *  @see ISevcLocator
0337    *  @see Service
0338    *
0339    *  @exception GaudiException for error in Algorithms::service
0340    *  @exception GaudiException for invalid service
0341    *
0342    *  @param name   service type name
0343    *  @param create Flag for creation of non-existing services
0344    *  @return       A pointer to the service
0345    */
0346   template <class SERVICE>
0347   SmartIF<SERVICE> svc( std::string_view name, const bool create = true ) const;
0348   /// Short-cut to locate the Update Manager Service.
0349   IUpdateManagerSvc* updMgrSvc() const;
0350 
0351 public:
0352   /** Print the error message and return with the given StatusCode.
0353    *
0354    *  Also performs statistical analysis of the error messages and
0355    *  suppression after the defined number of error instances.
0356    *
0357    *  @code
0358    *
0359    *   if( a < 0 ) { return Error("a is negative!") ;}
0360    *   if( b < 0 ) { return Error("b is illegal!" , StatusCode(25) );
0361    *   if( c < 0 )
0362    *      { return Error("c is negative" , StatusCode(35) , 50 );
0363    *
0364    *  @endcode
0365    *
0366    *  @see MsgStream
0367    *  @see IMessageSvc
0368    *  @see StatusCode
0369    *
0370    *  @param msg    Error message
0371    *  @param st     StatusCode to return
0372    *  @param mx     Maximum number of printouts for this message
0373    *  @return       StatusCode
0374    */
0375   StatusCode Error( std::string_view msg, const StatusCode st = StatusCode::FAILURE, const size_t mx = 10 ) const;
0376   /** Print the warning message and return with the given StatusCode.
0377    *
0378    *  Also performs statistical analysis of the warning messages and
0379    *  suppression after the defined number of error instances.
0380    *
0381    *  @code
0382    *
0383    *   if( a < 0 ) { return Warning("a is negative!") ;}
0384    *   if( b < 0 ) { return Warning("b is illegal!" , StatusCode(25) );
0385    *   if( c < 0 )
0386    *      { return Warning("c is negative" , StatusCode(35) , 50 );
0387    *
0388    *  @endcode
0389    *
0390    *  @see MsgStream
0391    *  @see IMessageSvc
0392    *  @see StatusCode
0393    *
0394    *  @param msg    Warning message
0395    *  @param st     StatusCode to return
0396    *  @param mx     Maximum number of printouts for this message
0397    *  @return       The given StatusCode
0398    */
0399   StatusCode Warning( std::string_view msg, const StatusCode st = StatusCode::FAILURE, const size_t mx = 10 ) const;
0400   /** Print the info message and return with the given StatusCode.
0401    *
0402    *  Also performs statistical analysis of the info messages and
0403    *  suppression after the defined number of instances.
0404    *
0405    *  @see MsgStream
0406    *  @see IMessageSvc
0407    *  @see StatusCode
0408    *  @see GaudiCommon::Warning
0409    *
0410    *  @param msg    Info message
0411    *  @param st     StatusCode to return
0412    *  @param mx     Maximum number of printouts for this message
0413    *  @return       The given StatusCode
0414    */
0415   StatusCode Info( std::string_view msg, const StatusCode st = StatusCode::SUCCESS, const size_t mx = 10 ) const;
0416   /** Print the message and return with the given StatusCode.
0417    *
0418    *  @see MsgStream
0419    *  @see IMessageSvc
0420    *  @see StatusCode
0421    *
0422    *  @param msg    Message to print
0423    *  @param st     StatusCode to return
0424    *  @param lev    Printout level for the given message
0425    *  @return       The given StatusCode
0426    */
0427   StatusCode Print( std::string_view msg, const StatusCode st = StatusCode::SUCCESS,
0428                     const MSG::Level lev = MSG::INFO ) const;
0429   /** Assertion - throw exception if the given condition is not fulfilled
0430    *
0431    *  @see GaudiException
0432    *
0433    *  @exception          Exception for invalid condition
0434    *  @param ok           Condition which should be "true"
0435    *  @param message      Message to be associated with the exception
0436    */
0437   void Assert( const bool ok, std::string_view message = "", const StatusCode sc = StatusCode::FAILURE ) const;
0438   /** Create and (re)-throw a given GaudiException
0439    *
0440    *  @see GaudiException
0441    *
0442    *  @exception    GaudiException always thrown!
0443    *  @param msg    Exception message
0444    *  @param exc    (previous) exception of type GaudiException
0445    */
0446   void Exception( std::string_view msg, const GaudiException& exc, const StatusCode sc = StatusCode::FAILURE ) const;
0447   /** Create and (re)-throw a given exception
0448    *
0449    *  @see GaudiException
0450    *
0451    *  @exception    std::exception always thrown!
0452    *  @param msg    Exception message
0453    *  @param exc    (previous) exception of type std::exception
0454    *  @param sc     StatusCode
0455    */
0456   void Exception( std::string_view msg, const std::exception& exc, const StatusCode sc = StatusCode::FAILURE ) const;
0457   /** Create and throw an exception with the given message
0458    *
0459    *  @see GaudiException
0460    *
0461    *  @exception    GaudiException always thrown!
0462    *  @param msg    Exception message
0463    *  @param sc     StatusCode
0464    */
0465   void Exception( std::string_view msg = "no message", const StatusCode sc = StatusCode::FAILURE ) const;
0466 
0467 private:
0468   /// accessor to all owned counters
0469   StatisticsOwn countersOwn() const { return m_countersOwn; }
0470 
0471 public:
0472   /** accessor to certain counter by name
0473    *
0474    *  @code
0475    *
0476    *  if ( OK ) { ++counter("OK") ; }
0477    *
0478    *  // additive counter ('Flag')
0479    *  counter("#Tracks") += tracks->size() ;
0480    *
0481    *  // multiplicative counter  ('Weight')
0482    *  counter("ProbTot") *= probability ;
0483    *
0484    *  @endcode
0485    *
0486    *  @see StatEntuty
0487    *  @param tag counter name
0488    *  @return the counter itself
0489    */
0490   //[[deprecated( "see LHCBPS-1758" )]], on top no garantee about thread safety
0491   StatEntity& counter( std::string_view tag ) const { return const_cast<GaudiCommon<PBASE>*>( this )->counter( tag ); }
0492   StatEntity& counter( std::string_view tag ) {
0493     auto lock = std::scoped_lock{ m_countersOwnMutex };
0494     // Return referenced StatEntity if it already exists, else create it
0495     auto p = m_countersOwn.find( tag );
0496     if ( p == m_countersOwn.end() ) {
0497       auto [iter, b] = m_countersOwn.try_emplace( std::string{ tag } );
0498       assert( b );
0499       this->serviceLocator()->monitoringHub().registerEntity( this->name(), iter->first, StatEntity::typeString,
0500                                                               iter->second );
0501       p = iter;
0502     }
0503     return p->second;
0504   }
0505   // ==========================================================================
0506 public:
0507   /** perform the actual printout of error counters
0508    *  @param  level The message level to print at
0509    *  @return number of error counters
0510    */
0511   long printErrors( const MSG::Level level = MSG::ALWAYS ) const;
0512   /** perform the actual printout of properties
0513    *  @param  level The message level to print at
0514    *  @return number of properties
0515    */
0516   long printProps( const MSG::Level level = MSG::ALWAYS ) const;
0517   /** register the current instance to the UpdateManagerSvc as a consumer for a condition.
0518    *  @param condition  the path inside the Transient Detector Store to the condition object.
0519    *  @param mf         optional pointer to the member function to call when the condition object
0520    *                    is updated. If the pointer is omitted the user must explicitly provide
0521    *                    the class name to the method.
0522    *  @code
0523    *  StatusCode MyAlg::initialize(){
0524    *     // ...
0525    *     registerCondition("/dd/Conditions/Readout/MyDet/MyCond",&MyAlg::i_CallBack);
0526    *     registerCondition<MyAlg>("/dd/Conditions/Readout/MyDet/MyOtherCond");
0527    *     // ...
0528    *     return StatusCode.SUCCESS;
0529    *  }
0530    *  @endcode
0531    */
0532   template <class CallerClass>
0533   void registerCondition( const std::string& condition, StatusCode ( CallerClass::*mf )() = nullptr ) {
0534     updMgrSvc()->registerCondition( dynamic_cast<CallerClass*>( this ), condition, mf );
0535   }
0536   /** register the current instance to the UpdateManagerSvc as a consumer for a condition.
0537    *  This version of the method allow the user to specify where to put a copy of the pointer
0538    *  to the condition object.
0539    *  @param condition    the path inside the Transient Detector Store to the condition object.
0540    *  @param condPtrDest  pointer to fill with the location of the condition object.
0541    *                      Note: the pointer can be safely used only in the execute method or in the
0542    *                      member function triggered by the update.
0543    *  @param mf           optional pointer to the member function to call when the condition object
0544    *                      is updated. If the pointer is omitted the user must explicitly provide
0545    *                      the class name to the method.
0546    *  @code
0547    *  class MyAlg: public GaudiAlgorithm {
0548    *     // ...
0549    *  public:
0550    *     virtual StatusCode i_CallBack();
0551    *  private:
0552    *     Condition *m_MyCond;
0553    *     SpecialCondition *m_MyOtherCond;
0554    *     // ...
0555    *  };
0556    *
0557    *  StatusCode MyAlg::initialize(){
0558    *     // ...
0559    *     registerCondition("/dd/Conditions/Readout/MyDet/MyCond",m_MyCond,&MyAlg::i_CallBack);
0560    *     registerCondition<MyAlg>("/dd/Conditions/Readout/MyDet/MyOtherCond",m_MyOtherCond);
0561    *     // ...
0562    *     return StatusCode.SUCCESS;
0563    *  }
0564    *  @endcode
0565    */
0566   template <class CallerClass, class CondType>
0567   void registerCondition( const std::string& condition, CondType*& condPtrDest,
0568                           StatusCode ( CallerClass::*mf )() = NULL ) {
0569     updMgrSvc()->registerCondition( dynamic_cast<CallerClass*>( this ), condition, mf, condPtrDest );
0570   }
0571   /// just to avoid conflicts with the version using a pointer to a template class.
0572   template <class CallerClass>
0573   void registerCondition( char* condition, StatusCode ( CallerClass::*mf )() = NULL ) {
0574     updMgrSvc()->registerCondition( dynamic_cast<CallerClass*>( this ), std::string( condition ), mf );
0575   }
0576   /** register the current instance to the UpdateManagerSvc as a consumer for a condition.
0577    *  @param condition  the path inside the Transient Detector Store to the condition object.
0578    *  @param mf         optional pointer to the member function to call when the condition object
0579    *                    is updated. If the pointer is omitted the user must explicitly provide
0580    *                    the class name to the method.
0581    *  @code
0582    *  StatusCode MyAlg::initialize(){
0583    *     // ...
0584    *     registerCondition("/dd/Conditions/Readout/MyDet/MyCond",&MyAlg::i_CallBack);
0585    *     registerCondition<MyAlg>("/dd/Conditions/Readout/MyDet/MyOtherCond");
0586    *     // ...
0587    *     return StatusCode.SUCCESS;
0588    *  }
0589    *  @endcode
0590    */
0591   template <class CallerClass, class TargetClass>
0592   void registerCondition( TargetClass* condition, StatusCode ( CallerClass::*mf )() = NULL ) {
0593     updMgrSvc()->registerCondition( dynamic_cast<CallerClass*>( this ), condition, mf );
0594   }
0595   /** asks the UpdateManagerSvc to perform an update of the instance (if needed) without waiting the
0596    *  next BeginEvent incident.
0597    *  It is useful if the instance can be instantiated after a BeginEvent incident, and used before
0598    *  the next one (for example with tools).
0599    *  @code
0600    *  StatusCode MyTool::initialize(){
0601    *    // ...
0602    *    return runUpdate();
0603    *  }
0604    *  @endcode
0605    */
0606   StatusCode runUpdate() { return updMgrSvc()->update( this ); }
0607 
0608 public:
0609   /// Algorithm constructor - the SFINAE constraint below ensures that this is
0610   /// constructor is only defined if PBASE derives from Algorithm
0611   template <typename U = PBASE, typename = std::enable_if_t<std::is_base_of_v<Gaudi::Algorithm, PBASE>, U>>
0612   GaudiCommon( std::string name, ISvcLocator* pSvcLocator ) : base_class( std::move( name ), pSvcLocator ) {
0613     initGaudiCommonConstructor();
0614   }
0615   /// Tool constructor - SFINAE-ed to insure this constructor is only defined
0616   /// if PBASE derives from AlgTool.
0617   template <typename U = PBASE, typename = std::enable_if_t<std::is_base_of_v<AlgTool, PBASE>, U>>
0618   GaudiCommon( std::string type, std::string name, const IInterface* ancestor )
0619       : base_class( std::move( type ), std::move( name ), ancestor ) {
0620     initGaudiCommonConstructor( this->parent() );
0621   }
0622 
0623 public:
0624   /** standard initialization method
0625    *  @return status code
0626    */
0627   StatusCode initialize() override;
0628   /** standard finalization method
0629    *  @return status code
0630    */
0631   StatusCode finalize() override;
0632 
0633   GaudiCommon()                                = delete;
0634   GaudiCommon( const GaudiCommon& )            = delete;
0635   GaudiCommon& operator=( const GaudiCommon& ) = delete;
0636 
0637 protected:
0638   /// manual forced (and 'safe') release of the tool
0639   StatusCode releaseTool( const IAlgTool* tool ) const;
0640   /// manual forced (and 'safe') release of the service
0641   StatusCode releaseSvc( const IInterface* svc ) const;
0642 
0643 public:
0644   /** Manual forced (and 'safe') release of the active tool or service
0645    *
0646    *  @code
0647    *
0648    *  IMyTool* mytool = tool<IMyTool>( .... ) ;
0649    *  mytool->spendCPUtime() ;
0650    *  release ( mytool ) ;
0651    *
0652    *  IMySvc* msvc = svc<IMySvc>( .... ) ;
0653    *  msvc->spendCPUtime() ;
0654    *  release ( msvc ) ;
0655    *
0656    *  @endcode
0657    *
0658    *  @param interface  Interface pointer to the interface to be released
0659    *  @return           StatusCode
0660    *  @retval           StatusCode::SUCCESS Tool or service was successfully released
0661    *  @retval           StatusCode::FAILURE Error releasing too or service
0662    */
0663   StatusCode release( const IInterface* interface ) const;
0664 
0665   /// Un-hide IInterface::release (ICC warning #1125)
0666   using PBASE::release;
0667   // ==========================================================================
0668 public:
0669   // ==========================================================================
0670   /// get the list of aquired services
0671   const Services& services() const { return m_services; } // get all services
0672   // ==========================================================================
0673 public:
0674   // ==========================================================================
0675   /// Returns the "context" string. Used to identify different processing states.
0676   const std::string& context() const { return m_context; }
0677 
0678 private:
0679   // ==========================================================================
0680   /// Add the given service to the list of acquired services
0681   void addToServiceList( SmartIF<IService> svc ) const;
0682   /// Constructor initializations
0683   void initGaudiCommonConstructor( const IInterface* parent = nullptr );
0684   // ==========================================================================
0685 private:
0686   /// List of active  tools
0687   mutable AlgTools m_managedTools;
0688   /// List of active  services
0689   mutable Services m_services;
0690   // ==========================================================================
0691   static auto increment( Counter& c, std::string_view which ) {
0692     auto i = c.find( which );
0693     return i != c.end() ? ++( i->second ) : c.emplace( which, 1 ).first->second;
0694   }
0695   /// Counter of errors
0696   mutable Counter m_errors;
0697   /// counter of warnings
0698   mutable Counter m_warnings;
0699   /// counter of infos
0700   mutable Counter m_infos;
0701   /// Counter of exceptions
0702   mutable Counter m_exceptions;
0703   /// General counters
0704   StatisticsOwn m_countersOwn;
0705   /// The mutex for m_countersOwn
0706   std::mutex m_countersOwnMutex;
0707   // ==========================================================================
0708   /// Pointer to the Update Manager Service instance
0709   mutable IUpdateManagerSvc* m_updMgrSvc = nullptr;
0710 
0711 protected:
0712   // ==========================================================================
0713   // Properties
0714   Gaudi::Property<bool> m_errorsPrint{ this, "ErrorsPrint", true,
0715                                        [this]( auto& ) {
0716                                          // no action if not yet initialized
0717                                          if ( this->FSMState() >= Gaudi::StateMachine::INITIALIZED &&
0718                                               this->m_errorsPrint.value() ) {
0719                                            this->printErrors();
0720                                          }
0721                                        },
0722                                        "print the statistics of errors/warnings/exceptions" };
0723   Gaudi::Property<bool> m_propsPrint{ this, "PropertiesPrint", false,
0724                                       [this]( auto& ) {
0725                                         // no action if not yet initialized
0726                                         if ( this->FSMState() >= Gaudi::StateMachine::INITIALIZED &&
0727                                              this->m_propsPrint.value() ) {
0728                                           this->printProps( MSG::ALWAYS );
0729                                         }
0730                                       },
0731                                       "print the properties of the component" };
0732   Gaudi::Property<bool> m_typePrint{ this, "TypePrint", true, "add the actual C++ component type into the messages" };
0733 
0734   Gaudi::Property<std::string>              m_context{ this, "Context", {}, "note: overridden by parent settings" };
0735   Gaudi::Property<std::vector<std::string>> m_counterList{
0736       this, "CounterList", { ".*" }, "RegEx list, of simple integer counters for CounterSummary" };
0737 };
0738 // ============================================================================
0739 #include "GaudiAlg/GaudiCommonImp.h"
0740 // ============================================================================
0741 
0742 // ============================================================================
0743 // The END
0744 // ============================================================================
0745 #endif // GAUDIALG_GAUDICOMMON_H