nx_video_source_sdk  1.0
Video Source SDK
ptr.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 <cstddef>
6 #include <type_traits>
7 #include <utility>
8 
9 namespace nx {
10 namespace sdk {
11 
17 template<class RefCountable>
18 class Ptr final
19 {
20 public:
22  Ptr(std::nullptr_t = nullptr)
23  {
24  // This assertion needs to be placed in any method because it uses sizeof().
25  static_assert(sizeof(Ptr<RefCountable>) == sizeof(RefCountable*),
26  "Ptr layout should be the same as of a raw pointer.");
27  }
28 
29  explicit Ptr(RefCountable* ptr): m_ptr(ptr) {}
30 
31  template<class OtherRefCountable>
32  explicit Ptr(OtherRefCountable* ptr): m_ptr(ptr) {}
33 
34  template<class OtherRefCountable>
35  Ptr(const Ptr<OtherRefCountable>& other): m_ptr(other.get()) { addRef(); }
36 
38  Ptr(const Ptr& other): m_ptr(other.get()) { addRef(); }
39 
40  template<class OtherRefCountable>
41  Ptr(Ptr<OtherRefCountable>&& other): m_ptr(other.releasePtr()) {}
42 
44  Ptr(Ptr&& other): m_ptr(other.releasePtr()) {}
45 
46  template<class OtherRefCountable>
47  Ptr& operator=(const Ptr<OtherRefCountable>& other) { return assignConst(other); }
48 
50  Ptr& operator=(const Ptr& other) { return assignConst(other); }
51 
52  template<class OtherRefCountable>
53  Ptr& operator=(Ptr<OtherRefCountable>&& other) { return assignRvalue(std::move(other)); }
54 
56  Ptr& operator=(Ptr&& other) { return assignRvalue(std::move(other)); }
57 
58  ~Ptr() { releaseRef(); }
59 
60  template<class OtherRefCountable>
61  bool operator==(const Ptr<OtherRefCountable>& other) const { return m_ptr == other.get(); }
62 
63  template<class OtherRefCountable>
64  bool operator!=(const Ptr<OtherRefCountable>& other) const { return !operator==(other); }
65 
70  void reset()
71  {
72  releaseRef();
73  m_ptr = nullptr;
74  }
75 
80  template<class OtherRefCountable>
81  void reset(OtherRefCountable* ptr)
82  {
83  releaseRef();
84  m_ptr = ptr;
85  }
86 
92  RefCountable* releasePtr()
93  {
94  RefCountable* result = m_ptr;
95  m_ptr = nullptr;
96  return result;
97  }
98 
99  RefCountable* get() const { return m_ptr; }
100  RefCountable* operator->() const { return m_ptr; }
101  RefCountable& operator*() const { return *m_ptr; }
102 
103  explicit operator bool() const { return m_ptr != nullptr; }
104 
105 private:
106  void addRef()
107  {
108  if (m_ptr)
109  m_ptr->addRef();
110  }
111 
112  void releaseRef()
113  {
114  if (m_ptr)
115  m_ptr->releaseRef();
116  }
117 
118  Ptr& assignConst(const Ptr& other)
119  {
120  if (this != &other && m_ptr != other.get())
121  {
122  releaseRef();
123  m_ptr = other.get();
124  addRef();
125  }
126  return *this;
127  }
128 
129  Ptr& assignRvalue(Ptr&& other)
130  {
131  if (this != &other && m_ptr != other.get())
132  {
133  releaseRef();
134  m_ptr = other.releasePtr();
135  }
136  return *this;
137  }
138 
139 private:
140  RefCountable* m_ptr = nullptr;
141 };
142 
143 template<class RefCountable, typename Object>
144 bool operator==(const Ptr<RefCountable>& ptr, Object* p) { return ptr.get() == p; }
145 
146 template<typename Object, class RefCountable>
147 bool operator==(Object* p, const Ptr<RefCountable>& ptr) { return p == ptr.get(); }
148 
149 template<class RefCountable, typename Object>
150 bool operator!=(const Ptr<RefCountable>& ptr, Object* p) { return ptr.get() != p; }
151 
152 template<typename Object, class RefCountable>
153 bool operator!=(Object* p, const Ptr<RefCountable>& ptr) { return p != ptr.get(); }
154 
155 template<class RefCountable>
156 bool operator==(const Ptr<RefCountable>& ptr, std::nullptr_t) { return !ptr; }
157 
158 template<class RefCountable>
159 bool operator==(std::nullptr_t, const Ptr<RefCountable>& ptr) { return !ptr; }
160 
161 template<class RefCountable>
162 bool operator!=(const Ptr<RefCountable>& ptr, std::nullptr_t) { return (bool) ptr; }
163 
164 template<class RefCountable>
165 bool operator!=(std::nullptr_t, const Ptr<RefCountable>& ptr) { return (bool) ptr; }
166 
167 template<typename RefCountable>
168 bool operator<(const Ptr<const RefCountable>& first, const Ptr<const RefCountable>& second)
169 {
170  return first.get() < second.get();
171 }
172 
173 template<typename RefCountable>
174 bool operator<(const Ptr<const RefCountable>& refCountable, std::nullptr_t)
175 {
176  return refCountable.get() < nullptr;
177 }
178 
179 template<typename RefCountable>
180 bool operator<(std::nullptr_t, const Ptr<RefCountable>& refCountable)
181 {
182  return nullptr < refCountable.get();
183 }
184 
189 template<class RefCountable>
190 static Ptr<RefCountable> shareToPtr(RefCountable* refCountable)
191 {
192  if (refCountable)
193  refCountable->addRef();
194  return Ptr(refCountable);
195 }
196 
201 template<class RefCountable>
202 static Ptr<RefCountable> shareToPtr(const Ptr<RefCountable>& ptr)
203 {
204  return ptr; //< Invoke the copy constructor.
205 }
206 
210 template<class RefCountable, typename... Args>
211 static Ptr<RefCountable> makePtr(Args&&... args)
212 {
213  return Ptr(new RefCountable(std::forward<Args>(args)...));
214 }
215 
220 template</*explicit*/ class Interface, /*deduced*/ class RefCountablePtr,
221  /*deduced*/ typename OldInterfaceId>
222 static Ptr<Interface> queryInterfaceOfOldSdk(
223  RefCountablePtr refCountable, const OldInterfaceId& interfaceId)
224 {
225  return refCountable
226  ? Ptr(static_cast<Interface*>(refCountable->queryInterface(interfaceId)))
227  : nullptr;
228 }
229 
234 template<class RefCountable>
235 int refCount(const Ptr<RefCountable>& ptr)
236 {
237  return refCount(ptr.get());
238 }
239 
240 } // namespace sdk
241 } // namespace nx
Ptr(Ptr &&other)
Definition: ptr.h:44
RefCountable * releasePtr()
Definition: ptr.h:92
Definition: ptr.h:18
Ptr(std::nullptr_t=nullptr)
Definition: ptr.h:22
Ptr & operator=(Ptr &&other)
Definition: ptr.h:56
Ptr & operator=(const Ptr &other)
Definition: ptr.h:50
Definition: apple_utils.h:6
Ptr(const Ptr &other)
Definition: ptr.h:38
void reset(OtherRefCountable *ptr)
Definition: ptr.h:81
void reset()
Definition: ptr.h:70