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 <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
nx::sdk::Ptr::Ptr
Ptr(Ptr &&other)
Definition: ptr.h:44
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=(Ptr &&other)
Definition: ptr.h:56
nx::sdk::Ptr::operator=
Ptr & operator=(const Ptr &other)
Definition: ptr.h:50
nx
Definition: apple_utils.h:6
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