ACF $AcfVersion:0$
TOptInterfacePtr.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// ACF includes
7
8
9namespace istd
10{
11
12
64template<class InterfaceType>
66{
67public:
68 typedef InterfaceType Interface;
71
72 TOptInterfacePtr(TOptInterfacePtr&&) noexcept = default;
73 TOptInterfacePtr& operator=(TOptInterfacePtr&&) noexcept = default;
74 TOptInterfacePtr() = default;
75
76 // Disallow ambiguous raw-ptr constructor (use SetUnmanagedPtr or AdoptRawPtr)
77 TOptInterfacePtr(Interface* unamangedPtr) = delete;
78
79
80 // Non-owning, explicit
81 static TOptInterfacePtr FromUnmanaged(InterfaceType* ptr)
82 {
83 TOptInterfacePtr retVal;
84
85 retVal.SetUnmanagedPtr(ptr);
86
87 return retVal;
88 }
89
90
92 :m_sharedPtr(managedPtr)
93 {
94 }
95
96
98 {
99 m_sharedPtr.FromUnique(managedPtr);
100 }
101
102
104 {
105 m_unmanagedPtr = ptr;
106
107 m_sharedPtr.Reset();
108
109 AssertInvariant();
110 }
111
112
114 {
115 m_sharedPtr = managedPtr;
116
117 m_unmanagedPtr = nullptr;
118
119 AssertInvariant();
120 }
121
122
127 void AdoptRawPtr(Interface* rawPtr)
128 {
129 m_sharedPtr = rawPtr;
130
131 m_unmanagedPtr = nullptr;
132
133 AssertInvariant();
134 }
135
136
137 template <typename T>
138 bool AdoptCastedRawPtr(T* rawPtr)
139 {
140 if (rawPtr == nullptr) {
141 Reset();
142
143 return true;
144 }
145
146 InterfaceType* castedPtr = dynamic_cast<InterfaceType*> (rawPtr);
147 if (castedPtr != nullptr) {
148 AdoptRawPtr(castedPtr);
149
150 return true;
151 }
152
153 return false;
154 }
155
156
157 template <class T>
159 {
160 if (!source.IsValid()) {
161 Reset();
162
163 return true;
164 }
165
166 SharedInterfacePtr sharedPtr;
167 if (sharedPtr.SetCastedPtr(source)) {
168 m_sharedPtr = sharedPtr;
169
170 m_unmanagedPtr = nullptr;
171
172 return true;
173 }
174
175 return false;
176 }
177
178
180 {
181 m_sharedPtr = ptr.m_sharedPtr;
182
183 m_unmanagedPtr = ptr.m_unmanagedPtr;
184
185 ptr.m_sharedPtr.Reset();
186 ptr.m_unmanagedPtr = nullptr;
187
188 AssertInvariant();
189 }
190
191
192 template <class T>
194 {
195 if (!source.IsValid()) {
196 Reset();
197
198 AssertInvariant();
199
200 return true;
201 }
202
204 if (sharedPtr.IsValid()) {
205 m_sharedPtr = sharedPtr;
206 m_unmanagedPtr = nullptr;
207
208 Q_ASSERT(!source.IsValid());
209
210 AssertInvariant();
211
212 return true;
213 }
214
215 return false;
216 }
217
218
219 template <class T>
221 {
222 if (!source.IsValid()) {
223 Reset();
224
225 AssertInvariant();
226
227 return true;
228 }
229
231 if (sharedPtr.IsValid()) {
232 m_sharedPtr = sharedPtr;
233 m_unmanagedPtr = nullptr;
234 Q_ASSERT(!source.IsValid());
235
236 AssertInvariant();
237
238 return true;
239 }
240
241 return false;
242 }
243
244
245 bool IsValid() const
246 {
247 return (m_unmanagedPtr != nullptr) || m_sharedPtr.IsValid();
248 }
249
250
251 bool IsManaged() const
252 {
253 return m_sharedPtr.IsValid();
254 }
255
256
257 bool IsUnmanaged() const
258 {
259 return (m_unmanagedPtr != nullptr);
260 }
261
262
263 void Reset()
264 {
265 m_unmanagedPtr = nullptr;
266
267 m_sharedPtr.Reset();
268 }
269
270
271 template<typename InterfaceCast = InterfaceType>
272 const InterfaceCast* GetPtr() const
273 {
274 AssertInvariant();
275
276 const Interface* retVal = nullptr;
277 if (m_unmanagedPtr != nullptr){
278 retVal = m_unmanagedPtr;
279 }
280 else if (m_sharedPtr.IsValid()){
281 retVal = m_sharedPtr.GetPtr();
282 }
283 else {
284 return nullptr;
285 }
286
287 if constexpr (std::is_same_v<InterfaceCast, InterfaceType>){
288 return retVal;
289 }
290 else{
291 return dynamic_cast<const InterfaceCast*>(retVal);
292 }
293 }
294
295
296 template<typename InterfaceCast = InterfaceType>
297 InterfaceCast* GetPtr() // non-const
298 {
299 AssertInvariant();
300
301 Interface* retVal = nullptr;
302 if (m_unmanagedPtr) {
303 retVal = m_unmanagedPtr;
304 }
305 else if (m_sharedPtr.IsValid()) {
306 retVal = m_sharedPtr.GetPtr(); // should be non-const getter
307 }
308 else {
309 return nullptr;
310 }
311
312 if constexpr (std::is_same_v<InterfaceCast, InterfaceType>) {
313 return retVal;
314 }
315 else {
316 return dynamic_cast<InterfaceCast*>(retVal);
317 }
318 }
319
320
321 const Interface* operator->() const
322 {
323 Q_ASSERT(GetPtr() != nullptr);
324
325 return GetPtr();
326 }
327
328
330 {
331 Q_ASSERT(GetPtr() != nullptr);
332
333 return GetPtr();
334 }
335
336
337 const Interface& operator*() const
338 {
339 Q_ASSERT(GetPtr() != nullptr);
340
341 return *GetPtr();
342 }
343
344
346 {
347 Q_ASSERT(GetPtr() != nullptr);
348
349 return *GetPtr();
350 }
351
352
357 {
358 m_sharedPtr = ptr.m_sharedPtr;
359
360 m_unmanagedPtr = ptr.m_unmanagedPtr;
361 }
362
363
368 {
369 m_sharedPtr = ptr.m_sharedPtr;
370
371 m_unmanagedPtr = ptr.m_unmanagedPtr;
372
373 return *this;
374 }
375
376
377 explicit operator bool() const noexcept
378 {
379 return IsValid();
380 }
381
382private:
383 inline void AssertInvariant() const
384 {
385 Q_ASSERT((m_sharedPtr.IsValid() && (m_unmanagedPtr == nullptr)) || (!m_sharedPtr.IsValid() && (m_unmanagedPtr != nullptr)) || (!m_sharedPtr.IsValid() && (m_unmanagedPtr == nullptr)));
386 }
387
388private:
389
393 SharedInterfacePtr m_sharedPtr;
394
398 Interface* m_unmanagedPtr = nullptr;
399};
400
401
402} // namespace istd
403
404
bool IsValid() const noexcept
Interface * GetPtr() noexcept
A wrapper for managed and unmanaged interface pointers.
const Interface & operator*() const
const Interface * operator->() const
bool SetCastedPtr(TSharedInterfacePtr< T > &source)
istd::TSharedInterfacePtr< InterfaceType > SharedInterfacePtr
bool AdoptCastedRawPtr(T *rawPtr)
void TakeOver(TOptInterfacePtr &ptr)
TOptInterfacePtr(const TOptInterfacePtr &ptr)
Copy constructor.
void SetManagedPtr(SharedInterfacePtr managedPtr)
const InterfaceCast * GetPtr() const
TOptInterfacePtr(TOptInterfacePtr &&) noexcept=default
TOptInterfacePtr(UniqueInterfacePtr &managedPtr)
void SetUnmanagedPtr(Interface *ptr)
TOptInterfacePtr(SharedInterfacePtr managedPtr)
istd::TUniqueInterfacePtr< InterfaceType > UniqueInterfacePtr
bool TakeOver(TUniqueInterfacePtr< T > &source)
InterfaceCast * GetPtr()
bool TakeOver(TUniqueInterfacePtr< T > &&source)
static TOptInterfacePtr FromUnmanaged(InterfaceType *ptr)
void AdoptRawPtr(Interface *rawPtr)
Adopts ownership of a raw pointer.The pointer must be allocated in a manner compatible with SharedInt...
TOptInterfacePtr & operator=(const TOptInterfacePtr &ptr)
Assign operator.
Shared ownership smart pointer for interface types.
static TSharedInterfacePtr CreateFromUnique(TUniqueInterfacePtr< OtherInterface > &uniquePtr) noexcept
Create a shared pointer from unique pointer of other type by transferring ownership if dynamic_cast s...
bool SetCastedPtr(TSharedInterfacePtr< SourceInterfaceType > &source) noexcept
Set from another shared pointer if dynamic_cast succeeds.
TSharedInterfacePtr & FromUnique(TUniqueInterfacePtr< DerivedType > &&uniquePtr) noexcept
Convert from unique to shared.
Unique ownership smart pointer for interface types.
Standard library.
Definition IComponent.h:17