nx_metadata_sdk 1.0 Metadata 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 <utility>
6 #include <cstddef>
7 #include <type_traits>
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 template<class OtherRefCountable>
30 Ptr(const Ptr<OtherRefCountable>& other): m_ptr(other.get()) { addRef(); }
31
33 Ptr(const Ptr& other): m_ptr(other.get()) { addRef(); }
34
35 template<class OtherRefCountable>
36 Ptr(Ptr<OtherRefCountable>&& other): m_ptr(other.releasePtr()) {}
37
39 Ptr(Ptr&& other): m_ptr(other.releasePtr()) {}
40
41 template<class OtherRefCountable>
42 Ptr& operator=(const Ptr<OtherRefCountable>& other) { return assignConst(other); }
43
45 Ptr& operator=(const Ptr& other) { return assignConst(other); }
46
47 template<class OtherRefCountable>
48 Ptr& operator=(Ptr<OtherRefCountable>&& other) { return assignRvalue(std::move(other)); }
49
51 Ptr& operator=(Ptr&& other) { return assignRvalue(std::move(other)); }
52
53 ~Ptr() { releaseRef(); }
54
55 template<class OtherRefCountable>
56 bool operator==(const Ptr<OtherRefCountable>& other) const { return m_ptr == other.get(); }
57
58 template<class OtherRefCountable>
59 bool operator!=(const Ptr<OtherRefCountable>& other) const { return !operator==(other); }
60
65 void reset()
66 {
67 releaseRef();
68 m_ptr = nullptr;
69 }
70
75 template<class OtherRefCountable>
76 void reset(OtherRefCountable* ptr)
77 {
78 releaseRef();
79 m_ptr = ptr;
80 }
81
87 RefCountable* releasePtr()
88 {
89 RefCountable* result = m_ptr;
90 m_ptr = nullptr;
91 return result;
92 }
93
94 RefCountable* get() const { return m_ptr; }
95 RefCountable* operator->() const { return m_ptr; }
96 RefCountable& operator*() const { return *m_ptr; }
97
98 explicit operator bool() const { return m_ptr != nullptr; }
99
100 private:
101 template<class OtherRefCountable>
102 friend Ptr<OtherRefCountable> toPtr(OtherRefCountable* refCountable);
103
104 explicit Ptr(RefCountable* ptr): m_ptr(ptr) {}
105
106 template<class OtherRefCountable>
107 explicit Ptr(OtherRefCountable* ptr): m_ptr(ptr) {}
108
109 void addRef()
110 {
111 if (m_ptr)
112 m_ptr->addRef();
113 }
114
115 void releaseRef()
116 {
117 if (m_ptr)
118 m_ptr->releaseRef();
119 }
120
121 Ptr& assignConst(const Ptr& other)
122 {
123 if (this != &other && m_ptr != other.get())
124 {
125 releaseRef();
126 m_ptr = other.get();
127 addRef();
128 }
129 return *this;
130 }
131
132 Ptr& assignRvalue(Ptr&& other)
133 {
134 if (this != &other && m_ptr != other.get())
135 {
136 releaseRef();
137 m_ptr = other.releasePtr();
138 }
139 return *this;
140 }
141
142 private:
143 RefCountable* m_ptr = nullptr;
144 };
145
146 template<class RefCountable, typename Object>
147 bool operator==(const Ptr<RefCountable>& ptr, Object* p) { return ptr.get() == p; }
148
149 template<typename Object, class RefCountable>
150 bool operator==(Object* p, const Ptr<RefCountable>& ptr) { return p == ptr.get(); }
151
152 template<class RefCountable, typename Object>
153 bool operator!=(const Ptr<RefCountable>& ptr, Object* p) { return ptr.get() != p; }
154
155 template<typename Object, class RefCountable>
156 bool operator!=(Object* p, const Ptr<RefCountable>& ptr) { return p != ptr.get(); }
157
158 template<class RefCountable>
159 bool operator==(const Ptr<RefCountable>& ptr, std::nullptr_t) { return !ptr; }
160
161 template<class RefCountable>
162 bool operator==(std::nullptr_t, const Ptr<RefCountable>& ptr) { return !ptr; }
163
164 template<class RefCountable>
165 bool operator!=(const Ptr<RefCountable>& ptr, std::nullptr_t) { return (bool) ptr; }
166
167 template<class RefCountable>
168 bool operator!=(std::nullptr_t, const Ptr<RefCountable>& ptr) { return (bool) ptr; }
169
170 template<typename RefCountable>
171 bool operator<(const Ptr<const RefCountable>& first, const Ptr<const RefCountable>& second)
172 {
173 return first.get() < second.get();
174 }
175
176 template<typename RefCountable>
177 bool operator<(const Ptr<const RefCountable>& refCountable, std::nullptr_t)
178 {
179 return refCountable.get() < nullptr;
180 }
181
182 template<typename RefCountable>
183 bool operator<(std::nullptr_t, const Ptr<RefCountable>& refCountable)
184 {
185 return nullptr < refCountable.get();
186 }
187
194 template<class RefCountable>
195 static Ptr<RefCountable> toPtr(RefCountable* refCountable)
196 {
197 return Ptr<RefCountable>(refCountable);
198 }
199
204 template<class RefCountable>
205 static Ptr<RefCountable> shareToPtr(RefCountable* refCountable)
206 {
207 if (refCountable)
208 refCountable->addRef();
209 return toPtr(refCountable);
210 }
211
216 template<class RefCountable>
217 static Ptr<RefCountable> shareToPtr(const Ptr<RefCountable>& ptr)
218 {
219 return ptr; //< Invoke the copy constructor.
220 }
221
225 template<class RefCountable, typename... Args>
226 static Ptr<RefCountable> makePtr(Args&&... args)
227 {
228 return toPtr(new RefCountable(std::forward<Args>(args)...));
229 }
230
235 template</*explicit*/ class Interface, /*deduced*/ class RefCountablePtr,
236 /*deduced*/ typename OldInterfaceId>
237 static Ptr<Interface> queryInterfaceOfOldSdk(
238 RefCountablePtr refCountable, const OldInterfaceId& interfaceId)
239 {
240 return refCountable
241 ? toPtr(static_cast<Interface*>(refCountable->queryInterface(interfaceId)))
242 : nullptr;
243 }
244
249 template<class RefCountable>
250 int refCount(const Ptr<RefCountable>& ptr)
251 {
252 return refCount(ptr.get());
253 }
254
255 } // namespace sdk
256 } // namespace nx
nx::sdk::Ptr::Ptr
Ptr(Ptr &&other)
Definition: ptr.h:39
nx::sdk::Ptr::releasePtr
RefCountable * releasePtr()
Definition: ptr.h:87
nx::sdk::Ptr
Definition: ptr.h:18
nx::sdk::Ptr::Ptr
Ptr(std::nullptr_t=nullptr)
Definition: ptr.h:22
nx::sdk::Ptr::operator=
Ptr & operator=(Ptr &&other)
Definition: ptr.h:51
nx::sdk::Ptr::operator=
Ptr & operator=(const Ptr &other)
Definition: ptr.h:45
nx
Definition: apple_utils.h:6
nx::sdk::Ptr::Ptr
Ptr(const Ptr &other)
Definition: ptr.h:33
nx::sdk::Ptr::reset
void reset(OtherRefCountable *ptr)
Definition: ptr.h:76
nx::sdk::RefCountable
Definition: ref_countable.h:84
nx::sdk::Ptr::reset
void reset()
Definition: ptr.h:65