nx_server_plugin_sdk 1.0 Server Plugin 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) noexcept: 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) noexcept { 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 First, typename Second>
168 bool operator<(const Ptr<First>& first, const Ptr<Second>& second)
169 {
170 return first.get() < second.get();
171 }
172
173 template<typename RefCountable>
174 bool operator<(const Ptr<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
185 template<typename First, typename Second>
186 bool operator<(const Ptr<First>& first, const Second* second)
187 {
188 return first.get() < second;
189 }
190
191 template<typename First, typename Second>
192 bool operator<(const First* first, const Ptr<Second>& second)
193 {
194 return first < second.get();
195 }
196
201 template<class RefCountable>
202 static Ptr<RefCountable> shareToPtr(RefCountable* refCountable)
203 {
204 if (refCountable)
205 refCountable->addRef();
206 return Ptr(refCountable);
207 }
208
213 template<class RefCountable>
214 static Ptr<RefCountable> shareToPtr(const Ptr<RefCountable>& ptr)
215 {
216 return ptr; //< Invoke the copy constructor.
217 }
218
222 template<class RefCountable, typename... Args>
223 static Ptr<RefCountable> makePtr(Args&&... args)
224 {
225 return Ptr(new RefCountable(std::forward<Args>(args)...));
226 }
227
232 template</*explicit*/ class NewRefCountable, /*deduced*/ class OldRefCountable>
233 static Ptr<NewRefCountable> reinterpretPtr(const Ptr<OldRefCountable>& ptr)
234 {
235 return shareToPtr(reinterpret_cast<NewRefCountable*>(ptr.get()));
236 }
237
242 template</*explicit*/ class Interface, /*deduced*/ class RefCountablePtr,
243 /*deduced*/ typename OldInterfaceId>
244 static Ptr<Interface> queryInterfaceOfOldSdk(
245 RefCountablePtr refCountable, const OldInterfaceId& interfaceId)
246 {
247 return refCountable
248 ? Ptr(static_cast<Interface*>(refCountable->queryInterface(interfaceId)))
249 : nullptr;
250 }
251
256 template<class RefCountable>
257 static int refCount(const Ptr<RefCountable>& ptr)
258 {
259 return refCount(ptr.get());
260 }
261
262 } // namespace sdk
263 } // namespace nx
nx::sdk::Ptr::releasePtr
RefCountable * releasePtr()
Definition: ptr.h:92
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=(const Ptr &other)
Definition: ptr.h:50
nx
Definition: apple_utils.h:6
nx::sdk::Ptr::operator=
Ptr & operator=(Ptr &&other) noexcept
Definition: ptr.h:56
nx::sdk::Ptr::Ptr
Ptr(const Ptr &other)
Definition: ptr.h:38
nx::sdk::Ptr::reset
void reset(OtherRefCountable *ptr)
Definition: ptr.h:81
nx::sdk::RefCountable
Definition: ref_countable.h:83
nx::sdk::Ptr::reset
void reset()
Definition: ptr.h:70
nx::sdk::Ptr::Ptr
Ptr(Ptr &&other) noexcept
Definition: ptr.h:44