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