ACF $AcfVersion:0$
TInterfacePtr.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// STL includes
6#include <memory>
7#include <utility>
8#include <functional>
9
10// Qt includes
11#include <QtCore/QDebug>
12
13// ACF includes
14#include <istd/IPolymorphic.h>
15
16
17namespace istd
18{
19
20
38template <class InterfaceType, class PolymorphicPointerImpl>
40{
41public:
42 typedef PolymorphicPointerImpl RootObjectPtr;
43 typedef std::function<InterfaceType* ()> ExtractInterfaceFunc;
44
45 bool IsValid() const noexcept
46 {
47 return m_interfacePtr != nullptr;
48 }
49
50 template<typename Interface = InterfaceType>
51 Interface* GetPtr() noexcept
52 {
53 if constexpr (std::is_same_v<Interface, InterfaceType>){
54 return m_interfacePtr;
55 }
56 else{
57 return dynamic_cast<Interface*>(m_interfacePtr);
58 }
59 }
60
61 template<typename Interface = InterfaceType>
62 const Interface* GetPtr() const noexcept
63 {
64 if constexpr (std::is_same_v<Interface, InterfaceType>){
65 return m_interfacePtr;
66 }
67 else{
68 return dynamic_cast<const Interface*>(m_interfacePtr);
69 }
70 }
71
72 const InterfaceType* operator->() const noexcept
73 {
74 Q_ASSERT(m_interfacePtr != nullptr);
75
76 return m_interfacePtr;
77 }
78
79 InterfaceType* operator->() noexcept
80 {
81 Q_ASSERT(m_interfacePtr != nullptr);
82
83 return m_interfacePtr;
84 }
85
86 const InterfaceType& operator*() const noexcept
87 {
88 Q_ASSERT(m_interfacePtr != nullptr);
89
90 return *m_interfacePtr;
91 }
92
93 InterfaceType& operator*() noexcept
94 {
95 Q_ASSERT(m_interfacePtr != nullptr);
96
97 return *m_interfacePtr;
98 }
99
100 void Reset() noexcept
101 {
102 m_rootPtr.reset();
103 m_interfacePtr = nullptr;
104 }
105
111 void SetPtr(InterfaceType* interfacePtr)
112 {
113 // Reset root with the raw pointer. This is only safe if the pointer types match.
114 m_rootPtr.reset(interfacePtr);
115
116 m_interfacePtr = interfacePtr;
117 }
118
119 void SetPtr(istd::IPolymorphic* rootPtr, const ExtractInterfaceFunc& extractInterface)
120 {
121 m_rootPtr.reset(rootPtr);
122
123 m_interfacePtr = extractInterface();
124 }
125
126 void SetPtr(istd::IPolymorphic* rootPtr, InterfaceType* interfacePtr) noexcept
127 {
128 m_rootPtr.reset(rootPtr);
129
130 m_interfacePtr = interfacePtr;
131 }
132
134 {
135 return m_rootPtr;
136 }
137
138 const RootObjectPtr& GetBasePtr() const noexcept
139 {
140 return m_rootPtr;
141 }
142
143 //
144 // STL-like support
145 //
146
147 InterfaceType* get() noexcept
148 {
149 return GetPtr();
150 }
151
155 const InterfaceType* get() const noexcept
156 {
157 return GetPtr();
158 }
159
160 explicit operator bool() const noexcept
161 {
162 return IsValid();
163 }
164
165 bool operator==(std::nullptr_t) const noexcept
166 {
167 return !IsValid();
168 }
169
170 bool operator!=(std::nullptr_t) const noexcept
171 {
172 return IsValid();
173 }
174
175 TInterfacePtr& operator=(std::nullptr_t) noexcept
176 {
177 Reset();
178
179 return *this;
180 }
181
182protected:
183 TInterfacePtr(const TInterfacePtr&) = delete;
185
186 TInterfacePtr() noexcept
187 :m_interfacePtr(nullptr)
188 {
189 }
190
191 TInterfacePtr(InterfaceType* interfacePtr) noexcept
192 :m_interfacePtr(interfacePtr)
193 {
194 m_rootPtr.reset(interfacePtr);
195 }
196
197 TInterfacePtr(std::nullptr_t) noexcept
198 :m_rootPtr(),
199 m_interfacePtr(nullptr)
200 {
201 }
202
203 TInterfacePtr(istd::IPolymorphic* rootPtr, const ExtractInterfaceFunc& extractInterface) noexcept
204 {
205 SetPtr(rootPtr, extractInterface);
206 }
207
208 TInterfacePtr(istd::IPolymorphic* rootPtr, InterfaceType* interfacePtr) noexcept
209 {
210 SetPtr(rootPtr, interfacePtr);
211 }
212
213 // Move constructor
215 :m_rootPtr(std::move(ptr.m_rootPtr)),
216 m_interfacePtr(std::exchange(ptr.m_interfacePtr, nullptr))
217 {
218 }
219
220 // Move assignment
222 {
223 if (this != &ptr){
224 m_rootPtr = std::move(ptr.m_rootPtr);
225 m_interfacePtr = std::exchange(ptr.m_interfacePtr, nullptr);
226 }
227 return *this;
228 }
229
230protected:
231 // invariant: both pointers are either null or valid,
232 // and if valid, m_interfacePtr points to an interface implemented by the object owned by m_rootPtr
234 InterfaceType* m_interfacePtr = nullptr;
235};
236
237
272template <class InterfaceType, class RootIntefaceType = istd::IPolymorphic>
273class TUniqueInterfacePtr : public TInterfacePtr<InterfaceType, std::unique_ptr<RootIntefaceType>>
274{
275
276 template<typename U, typename R>
278
279public:
281 typedef typename BaseClass::ExtractInterfaceFunc ExtractInterfaceFunc;
282
283 static_assert(std::is_base_of_v<istd::IPolymorphic, RootIntefaceType>,
284 "RootIntefaceType must derive from istd::IPolymorphic");
285 static_assert(std::has_virtual_destructor_v<RootIntefaceType>,
286 "RootIntefaceType must have a virtual destructor");
287 static_assert(std::is_base_of_v<RootIntefaceType, InterfaceType>,
288 "InterfaceType must derive from RootIntefaceType");
289
291 :BaseClass()
292 {
293 }
294
295 TUniqueInterfacePtr(InterfaceType* interfacePtr) noexcept
296 :BaseClass(interfacePtr)
297 {
298 }
299
300 template <typename T>
301 TUniqueInterfacePtr(std::unique_ptr<T>&& ptr) noexcept
302 {
303 BaseClass::m_interfacePtr = ptr.get();
304 BaseClass::m_rootPtr = std::move(ptr);
305 }
306
307 explicit TUniqueInterfacePtr(RootIntefaceType* rootPtr, const ExtractInterfaceFunc& extractInterface) noexcept
308 :BaseClass(rootPtr, extractInterface)
309 {
310 }
311
312 explicit TUniqueInterfacePtr(RootIntefaceType* rootPtr, InterfaceType* interfacePtr) noexcept
313 :BaseClass(rootPtr, interfacePtr)
314 {
315 }
316
319
323 template <typename DerivedType>
325 {
326 static_assert(std::is_base_of_v<InterfaceType, DerivedType>, "DerivedType must extend InterfaceType");
327 BaseClass::m_rootPtr = std::move(ptr.m_rootPtr);
328 BaseClass::m_interfacePtr = std::exchange(ptr.m_interfacePtr, nullptr);
329 }
330
335 {
336 if (this != &ptr){
337 BaseClass::m_rootPtr = std::move(ptr.m_rootPtr);
338 BaseClass::m_interfacePtr = std::exchange(ptr.m_interfacePtr, nullptr);
339 }
340 return *this;
341 }
342
346 template <typename DerivedType>
348 {
349 static_assert(std::is_base_of_v<InterfaceType, DerivedType>, "DerivedType must extend InterfaceType");
350 static_assert(!std::is_same_v<DerivedType, InterfaceType>, "Non-templated move assignment operator overload must be used");
351
352 BaseClass::m_rootPtr = std::move(ptr.m_rootPtr);
353 BaseClass::m_interfacePtr = std::exchange(ptr.m_interfacePtr, nullptr);
354 return *this;
355 }
356
357 TUniqueInterfacePtr& operator=(std::nullptr_t) noexcept
358 {
359 BaseClass::Reset();
360 return *this;
361 }
362
366 RootIntefaceType* PopRootPtr() noexcept
367 {
368 BaseClass::m_interfacePtr = nullptr;
369
370 return BaseClass::m_rootPtr.release(); // caller owns returned pointer
371 }
372
383 InterfaceType* PopInterfacePtr() noexcept
384 {
385 // Case 1: Root and interface are the same (simple objects)
386 if (BaseClass::m_rootPtr.get() == BaseClass::m_interfacePtr){
387 InterfaceType* retVal = BaseClass::m_interfacePtr;
388
389 BaseClass::m_interfacePtr = nullptr;
390
391 BaseClass::m_rootPtr.release();
392
393 return retVal;
394 }
395
396 // Case 2: Only interface is set, no root
397 if (BaseClass::m_interfacePtr != nullptr && BaseClass::m_rootPtr.get() == nullptr){
398 InterfaceType* retVal = BaseClass::m_interfacePtr;
399
400 BaseClass::m_interfacePtr = nullptr;
401
402 return retVal;
403 }
404
405 // Case 3: Root and interface differ (composite components)
406 if (BaseClass::m_rootPtr.get() != nullptr && BaseClass::m_interfacePtr != nullptr){
407 // First check if dynamic_cast will succeed to avoid memory leak
408 InterfaceType* castedPtr = dynamic_cast<InterfaceType*>(BaseClass::m_rootPtr.get());
409 if (castedPtr != nullptr){
410 // Cast succeeded, safe to release ownership
411 RootIntefaceType* rootPtr = PopRootPtr();
412 Q_UNUSED(rootPtr);
413
414 return castedPtr;
415 }
416
417 // Cast failed - this should never happen in correct code
418 Q_ASSERT(false && "dynamic_cast failed in PopInterfacePtr - interface pointer type mismatch");
419
420 return nullptr;
421 }
422
423 // Empty pointer
424 return nullptr;
425 }
426
435 InterfaceType* PopPtr() noexcept
436 {
437 return PopInterfacePtr();
438 }
439
445 {
446 *this = std::move(from);
447 }
448
449 template<class SourceInterfaceType>
451 {
452 InterfaceType* targetPtr = dynamic_cast<InterfaceType*>(source.GetPtr());
453 if (targetPtr != nullptr){
454 BaseClass::m_rootPtr = std::move(source.GetBasePtr());
455 BaseClass::m_interfacePtr = targetPtr;
456 source.Reset();
457 return true;
458 }
459 return false;
460 }
461
462 template<class SourceInterfaceType>
463 [[deprecated]] bool MoveCastedPtr(TUniqueInterfacePtr<SourceInterfaceType>& source) noexcept
464 {
465 return MoveCastedPtr(std::move(source));
466 }
467};
468
469
505template <class InterfaceType, class RootIntefaceType = istd::IPolymorphic>
506class TSharedInterfacePtr : public TInterfacePtr<InterfaceType, std::shared_ptr<RootIntefaceType>>
507{
508public:
510 typedef typename BaseClass::ExtractInterfaceFunc ExtractInterfaceFunc;
511
512 static_assert(std::is_base_of_v<istd::IPolymorphic, RootIntefaceType>, "RootIntefaceType must derive from istd::IPolymorphic");
513 static_assert(std::has_virtual_destructor_v<RootIntefaceType>, "RootIntefaceType must have a virtual destructor");
514 static_assert(std::is_base_of_v<RootIntefaceType, InterfaceType>,
515 "InterfaceType must derive from RootIntefaceType");
516
518 :BaseClass()
519 {
520 }
521
522 TSharedInterfacePtr(InterfaceType* interfacePtr) noexcept
523 :BaseClass(interfacePtr)
524 {
525 }
526
527 TSharedInterfacePtr(RootIntefaceType* rootPtr, const ExtractInterfaceFunc& extractInterface) noexcept
528 :BaseClass(rootPtr, extractInterface)
529 {
530 }
531
536 {
537 BaseClass::m_rootPtr = ptr.m_rootPtr;
538 BaseClass::m_interfacePtr = ptr.m_interfacePtr;
539 }
540
544 template <typename DerivedType>
546 {
547 static_assert(std::is_base_of_v<InterfaceType, DerivedType>, "DerivedType must extend InterfaceType");
548 BaseClass::m_rootPtr = other.GetBasePtr();
549 BaseClass::m_interfacePtr = const_cast<DerivedType*>(other.GetPtr());
550 }
551
552 template<typename DerivedType>
553 TSharedInterfacePtr(const std::shared_ptr<DerivedType>& ptr) noexcept
554 {
555 static_assert(std::is_base_of_v<RootIntefaceType, InterfaceType>, "Here InterfaceType must extend RootIntefaceType");
556 static_assert(std::is_base_of_v<InterfaceType, DerivedType>, "DerivedType must extend InterfaceType");
557 BaseClass::m_rootPtr = ptr;
558 BaseClass::m_interfacePtr = ptr.get();
559 }
560
561 template<typename DerivedType>
562 TSharedInterfacePtr(std::unique_ptr<DerivedType>&& ptr) noexcept
563 {
564 static_assert(std::is_base_of_v<RootIntefaceType, InterfaceType>, "Here InterfaceType must extend RootIntefaceType");
565 static_assert(std::is_base_of_v<InterfaceType, DerivedType>, "DerivedType must extend InterfaceType");
566 BaseClass::m_interfacePtr = ptr.get();
567 BaseClass::m_rootPtr = std::move(ptr);
568 }
569
574 {
575 BaseClass::m_rootPtr = std::move(ptr.m_rootPtr);
576 BaseClass::m_interfacePtr = std::exchange(ptr.m_interfacePtr, nullptr);
577 }
578
582 template <typename DerivedType>
584 {
585 FromUnique(std::move(ptr));
586 }
587
589 {
590 Reset();
591 }
592
593 void Reset() noexcept
594 {
595 BaseClass::m_rootPtr.reset();
596 BaseClass::m_interfacePtr = nullptr;
597 }
598
603 {
604 BaseClass::m_rootPtr = ptr.m_rootPtr;
605 BaseClass::m_interfacePtr = ptr.m_interfacePtr;
606 return *this;
607 }
608
612 template <typename DerivedType>
614 {
615 static_assert(std::is_base_of_v<InterfaceType, DerivedType>, "DerivedType must extend InterfaceType");
616 BaseClass::m_rootPtr = ptr.GetBasePtr();
617 BaseClass::m_interfacePtr = const_cast<DerivedType*>(ptr.GetPtr());
618 return *this;
619 }
620
622 {
623 BaseClass::m_rootPtr = std::move(ptr.m_rootPtr);
624 BaseClass::m_interfacePtr = std::exchange(ptr.m_interfacePtr, nullptr);
625 return *this;
626 }
627
631 template<typename DerivedType>
633 {
634 static_assert(std::is_base_of_v<InterfaceType, DerivedType>, "DerivedType must extend InterfaceType");
635
636 if (!uniquePtr.IsValid()){
637 Reset();
638 return *this;
639 }
640
641 BaseClass::m_interfacePtr = uniquePtr.GetPtr();
642
643 // Acquire raw pointer in one step and assign to shared_ptr to avoid leaks on exceptions.
644 RootIntefaceType* rawRoot = uniquePtr.PopRootPtr(); // caller (this function) now owns rawRoot
645 if (rawRoot == nullptr){
646 Reset();
647 return *this;
648 }
649
650 // Create shared_ptr from raw pointer (shared_ptr now owns it)
651 BaseClass::m_rootPtr = std::shared_ptr<RootIntefaceType>(rawRoot);
652
653 return *this;
654 }
655
657 {
658 return FromUnique(std::move(uniquePtr));
659 }
660
664 template <typename OtherInterface>
666 {
667 TSharedInterfacePtr retVal;
668 if (!uniquePtr.IsValid()){
669 return retVal;
670 }
671
672 // Try dynamic cast on the raw pointer before transferring ownership
673 InterfaceType* interfacePtr = dynamic_cast<InterfaceType*>(uniquePtr.GetPtr());
674 if (interfacePtr != nullptr){
675 RootIntefaceType* rawRoot = uniquePtr.PopRootPtr();
676 retVal.BaseClass::m_rootPtr = std::shared_ptr<RootIntefaceType>(rawRoot);
677 retVal.BaseClass::m_interfacePtr = interfacePtr;
678 }
679
680 return retVal;
681 }
682
688 {
689 TSharedInterfacePtr retVal;
690 retVal.FromUnique(std::move(uniquePtr));
691 return retVal;
692 }
693
695 {
696 return CreateFromUnique(std::move(uniquePtr));
697 }
698
702 template<class SourceInterfaceType>
704 {
705 if (!source.IsValid()){
706 Reset();
707 return true;
708 }
709
710 InterfaceType* targetPtr = dynamic_cast<InterfaceType*>(source.GetPtr());
711 if (targetPtr != nullptr){
712 // Transfer ownership of the unique_ptr into shared_ptr safely
713 RootIntefaceType* rawRoot = source.PopRootPtr();
714 BaseClass::m_rootPtr = std::shared_ptr<RootIntefaceType>(rawRoot);
715 BaseClass::m_interfacePtr = targetPtr;
716 return true;
717 }
718
719 return false;
720 }
721
722 template<class SourceInterfaceType>
723 [[deprecated]] bool MoveCastedPtr(TUniqueInterfacePtr<SourceInterfaceType>& source) noexcept
724 {
725 return MoveCastedPtr(std::move(source));
726 }
727
731 template<class SourceInterfaceType>
733 {
734 if (!source.IsValid()){
735 Reset();
736 return true;
737 }
738
739 InterfaceType* targetPtr = dynamic_cast<InterfaceType*>(source.GetPtr());
740 if (targetPtr != nullptr){
741 BaseClass::m_rootPtr = source.GetBasePtr();
742 BaseClass::m_interfacePtr = targetPtr;
743 return true;
744 }
745
746 return false;
747 }
748
749 //
750 // Qt-like support
751 //
752
753 template <class T>
755 {
757 retVal.SetCastedPtr(*this);
758 return retVal;
759 }
760
761 template <class T>
763 {
765 retVal.SetCastedPtr(const_cast<TSharedInterfacePtr&>(*this));
766 return retVal;
767 }
768};
769
770
771} // namespace istd
772
773
Base interface for all used interfaces and implementations.
Base template for polymorphic interface pointers.
bool IsValid() const noexcept
TInterfacePtr(InterfaceType *interfacePtr) noexcept
InterfaceType * operator->() noexcept
Interface * GetPtr() noexcept
TInterfacePtr & operator=(std::nullptr_t) noexcept
PolymorphicPointerImpl RootObjectPtr
const InterfaceType & operator*() const noexcept
void SetPtr(InterfaceType *interfacePtr)
bool operator!=(std::nullptr_t) const noexcept
TInterfacePtr(const TInterfacePtr &)=delete
const Interface * GetPtr() const noexcept
TInterfacePtr & operator=(TInterfacePtr &&ptr) noexcept
const InterfaceType * operator->() const noexcept
const RootObjectPtr & GetBasePtr() const noexcept
InterfaceType & operator*() noexcept
void Reset() noexcept
void SetPtr(istd::IPolymorphic *rootPtr, const ExtractInterfaceFunc &extractInterface)
InterfaceType * get() noexcept
TInterfacePtr & operator=(const TInterfacePtr &)=delete
TInterfacePtr(TInterfacePtr &&ptr) noexcept
TInterfacePtr(istd::IPolymorphic *rootPtr, InterfaceType *interfacePtr) noexcept
bool operator==(std::nullptr_t) const noexcept
const InterfaceType * get() const noexcept
std::function< InterfaceType *()> ExtractInterfaceFunc
InterfaceType * m_interfacePtr
TInterfacePtr(std::nullptr_t) noexcept
RootObjectPtr & GetBasePtr() noexcept
RootObjectPtr m_rootPtr
void SetPtr(istd::IPolymorphic *rootPtr, InterfaceType *interfacePtr) noexcept
TInterfacePtr(istd::IPolymorphic *rootPtr, const ExtractInterfaceFunc &extractInterface) noexcept
Shared ownership smart pointer for interface types.
TSharedInterfacePtr & operator=(TSharedInterfacePtr &&ptr) noexcept
static TSharedInterfacePtr CreateFromUnique(TUniqueInterfacePtr< OtherInterface > &uniquePtr) noexcept
Create a shared pointer from unique pointer of other type by transferring ownership if dynamic_cast s...
TSharedInterfacePtr & operator=(const TSharedInterfacePtr &ptr) noexcept
Copy assignment operator.
TSharedInterfacePtr< const T > dynamicCast() const noexcept
TSharedInterfacePtr(const std::shared_ptr< DerivedType > &ptr) noexcept
TSharedInterfacePtr(TSharedInterfacePtr &&ptr) noexcept
Move constructor.
TSharedInterfacePtr(RootIntefaceType *rootPtr, const ExtractInterfaceFunc &extractInterface) noexcept
TSharedInterfacePtr(std::unique_ptr< DerivedType > &&ptr) noexcept
BaseClass::ExtractInterfaceFunc ExtractInterfaceFunc
TSharedInterfacePtr< T > dynamicCast() noexcept
bool MoveCastedPtr(TUniqueInterfacePtr< SourceInterfaceType > &&source) noexcept
Move-cast from unique: transfer ownership if dynamic_cast succeeds.
bool SetCastedPtr(TSharedInterfacePtr< SourceInterfaceType > &source) noexcept
Set from another shared pointer if dynamic_cast succeeds.
TSharedInterfacePtr(InterfaceType *interfacePtr) noexcept
TSharedInterfacePtr(const TSharedInterfacePtr &ptr) noexcept
Copy constructor.
TInterfacePtr< InterfaceType, std::shared_ptr< RootIntefaceType > > BaseClass
TSharedInterfacePtr & FromUnique(TUniqueInterfacePtr< InterfaceType > &uniquePtr) noexcept
TSharedInterfacePtr(const TSharedInterfacePtr< DerivedType > &other) noexcept
Copy constructor from derived type.
static TSharedInterfacePtr CreateFromUnique(TUniqueInterfacePtr< InterfaceType > &uniquePtr) noexcept
TSharedInterfacePtr & operator=(const TSharedInterfacePtr< DerivedType > &ptr) noexcept
Copy assignment operator from derived type.
static TSharedInterfacePtr CreateFromUnique(TUniqueInterfacePtr< InterfaceType > &&uniquePtr) noexcept
Create a shared pointer from unique of the same type by transferring ownership.
TSharedInterfacePtr(TUniqueInterfacePtr< DerivedType > &&ptr) noexcept
Construct from unique by transferring ownership into shared.
bool MoveCastedPtr(TUniqueInterfacePtr< SourceInterfaceType > &source) noexcept
TSharedInterfacePtr & FromUnique(TUniqueInterfacePtr< DerivedType > &&uniquePtr) noexcept
Convert from unique to shared.
Unique ownership smart pointer for interface types.
TUniqueInterfacePtr(std::unique_ptr< T > &&ptr) noexcept
TInterfacePtr< InterfaceType, std::unique_ptr< RootIntefaceType > > BaseClass
TUniqueInterfacePtr & operator=(std::nullptr_t) noexcept
TUniqueInterfacePtr & operator=(TUniqueInterfacePtr &&ptr) noexcept
Move assignment.
void TakeOver(TUniqueInterfacePtr< InterfaceType > &from) noexcept
Transfer ownership from another unique ptr (take over raw ownership).
bool MoveCastedPtr(TUniqueInterfacePtr< SourceInterfaceType > &&source) noexcept
TUniqueInterfacePtr(const TUniqueInterfacePtr &ptr)=delete
TUniqueInterfacePtr(InterfaceType *interfacePtr) noexcept
bool MoveCastedPtr(TUniqueInterfacePtr< SourceInterfaceType > &source) noexcept
InterfaceType * PopInterfacePtr() noexcept
Intelligent pop of interface pointer.
RootIntefaceType * PopRootPtr() noexcept
Pop the root pointer.
TUniqueInterfacePtr(RootIntefaceType *rootPtr, const ExtractInterfaceFunc &extractInterface) noexcept
BaseClass::ExtractInterfaceFunc ExtractInterfaceFunc
InterfaceType * PopPtr() noexcept
Intelligent pop method - alias for PopInterfacePtr().
TUniqueInterfacePtr & operator=(const TUniqueInterfacePtr &ptr)=delete
TUniqueInterfacePtr(RootIntefaceType *rootPtr, InterfaceType *interfacePtr) noexcept
TUniqueInterfacePtr & operator=(TUniqueInterfacePtr< DerivedType > &&ptr) noexcept
Move assignment from derived type.
TUniqueInterfacePtr(TUniqueInterfacePtr< DerivedType > &&ptr) noexcept
Move constructor from unique pointer for the derived or same type.
Standard library.
Definition IComponent.h:17