nx_metadata_sdk  1.0
Metadata SDK
ref_countable.h
1 // Copyright 2018-present Network Optix, Inc. Licensed under MPL 2.0: www.mozilla.org/MPL/2.0/
2 
3 #pragma once
4 
5 #include <atomic>
6 
7 #include <nx/sdk/helpers/lib_context.h>
8 #include <nx/sdk/i_ref_countable.h>
9 
10 namespace nx::sdk {
11 
24 {
25 public:
26  RefCountableHolder(const RefCountableHolder&) = delete;
27  RefCountableHolder& operator=(const RefCountableHolder&) = delete;
29  RefCountableHolder& operator=(RefCountableHolder&&) = delete;
30  ~RefCountableHolder() = default;
31 
38  RefCountableHolder(const IRefCountable* refCountable): m_refCountable(refCountable) {}
39 
43  RefCountableHolder(const RefCountableHolder* delegate): m_refCountHolderDelegate(delegate) {}
44 
45  int addRef() const
46  {
47  return m_refCountHolderDelegate ? m_refCountHolderDelegate->addRef() : ++m_refCount;
48  }
49 
53  int releaseRef() const
54  {
55  if (m_refCountHolderDelegate)
56  return m_refCountHolderDelegate->releaseRef();
57 
58  const int newRefCounter = --m_refCount;
59  if (newRefCounter == 0)
60  delete m_refCountable;
61  return newRefCounter;
62  }
63 
64  int refCount() const
65  {
66  if (m_refCountHolderDelegate)
67  return m_refCountHolderDelegate->refCount();
68  return m_refCount;
69  }
70 
71 private:
72  mutable std::atomic<int> m_refCount{1};
73  const IRefCountable* const m_refCountable = nullptr;
74  const RefCountableHolder* const m_refCountHolderDelegate = nullptr;
75 };
76 
82 template<class RefCountableInterface>
83 class RefCountable: public RefCountableInterface
84 {
85 public:
86  RefCountable(const RefCountable&) = delete;
87  RefCountable& operator=(const RefCountable&) = delete;
88  RefCountable(RefCountable&&) = delete;
89  RefCountable& operator=(RefCountable&&) = delete;
90 
91  virtual ~RefCountable()
92  {
93  if (const auto refCountableRegistry = libContext().refCountableRegistry())
94  refCountableRegistry->notifyDestroyed(this, refCount());
95  }
96 
97  virtual int addRef() const override { return m_refCountableHolder.addRef(); }
98  virtual int releaseRef() const override { return m_refCountableHolder.releaseRef(); }
99 
100  int refCount() const { return m_refCountableHolder.refCount(); }
101 
102 protected:
103  RefCountable(): m_refCountableHolder(static_cast<const IRefCountable*>(this))
104  {
105  if (const auto refCountableRegistry = libContext().refCountableRegistry())
106  refCountableRegistry->notifyCreated(this, refCount());
107  }
108 
109 private:
110  const RefCountableHolder m_refCountableHolder;
111 };
112 
113 } // namespace nx::sdk
RefCountableHolder(const RefCountableHolder *delegate)
Definition: ref_countable.h:43
RefCountableHolder(const IRefCountable *refCountable)
Definition: ref_countable.h:38
int releaseRef() const
Definition: ref_countable.h:53
Definition: device_agent.h:12
Definition: ref_countable.h:23
Definition: i_ref_countable.h:48
Definition: ref_countable.h:83