Back to home page

EIC code displayed by LXR

 
 

    


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

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_IMPLEMENTS_H
0012 #define GAUDIKERNEL_IMPLEMENTS_H
0013 
0014 #include "GaudiKernel/IInterface.h"
0015 #include <atomic>
0016 
0017 /// Base class used to implement the interfaces.
0018 template <typename... Interfaces>
0019 struct GAUDI_API implements : virtual public extend_interfaces<Interfaces...> {
0020   /// Typedef to this class.
0021   using base_class = implements<Interfaces...>;
0022   /// Typedef to the base of this class.
0023   using extend_interfaces_base = extend_interfaces<Interfaces...>;
0024   using iids                   = typename extend_interfaces_base::ext_iids;
0025 
0026 public:
0027   /**Implementation of IInterface::i_cast. */
0028   void* i_cast( const InterfaceID& tid ) const override { return Gaudi::iid_cast( tid, iids{}, this ); }
0029   /** Implementation of IInterface::queryInterface. */
0030   StatusCode queryInterface( const InterfaceID& ti, void** pp ) override {
0031     if ( !pp ) return StatusCode::FAILURE;
0032     *pp = Gaudi::iid_cast( ti, iids{}, this );
0033     if ( !*pp ) return StatusCode::FAILURE; /* cast failed */
0034     this->addRef();
0035     return StatusCode::SUCCESS;
0036   }
0037   /** Implementation of IInterface::getInterfaceNames. */
0038   std::vector<std::string> getInterfaceNames() const override { return Gaudi::getInterfaceNames( iids{} ); }
0039   /** Default constructor */
0040   implements() = default;
0041   /** Copy constructor (zero the reference count) */
0042   implements( const implements& /*other*/ ) : m_refCount{ 0 } {}
0043   /** Assignment operator (do not touch the reference count).*/
0044   implements& operator=( const implements& /*other*/ ) { return *this; }
0045 
0046 public:
0047   /** Reference Interface instance               */
0048   unsigned long addRef() override { return ++m_refCount; }
0049   /** Release Interface instance                 */
0050   unsigned long release() override {
0051     /* Avoid to decrement 0 */
0052     auto count = ( m_refCount ? --m_refCount : m_refCount.load() );
0053     if ( count == 0 ) delete this;
0054     return count;
0055   }
0056   /** Current reference count                    */
0057   unsigned long refCount() const override { return m_refCount.load(); }
0058 
0059 protected:
0060   /** Reference counter                          */
0061   std::atomic_ulong m_refCount = { 0 };
0062 };
0063 
0064 template <typename I1>
0065 using implements1 = implements<I1>;
0066 template <typename I1, typename I2>
0067 using implements2 = implements<I1, I2>;
0068 template <typename I1, typename I2, typename I3>
0069 using implements3 = implements<I1, I2, I3>;
0070 template <typename I1, typename I2, typename I3, typename I4>
0071 using implements4 = implements<I1, I2, I3, I4>;
0072 
0073 #endif /* GAUDIKERNEL_IMPLEMENTS_H_ */