Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/GaudiKernel/ServiceHandle.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2025 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_SERVICEHANDLE_H
0012 #define GAUDIKERNEL_SERVICEHANDLE_H
0013 
0014 // Includes
0015 #include <Gaudi/Concepts.h>
0016 #include <GaudiKernel/Bootstrap.h>
0017 #include <GaudiKernel/GaudiException.h>
0018 #include <GaudiKernel/GaudiHandle.h>
0019 #include <GaudiKernel/IMessageSvc.h>
0020 #include <GaudiKernel/IProperty.h>
0021 #include <GaudiKernel/ISvcLocator.h>
0022 #include <GaudiKernel/MsgStream.h>
0023 #include <GaudiKernel/ServiceLocatorHelper.h>
0024 
0025 #include <stdexcept>
0026 #include <string>
0027 #include <type_traits>
0028 
0029 // class predeclarations
0030 class IAlgTool;
0031 class IToolSvc;
0032 class ServiceHandleProperty;
0033 
0034 /** @class ServiceHandle ServiceHandle.h GaudiKernel/ServiceHandle.h
0035 
0036     Handle to be used in lieu of naked pointers to services. This allows
0037     better control through the framework of service loading and usage.
0038 
0039     @author Martin.Woudstra@cern.ch
0040 */
0041 template <class T>
0042 class ServiceHandle : public GaudiHandle<T> {
0043 public:
0044   //
0045   // Constructors etc.
0046   //
0047   /** Create a handle ('smart pointer') to a service.
0048       The arguments are passed on to ServiceSvc, and have the same meaning:
0049       @param serviceName name of the service
0050       @param parentName name of the parent Algorithm, AlgTool or Service.
0051              It is used for log printout at retrieve(), and for retrieving
0052              a thread-dependent service (if applicable)
0053   */
0054   ServiceHandle( const std::string& serviceName, const std::string& theParentName )
0055       : GaudiHandle<T>( serviceName, "Service", theParentName ) {}
0056 
0057   /** Copy constructor from a non const T to const T service handle */
0058   template <typename CT = T, typename NCT = std::remove_const_t<T>>
0059     requires( std::is_const_v<CT> && !std::is_same_v<CT, NCT> )
0060   ServiceHandle( const ServiceHandle<NCT>& other ) : GaudiHandle<CT>( other ) {}
0061 
0062   /// Autodeclaring constructor with property name, service type/name and documentation.
0063   /// @note the use of requires is required to avoid ambiguities
0064   template <std::derived_from<IProperty> OWNER>
0065   inline ServiceHandle( OWNER* owner, std::string PropName, const std::string& svcName, std::string doc = "" )
0066       : ServiceHandle( svcName, owner->name() ) {
0067     auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( PropName ), *this, std::move( doc ) );
0068     p->template setOwnerType<OWNER>();
0069   }
0070 
0071   StatusCode initialize( const std::string& serviceName, const std::string& theParentName ) {
0072 
0073     GaudiHandleBase::setTypeAndName( serviceName );
0074     GaudiHandleBase::setParentName( theParentName );
0075 
0076     return StatusCode::SUCCESS;
0077   }
0078 
0079   /** Retrieve the Service. Release existing Service if needed.
0080       Function must be repeated here to avoid hiding the function retrieve( T*& ) */
0081   using GaudiHandle<T>::retrieve;
0082 
0083   //  /** Release the Service.
0084   //    Function must be repeated here to avoid hiding the function release( T*& ) */
0085   //   StatusCode release() const { // not really const, because it updates m_pObject
0086   //     return GaudiHandle<T>::release();
0087   //   }
0088 
0089   /// Allow non const access to the service, even from a const handle...
0090   T* get() const { return ::details::nonConst( GaudiHandle<T>::get() ); }
0091 
0092   /// Allow non const access to the service, even from a const handle...
0093   T* operator->() const { return ::details::nonConst( GaudiHandle<T>::operator->() ); }
0094   T& operator*() const { return *::details::nonConst( GaudiHandle<T>::operator->() ); }
0095 
0096 protected:
0097   /** Do the real retrieval of the Service. */
0098   StatusCode retrieve( T*& service ) const override { return i_retrieve( service ); }
0099 
0100   /// retrieve the service for ServiceHandles<ISomeInterfaces>
0101   template <Gaudi::IsInterface I = T>
0102   StatusCode i_retrieve( I*& service ) const {
0103     const ServiceLocatorHelper helper( *serviceLocator(), GaudiHandleBase::messageName(), this->parentName() );
0104     return helper.getService( GaudiHandleBase::typeAndName(), true, I::interfaceID(), (void**)&service );
0105   }
0106 
0107   /// retrieve the service for ServiceHandles<ActualService>
0108   template <typename I = T>
0109     requires( !Gaudi::IsInterface<I> )
0110   StatusCode i_retrieve( I*& service ) const {
0111     IService* svc = nullptr;
0112     return i_retrieve( svc ).andThen( [&] {
0113       service = dynamic_cast<I*>( svc );
0114       if ( !service )
0115         throw GaudiException( "unable to dcast Service " + this->typeAndName() + " to " +
0116                                   System::typeinfoName( typeid( T ) ),
0117                               this->typeAndName() + " retrieve", StatusCode::FAILURE );
0118     } );
0119   }
0120 
0121   //   /** Do the real release of the Service */
0122   //   virtual StatusCode release( T* service ) const {
0123   //     return service->release();
0124   //   }
0125 
0126 private:
0127   //
0128   // Private helper functions
0129   //
0130   SmartIF<ISvcLocator>& serviceLocator() const { // not really const, because it may change m_pSvcLocator
0131     if ( !m_pSvcLocator ) {
0132       m_pSvcLocator = Gaudi::svcLocator();
0133       if ( !m_pSvcLocator ) {
0134         throw GaudiException( "SvcLocator not found", "Core component not found", StatusCode::FAILURE );
0135       }
0136     }
0137     return m_pSvcLocator;
0138   }
0139 
0140   SmartIF<IMessageSvc>& messageSvc() const { // not really const, because it may change m_pMessageSvc
0141     if ( !m_pMessageSvc ) {
0142       m_pMessageSvc = serviceLocator(); // default message service
0143       if ( !m_pMessageSvc ) {
0144         throw GaudiException( "Service [MessageSvc] not found", this->parentName(), StatusCode::FAILURE );
0145       }
0146     }
0147     return m_pMessageSvc;
0148   }
0149   //
0150   // private data members
0151   //
0152   mutable SmartIF<ISvcLocator> m_pSvcLocator;
0153   mutable SmartIF<IMessageSvc> m_pMessageSvc;
0154 };
0155 
0156 /** @class ServiceHandleArray ServiceHandle.h GaudiKernel/ServiceHandle.h
0157 
0158     Array of Handles to be used in lieu of vector of naked pointers to tools.
0159     This allows better control through the framework of tool loading and usage.
0160     @parameter T is the AlgTool interface class (or concrete class) of
0161     the tool to use, and must derive from IAlgTool.
0162 
0163     @author Yushu Yao <yyao@lbl.gov>
0164 */
0165 
0166 template <class T>
0167 class ServiceHandleArray : public GaudiHandleArray<ServiceHandle<T>> {
0168 public:
0169   //
0170   // Constructors
0171   //
0172   /** Generic constructor. Probably not very useful...
0173    **/
0174   ServiceHandleArray( const std::vector<std::string>& myTypesAndNamesList, const std::string& myComponentType,
0175                       const std::string& myParentName )
0176       : GaudiHandleArray<ServiceHandle<T>>( myTypesAndNamesList, myComponentType, myParentName ) {}
0177 
0178   virtual ~ServiceHandleArray() {}
0179 
0180   ServiceHandleArray( const std::string& myParentName )
0181       : GaudiHandleArray<ServiceHandle<T>>( "Service", myParentName ) {}
0182 
0183   virtual bool push_back( const std::string& serviceTypeAndName ) {
0184     ServiceHandle<T> handle( serviceTypeAndName, GaudiHandleInfo::parentName() );
0185     GaudiHandleArray<ServiceHandle<T>>::push_back( handle );
0186     return true;
0187   }
0188 
0189   virtual bool push_back( const ServiceHandle<T>& myHandle ) { return push_back( myHandle.typeAndName() ); }
0190 };
0191 
0192 template <class T>
0193 inline std::ostream& operator<<( std::ostream& os, const ServiceHandle<T>& handle ) {
0194   return operator<<( os, static_cast<const GaudiHandleInfo&>( handle ) );
0195 }
0196 
0197 template <class T>
0198 inline std::ostream& operator<<( std::ostream& os, const ServiceHandleArray<T>& handle ) {
0199   return operator<<( os, static_cast<const GaudiHandleInfo&>( handle ) );
0200 }
0201 
0202 #endif // ! GAUDIKERNEL_SERVICEHANDLE_H