The Gaudi Framework  master (b9786168)
Loading...
Searching...
No Matches
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
14#include <atomic>
15#include <cassert>
16
18template <typename... Interfaces>
19struct GAUDI_API implements : virtual public extend_interfaces<Interfaces...> {
21 using base_class = implements<Interfaces...>;
25
26public:
27 using extend_interfaces_base::i_cast;
28
30 void const* i_cast( const InterfaceID& tid ) const override { return Gaudi::iid_cast( tid, iids{}, this ); }
32 StatusCode queryInterface( const InterfaceID& ti, void** pp ) override {
33 if ( !pp ) return StatusCode::FAILURE;
34 *pp = i_cast( ti );
35 if ( !*pp ) return StatusCode::FAILURE; /* cast failed */
36 this->addRef();
38 }
39
40 std::vector<std::string> getInterfaceNames() const override { return Gaudi::getInterfaceNames( iids{} ); }
42 implements() = default;
44 implements( const implements& /*other*/ ) : m_refCount{ 0 } {}
46 implements& operator=( const implements& /*other*/ ) { return *this; } // cppcheck-suppress operatorEqVarError
47
48public:
50 unsigned long addRef() const override { return ++m_refCount; }
52 unsigned long release() const override {
53 if ( auto count = decRef() ) {
54 return count;
55 } else {
56 delete this;
57 return 0;
58 }
59 }
60
61 unsigned long refCount() const override { return m_refCount.load(); }
62
63protected:
64 unsigned long decRef() const override {
65 auto count = m_refCount.load();
66 // thread-safe decrement, but make sure we don't go below 0
67 // (if the last two references are being released at the same time, this guarantees that
68 // one decrements m_refCount from 2 to 1 and the other from 1 to 0)
69 while ( count > 0 && !m_refCount.compare_exchange_weak( count, count - 1 ) ) { assert( count > 0 ); }
70 // when we reach this point, we managed to set m_refCount to "count - 1", so no need to read it again
71 return count - 1;
72 }
73
75 mutable std::atomic_ulong m_refCount = { 0 };
76};
77
78template <typename I1>
80template <typename I1, typename I2>
82template <typename I1, typename I2, typename I3>
84template <typename I1, typename I2, typename I3, typename I4>
#define GAUDI_API
Definition Kernel.h:49
Interface ID class.
Definition IInterface.h:38
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
implements< I1, I2 > implements2
Definition implements.h:81
implements< I1 > implements1
Definition implements.h:79
implements< I1, I2, I3, I4 > implements4
Definition implements.h:85
implements< I1, I2, I3 > implements3
Definition implements.h:83
void * iid_cast(const InterfaceID &tid, Gaudi::interface_list< Is... >, P *ptr)
Definition IInterface.h:163
std::vector< std::string > getInterfaceNames(Gaudi::interface_list< Is... >)
Definition IInterface.h:158
Base class to be used to extend an interface.
typename Gaudi::interface_list_cat< typename Interfaces::ext_iids... >::type ext_iids
Base class used to implement the interfaces.
Definition implements.h:19
unsigned long release() const override
Release Interface instance.
Definition implements.h:52
std::atomic_ulong m_refCount
Definition implements.h:75
implements & operator=(const implements &)
Assignment operator (do not touch the reference count).
Definition implements.h:46
std::vector< std::string > getInterfaceNames() const override
Implementation of IInterface::getInterfaceNames.
Definition implements.h:40
implements()=default
Default constructor.
StatusCode queryInterface(const InterfaceID &ti, void **pp) override
Implementation of IInterface::queryInterface.
Definition implements.h:32
extend_interfaces< Interfaces... > extend_interfaces_base
Definition implements.h:23
unsigned long refCount() const override
Current reference count.
Definition implements.h:61
implements< Interfaces... > base_class
Typedef to this class.
Definition implements.h:21
typename extend_interfaces_base::ext_iids iids
Definition implements.h:24
unsigned long addRef() const override
Definition implements.h:50
unsigned long decRef() const override
Definition implements.h:64
void const * i_cast(const InterfaceID &tid) const override
Implementation of IInterface::i_cast.
Definition implements.h:30
implements(const implements &)
Copy constructor (zero the reference count)
Definition implements.h:44