stub_analytics_plugin  1.6
Network Optix Video Analytics SDK
ptr.h
1 #pragma once
2 
3 #include <utility>
4 #include <cstddef>
5 #include <type_traits>
6 
7 namespace nx {
8 namespace sdk {
9 
15 template<class RefCountable>
16 class Ptr final
17 {
18 public:
20  Ptr(std::nullptr_t = nullptr) {}
21 
23  template<class OtherRefCountable>
24  using IsConvertibleFrom =
25  std::enable_if_t<std::is_base_of<RefCountable, OtherRefCountable>::value, int /*dummy*/>;
26 
27  explicit Ptr(RefCountable* ptr): m_ptr(ptr) {}
28 
29  template<class OtherRefCountable, IsConvertibleFrom<OtherRefCountable> = 0>
30  explicit Ptr(OtherRefCountable* ptr): m_ptr(ptr) {}
31 
32  template<class OtherRefCountable, IsConvertibleFrom<OtherRefCountable> = 0>
33  Ptr(const Ptr<OtherRefCountable>& other): m_ptr(other.get()) { addRef(); }
34 
36  Ptr(const Ptr& other): m_ptr(other.get()) { addRef(); }
37 
38  template<class OtherRefCountable, IsConvertibleFrom<OtherRefCountable> = 0>
39  Ptr(Ptr<OtherRefCountable>&& other): m_ptr(other.releasePtr()) {}
40 
42  Ptr(Ptr&& other): m_ptr(other.releasePtr()) {}
43 
44  template<class OtherRefCountable, IsConvertibleFrom<OtherRefCountable> = 0>
45  Ptr& operator=(const Ptr<OtherRefCountable>& other) { return assignConst(other); }
46 
48  Ptr& operator=(const Ptr& other) { return assignConst(other); }
49 
50  template<class OtherRefCountable, IsConvertibleFrom<OtherRefCountable> = 0>
51  Ptr& operator=(Ptr<OtherRefCountable>&& other) { return assignRvalue(std::move(other)); }
52 
54  Ptr& operator=(Ptr&& other) { return assignRvalue(std::move(other)); }
55 
56  ~Ptr() { releaseRef(); }
57 
58  template<class OtherRefCountable, IsConvertibleFrom<OtherRefCountable> = 0>
59  bool operator==(const Ptr<OtherRefCountable>& other) const { return m_ptr == other.get(); }
60 
61  template<class OtherRefCountable, IsConvertibleFrom<OtherRefCountable> = 0>
62  bool operator!=(const Ptr<OtherRefCountable>& other) const { return !operator==(other); }
63 
68  void reset()
69  {
70  releaseRef();
71  m_ptr = nullptr;
72  }
73 
78  template<class OtherRefCountable, IsConvertibleFrom<OtherRefCountable> = 0>
79  void reset(OtherRefCountable* ptr)
80  {
81  releaseRef();
82  m_ptr = ptr;
83  }
84 
91  {
92  RefCountable* result = m_ptr;
93  m_ptr = nullptr;
94  return result;
95  }
96 
97  RefCountable* get() const { return m_ptr; }
98  RefCountable* operator->() const { return m_ptr; }
99 
100  operator bool() const { return m_ptr != nullptr; }
101 
102  template<class OtherRefCountable>
103  Ptr<OtherRefCountable> dynamicCast() const
104  {
105  auto ptr = dynamic_cast<OtherRefCountable*>(m_ptr);
106  if (ptr)
107  m_ptr->addRef();
108  return Ptr<OtherRefCountable>(ptr);
109  }
110 
111 private:
112  void addRef()
113  {
114  if (m_ptr)
115  m_ptr->addRef();
116  }
117 
118  void releaseRef()
119  {
120  if (m_ptr)
121  m_ptr->releaseRef();
122  }
123 
124  Ptr& assignConst(const Ptr& other)
125  {
126  if (this != &other && m_ptr != other.get())
127  {
128  releaseRef();
129  m_ptr = other.get();
130  addRef();
131  }
132  return *this;
133  }
134 
135  Ptr& assignRvalue(Ptr&& other)
136  {
137  if (this != &other && m_ptr != other.get())
138  {
139  releaseRef();
140  m_ptr = other.releasePtr();
141  }
142  return *this;
143  }
144 
145 private:
146  RefCountable* m_ptr = nullptr;
147 };
148 
149 template<class RefCountable>
150 bool operator==(const Ptr<RefCountable>& ptr, std::nullptr_t) { return ! (bool) ptr; }
151 
152 template<class RefCountable>
153 bool operator==(std::nullptr_t, const Ptr<RefCountable>& ptr) { return ! (bool) ptr; }
154 
155 template<class RefCountable>
156 bool operator!=(const Ptr<RefCountable>& ptr, std::nullptr_t) { return (bool) ptr; }
157 
158 template<class RefCountable>
159 bool operator!=(std::nullptr_t, const Ptr<RefCountable>& ptr) { return (bool) ptr; }
160 
167 template<class RefCountable>
168 static Ptr<RefCountable> toPtr(RefCountable* refCountable)
169 {
170  return Ptr<RefCountable>(refCountable);
171 }
172 
176 template<class RefCountable, typename... Args>
177 static Ptr<RefCountable> makePtr(Args&&... args)
178 {
179  return Ptr<RefCountable>{new RefCountable(std::forward<Args>(args)...)};
180 }
181 
185 template</*explicit*/ class Interface, /*deduced*/ class RefCountablePtr>
186 static Ptr<Interface> queryInterfacePtr(RefCountablePtr refCountable)
187 {
188  return Ptr<Interface>(
189  static_cast<Interface*>(refCountable->queryInterface(Interface::interfaceId())));
190 }
191 
195 template</*explicit*/ class Interface, /*deduced*/ class RefCountablePtr,
196  /*deduced*/ typename InterfaceId>
197 static Ptr<Interface> queryInterfacePtr(
198  RefCountablePtr refCountable, const InterfaceId& interfaceId)
199 {
200  return Ptr<Interface>(
201  static_cast<Interface*>(refCountable->queryInterface(interfaceId)));
202 }
203 
208 template<class RefCountable>
209 int refCount(const Ptr<RefCountable>& ptr)
210 {
211  return refCount(ptr.get());
212 }
213 
214 } // namespace sdk
215 } // namespace nx
Ptr(Ptr &&other)
Definition: ptr.h:42
RefCountable * releasePtr()
Definition: ptr.h:90
Definition: ptr.h:16
Ptr(std::nullptr_t=nullptr)
Definition: ptr.h:20
Ptr & operator=(Ptr &&other)
Definition: ptr.h:54
Ptr & operator=(const Ptr &other)
Definition: ptr.h:48
Definition: debug.cpp:12
Ptr(const Ptr &other)
Definition: ptr.h:36
void reset(OtherRefCountable *ptr)
Definition: ptr.h:79
std::enable_if_t< std::is_base_of< RefCountable, OtherRefCountable >::value, int > IsConvertibleFrom
Definition: ptr.h:25
Definition: ref_countable.h:79
void reset()
Definition: ptr.h:68