Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:38:41

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 GAUDI_SMARTIF_H
0012 #define GAUDI_SMARTIF_H 1
0013 
0014 // Framework include files
0015 #include "GaudiKernel/IInterface.h"
0016 
0017 /** @class SmartIF SmartIF.h GaudiKernel/SmartIF.h
0018  *
0019  * Small smart pointer class with automatic reference counting for IInterface.
0020  *
0021  * SmartIF simplifies the interaction with components in Gaudi by implementing
0022  * an automatic reference counting and the casting (via IInterface::queryInterface).
0023  *
0024  * @author Markus Frank
0025  * @author Sebastien Ponce
0026  * @author Marco Clemencic
0027  */
0028 template <class TYPE>
0029 class SmartIF {
0030 private:
0031   /// Pointer to the instance
0032   TYPE* m_interface = nullptr;
0033 
0034 public:
0035   // ---------- Construction and destruction ----------
0036   /// Default constructor.
0037   inline SmartIF() = default;
0038   /// Standard constructor from pointer.
0039   inline SmartIF( TYPE* ptr ) : m_interface( ptr ) {
0040     if ( m_interface ) m_interface->addRef();
0041   }
0042   /// Standard constructor from any (IInterface-derived) pointer.
0043   template <class OTHER>
0044   inline SmartIF( OTHER* ptr ) {
0045     if ( ptr ) reset( ptr );
0046   }
0047   /// Copy constructor.
0048   inline SmartIF( const SmartIF& rhs ) : m_interface( rhs.get() ) {
0049     if ( m_interface ) m_interface->addRef();
0050   }
0051   /// Move constructor
0052   inline SmartIF( SmartIF&& rhs ) : m_interface( rhs.m_interface ) { rhs.m_interface = nullptr; }
0053   /// Move assignement
0054   inline SmartIF& operator=( SmartIF&& rhs ) {
0055     if ( m_interface ) m_interface->release();
0056     m_interface     = rhs.m_interface;
0057     rhs.m_interface = nullptr;
0058     return *this;
0059   }
0060 
0061   /// Constructor from another SmartIF, with a different type.
0062   /// @note it cannot replace the copy constructor.
0063   template <class T>
0064   inline explicit SmartIF( const SmartIF<T>& rhs ) {
0065     reset( rhs.get() );
0066   }
0067   /// Standard Destructor.
0068   inline ~SmartIF() { reset(); }
0069 
0070   // ---------- Boolean and comparison methods ----------
0071   /// Allow for check if smart pointer is valid.
0072   inline bool isValid() const { return m_interface != nullptr; }
0073 
0074   inline explicit operator bool() const { return isValid(); }
0075   inline bool operator!() const { return !isValid(); }
0076 
0077   // ---------- Pointer access methods ----------
0078   /// Automatic conversion to pointer.
0079   /// It is also used by the compiler for automatic conversion to boolean.
0080   inline operator TYPE*() const { return m_interface; }
0081   /// Dereference operator
0082   inline TYPE* operator->() const { return m_interface; }
0083   /// Dereference operator
0084   inline TYPE& operator*() const { return *m_interface; }
0085   /// Get interface pointer
0086   inline TYPE* get() const { return m_interface; }
0087 #if !defined( GAUDI_V22_API ) && !defined( NEW_SMARTIF )
0088   /// Get reference to the pointer
0089   inline TYPE*& pRef() { return m_interface; }
0090 #endif
0091 
0092   // ---------- Cast methods ----------
0093   /// Set the internal pointer to the passed one disposing of the old one.
0094   /// Version for pointers of the same type of the managed ones (no call to
0095   /// queryInterface needed).
0096   inline void reset( TYPE* ptr = nullptr ) {
0097     if ( ptr == m_interface ) return;
0098     if ( m_interface ) m_interface->release();
0099     m_interface = ptr;
0100     if ( m_interface ) m_interface->addRef();
0101   }
0102   /// Set the internal pointer to the passed one disposing of the old one.
0103   /// Version for pointers of types inheriting from IInterface.
0104   template <class OTHER>
0105   inline void reset( OTHER* ptr ) {
0106     if ( static_cast<IInterface*>( ptr ) == static_cast<IInterface*>( m_interface ) ) return;
0107     if ( m_interface ) m_interface->release();
0108     if ( ptr ) {
0109       ptr->queryInterface( TYPE::interfaceID(), pp_cast<void>( &m_interface ) ).ignore();
0110     } else {
0111       m_interface = nullptr;
0112     }
0113   }
0114 
0115   /// return a new SmartIF instance to another interface
0116   template <typename IFace>
0117   SmartIF<IFace> as() const {
0118     return SmartIF<IFace>{ *this };
0119   }
0120 
0121   // ---------- Special hacks ----------
0122   /// Assignment operator from IInterface pointer.
0123   /// It allows things like
0124   /// <code>
0125   /// SmartIF<T> x;
0126   /// x = 0;
0127   /// </code>
0128   inline SmartIF& operator=( IInterface* ptr ) {
0129     reset( ptr );
0130     return *this;
0131   }
0132   /// Assignment operator.
0133   inline SmartIF& operator=( const SmartIF& rhs ) {
0134     reset( rhs.get() );
0135     return *this;
0136   }
0137   /// Assignment operator from a different SmartIF.
0138   /// @note it cannot replace the assignment operator.
0139   template <class T>
0140   inline SmartIF& operator=( const SmartIF<T>& rhs ) {
0141     reset( rhs.get() );
0142     return *this;
0143   }
0144 };
0145 
0146 // helper function to turn a pointer to an interface into
0147 // the corresponding SmartIF -- this avoids having to type
0148 // the typename twice, and thus insures consistency
0149 template <typename IFace>
0150 SmartIF<IFace> make_SmartIF( IFace* iface ) {
0151   return SmartIF<IFace>{ iface };
0152 }
0153 
0154 #endif // GAUDI_SMARTIF_H