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 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
176 template<class RefCountable>
177 static Ptr<RefCountable> toPtr(RefCountable* refCountable)
178 {
179 return Ptr<RefCountable>(refCountable);
180 }
181
185 template<class RefCountable, typename... Args>
186 static Ptr<RefCountable> makePtr(Args&&... args)
187 {
188 return toPtr(new RefCountable(std::forward<Args>(args)...));
189 }
190
195 template</*explicit*/ class Interface, /*deduced*/ class RefCountablePtr,
196 /*deduced*/ typename OldInterfaceId>
197 static Ptr<Interface> queryInterfaceOfOldSdk(
198 RefCountablePtr refCountable, const OldInterfaceId& interfaceId)
199 {
200 return refCountable
201 ? toPtr(static_cast<Interface*>(refCountable->queryInterface(interfaceId)))
202 : nullptr;
203 }
204
209 template<class RefCountable>
210 int refCount(const Ptr<RefCountable>& ptr)
211 {
212 return refCount(ptr.get());
213 }
214
215 } // namespace sdk
216 } // 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