The Gaudi Framework  master (d98a2936)
implements.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #pragma once
12 
13 #include <GaudiKernel/IInterface.h>
14 #include <atomic>
15 #include <cassert>
16 
18 template <typename... Interfaces>
19 struct GAUDI_API implements : virtual public extend_interfaces<Interfaces...> {
21  using base_class = implements<Interfaces...>;
23  using extend_interfaces_base = extend_interfaces<Interfaces...>;
25 
26 public:
28  void const* i_cast( const InterfaceID& tid ) const override { return Gaudi::iid_cast( tid, iids{}, this ); }
30  StatusCode queryInterface( const InterfaceID& ti, void** pp ) override {
31  if ( !pp ) return StatusCode::FAILURE;
32  *pp = Gaudi::iid_cast( ti, iids{}, this );
33  if ( !*pp ) return StatusCode::FAILURE; /* cast failed */
34  this->addRef();
35  return StatusCode::SUCCESS;
36  }
38  std::vector<std::string> getInterfaceNames() const override { return Gaudi::getInterfaceNames( iids{} ); }
40  implements() = default;
42  implements( const implements& /*other*/ ) : m_refCount{ 0 } {}
44  implements& operator=( const implements& /*other*/ ) { return *this; } // cppcheck-suppress operatorEqVarError
45 
46 public:
48  unsigned long addRef() const override { return ++m_refCount; }
50  unsigned long release() const override {
51  if ( auto count = decRef() ) {
52  return count;
53  } else {
54  delete this;
55  return 0;
56  }
57  }
59  unsigned long refCount() const override { return m_refCount.load(); }
60 
61 protected:
62  unsigned long decRef() const override {
63  auto count = m_refCount.load();
64  // thread-safe decrement, but make sure we don't go below 0
65  // (if the last two references are being released at the same time, this guarantees that
66  // one decrements m_refCount from 2 to 1 and the other from 1 to 0)
67  while ( count > 0 && !m_refCount.compare_exchange_weak( count, count - 1 ) ) { assert( count > 0 ); }
68  // when we reach this point, we managed to set m_refCount to "count - 1", so no need to read it again
69  return count - 1;
70  }
71 
73  mutable std::atomic_ulong m_refCount = { 0 };
74 };
75 
76 template <typename I1>
78 template <typename I1, typename I2>
80 template <typename I1, typename I2, typename I3>
82 template <typename I1, typename I2, typename I3, typename I4>
implements::queryInterface
StatusCode queryInterface(const InterfaceID &ti, void **pp) override
Implementation of IInterface::queryInterface.
Definition: implements.h:30
extend_interfaces< Interfaces... >::ext_iids
typename Gaudi::interface_list_cat< typename Interfaces::ext_iids... >::type ext_iids
take union of the ext_iids of all Interfaces...
Definition: extend_interfaces.h:25
implements::operator=
implements & operator=(const implements &)
Assignment operator (do not touch the reference count).
Definition: implements.h:44
implements::refCount
unsigned long refCount() const override
Current reference count
Definition: implements.h:59
implements< IInterface >::iids
typename extend_interfaces_base::ext_iids iids
Definition: implements.h:24
implements::release
unsigned long release() const override
Release Interface instance
Definition: implements.h:50
implements::getInterfaceNames
std::vector< std::string > getInterfaceNames() const override
Implementation of IInterface::getInterfaceNames.
Definition: implements.h:38
extend_interfaces
Base class to be used to extend an interface.
Definition: extend_interfaces.h:14
implements::i_cast
void const * i_cast(const InterfaceID &tid) const override
Implementation of IInterface::i_cast.
Definition: implements.h:28
StatusCode
Definition: StatusCode.h:64
IInterface.h
implements::implements
implements()=default
Default constructor.
implements::implements
implements(const implements &)
Copy constructor (zero the reference count)
Definition: implements.h:42
implements::addRef
unsigned long addRef() const override
Reference Interface instance
Definition: implements.h:48
implements
Base class used to implement the interfaces.
Definition: implements.h:19
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:99
Gaudi::iid_cast
void * iid_cast(const InterfaceID &tid, Gaudi::interface_list< Is... >, P *ptr)
Definition: IInterface.h:163
Gaudi::getInterfaceNames
std::vector< std::string > getInterfaceNames(Gaudi::interface_list< Is... >)
Definition: IInterface.h:158
implements::decRef
unsigned long decRef() const override
Definition: implements.h:62
InterfaceID
Definition: IInterface.h:38
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:100
compareOutputFiles.pp
pp
Definition: compareOutputFiles.py:507
GAUDI_API
#define GAUDI_API
Definition: Kernel.h:49