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/i_ref_countable.h>
8 #include <nx/sdk/helpers/lib_context.h>
9 
10 namespace nx {
11 namespace sdk {
12 
25 {
26 public:
27  RefCountableHolder(const RefCountableHolder&) = delete;
28  RefCountableHolder& operator=(const RefCountableHolder&) = delete;
30  RefCountableHolder& operator=(RefCountableHolder&&) = delete;
31  ~RefCountableHolder() = default;
32 
39  RefCountableHolder(const IRefCountable* refCountable): m_refCountable(refCountable) {}
40 
44  RefCountableHolder(const RefCountableHolder* delegate): m_refCountHolderDelegate(delegate) {}
45 
46  int addRef() const
47  {
48  return m_refCountHolderDelegate ? m_refCountHolderDelegate->addRef() : ++m_refCount;
49  }
50 
54  int releaseRef() const
55  {
56  if (m_refCountHolderDelegate)
57  return m_refCountHolderDelegate->releaseRef();
58 
59  const int newRefCounter = --m_refCount;
60  if (newRefCounter == 0)
61  delete m_refCountable;
62  return newRefCounter;
63  }
64 
65  int refCount() const
66  {
67  if (m_refCountHolderDelegate)
68  return m_refCountHolderDelegate->refCount();
69  return m_refCount;
70  }
71 
72 private:
73  mutable std::atomic<int> m_refCount{1};
74  const IRefCountable* const m_refCountable = nullptr;
75  const RefCountableHolder* const m_refCountHolderDelegate = nullptr;
76 };
77 
83 template<class RefCountableInterface>
84 class RefCountable: public RefCountableInterface
85 {
86 public:
87  RefCountable(const RefCountable&) = delete;
88  RefCountable& operator=(const RefCountable&) = delete;
89  RefCountable(RefCountable&&) = delete;
90  RefCountable& operator=(RefCountable&&) = delete;
91 
92  virtual ~RefCountable()
93  {
94  if (const auto refCountableRegistry = libContext().refCountableRegistry())
95  refCountableRegistry->notifyDestroyed(this, refCount());
96  }
97 
98  virtual int addRef() const override { return m_refCountableHolder.addRef(); }
99  virtual int releaseRef() const override { return m_refCountableHolder.releaseRef(); }
100 
101  int refCount() const { return m_refCountableHolder.refCount(); }
102 
103 protected:
104  RefCountable(): m_refCountableHolder(static_cast<const RefCountableInterface*>(this))
105  {
106  if (const auto refCountableRegistry = libContext().refCountableRegistry())
107  refCountableRegistry->notifyCreated(this, refCount());
108  }
109 
110 private:
111  const RefCountableHolder m_refCountableHolder;
112 };
113 
114 } // namespace sdk
115 } // namespace nx
RefCountableHolder(const RefCountableHolder *delegate)
Definition: ref_countable.h:44
RefCountableHolder(const IRefCountable *refCountable)
Definition: ref_countable.h:39
int releaseRef() const
Definition: ref_countable.h:54
Definition: apple_utils.h:6
Definition: ref_countable.h:24
Definition: i_ref_countable.h:49
Definition: ref_countable.h:84