UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SharedPointerInternals.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5// HEADER_UNIT_SKIP - Included through SharedPointer.h
6
7#include "CoreTypes.h"
8#include "HAL/UnrealMemory.h"
13#include "AutoRTFM.h"
14#include <atomic>
15#include <type_traits>
16
18#define THREAD_SANITISE_UNSAFEPTR 0
19
20#if THREAD_SANITISE_UNSAFEPTR
21 #define TSAN_SAFE_UNSAFEPTR
22#else
23 #define TSAN_SAFE_UNSAFEPTR TSAN_SAFE
24#endif
25
26
32{
33 // Forward declarations
34 template< ESPMode Mode > class FWeakReferencer;
35
37 struct FStaticCastTag {};
38 struct FConstCastTag {};
39
40 // NOTE: The following is an Unreal extension to standard shared_ptr behavior
41 struct FNullTag {};
42
43 template <ESPMode Mode>
45 {
46 using RefCountType = std::conditional_t<Mode == ESPMode::ThreadSafe, std::atomic<int32>, int32>;
47
48 public:
50
51 // Number of shared references to this object. When this count reaches zero, the associated object
52 // will be destroyed (even if there are still weak references!), but not the reference controller.
53 //
54 // This starts at 1 because we create reference controllers via the construction of a TSharedPtr,
55 // and that is the first reference. There is no point in starting at 0 and then incrementing it.
56 RefCountType SharedReferenceCount{1};
57
58 // Number of weak references to this object. If there are any shared references, that counts as one
59 // weak reference too. When this count reaches zero, the reference controller will be deleted.
60 //
61 // This starts at 1 because it represents the shared reference that we are also initializing
62 // SharedReferenceCount with.
63 RefCountType WeakReferenceCount{1};
64
66 virtual void DestroyObject() = 0;
67
69 {
70 }
71
74 {
75 if constexpr (Mode == ESPMode::ThreadSafe)
76 {
77 // A 'live' shared reference count is unstable by nature and so there's no benefit
78 // to try and enforce memory ordering around the reading of it.
79 //
80 // This is equivalent to https://en.cppreference.com/w/cpp/memory/shared_ptr/use_count
81
82 int32 Count = 0;
83
85 {
86 // This reference count may be accessed by multiple threads
87 Count = SharedReferenceCount.load(std::memory_order_relaxed);
88 }
89 ;
90
91 return Count;
92 }
93 else
94 {
96 }
97 }
98
101 {
102 return 1 == GetSharedReferenceCount();
103 }
104
106 inline void AddSharedReference()
107 {
108 if constexpr (Mode == ESPMode::ThreadSafe)
109 {
110 // Incrementing a reference count with relaxed ordering is always safe because no other action is taken
111 // in response to the increment, so there's nothing to order with.
112
113#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
115 {
116 // We do a regular SC increment here because it maps to an _InterlockedIncrement (lock inc).
117 // The codegen for a relaxed fetch_add is actually much worse under MSVC (lock xadd).
119 };
120#else
122 {
123 SharedReferenceCount.fetch_add(1, std::memory_order_relaxed);
124 };
125#endif
126
127 // If the transaction would abort, we need to undo adding the shared reference.
129 {
131 };
132 }
133 else
134 {
136 }
137 }
138
145 {
146 if constexpr (Mode == ESPMode::ThreadSafe)
147 {
148 bool bSucceeded = false;
149
151 {
152 // See AddSharedReference for the same reasons that std::memory_order_relaxed is used in this function.
153
154 // Peek at the current shared reference count. Remember, this value may be updated by
155 // multiple threads.
156 int32 OriginalCount = SharedReferenceCount.load(std::memory_order_relaxed);
157
158 for (; ; )
159 {
160 if (OriginalCount == 0)
161 {
162 // Never add a shared reference if the pointer has already expired
163 bSucceeded = false;
164 break;
165 }
166
167 // Attempt to increment the reference count.
168 //
169 // We need to make sure that we never revive a counter that has already expired, so if the
170 // actual value what we expected (because it was touched by another thread), then we'll try
171 // again. Note that only in very unusual cases will this actually have to loop.
172 //
173 // We do a weak read here because we require a loop and this is the recommendation:
174 //
175 // https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange
176 //
177 // > When a compare-and-exchange is in a loop, the weak version will yield better performance on some platforms.
178 // > When a weak compare-and-exchange would require a loop and a strong one would not, the strong one is preferable
179 if (SharedReferenceCount.compare_exchange_weak(OriginalCount, OriginalCount + 1, std::memory_order_relaxed))
180 {
181 bSucceeded = true;
182 break;
183 }
184 }
185 };
186
187 // If we succeeded in taking a shared reference count, we need to undo that on an abort.
188 if (bSucceeded)
189 {
191 {
193 };
194 }
195
196 return bSucceeded;
197 }
198 else
199 {
200 if( SharedReferenceCount == 0 )
201 {
202 // Never add a shared reference if the pointer has already expired
203 return false;
204 }
205
207 return true;
208 }
209 }
210
213 {
214 if constexpr (Mode == ESPMode::ThreadSafe)
215 {
217 {
218 // std::memory_order_acq_rel is used here so that, if we do end up executing the destructor, it's not possible
219 // for side effects from executing the destructor end up being visible before we've determined that the shared
220 // reference count is actually zero.
221
222 int32 OldSharedCount = SharedReferenceCount.fetch_sub(1, std::memory_order_acq_rel);
224 if (OldSharedCount == 1)
225 {
226 // Last shared reference was released! Destroy the referenced object.
228
229 // No more shared referencers, so decrement the weak reference count by one. When the weak
230 // reference count reaches zero, this object will be deleted.
232 }
233 };
234 }
235 else
236 {
238
239 if( --SharedReferenceCount == 0 )
240 {
241 // Last shared reference was released! Destroy the referenced object.
243
244 // No more shared referencers, so decrement the weak reference count by one. When the weak
245 // reference count reaches zero, this object will be deleted.
247 }
248 }
249 }
250
253 {
254 if (ReferenceController != nullptr)
255 {
256 // Tell the reference counter object that we're no longer referencing the object with
257 // this shared pointer
258 ReferenceController->ReleaseSharedReference();
259 }
260 }
261
263 inline void AddWeakReference()
264 {
265 if constexpr (Mode == ESPMode::ThreadSafe)
266 {
267 // See AddSharedReference for the same reasons that std::memory_order_relaxed is used in this function.
268
269#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
271 {
272 // We do a regular SC increment here because it maps to an _InterlockedIncrement (lock inc).
273 // The codegen for a relaxed fetch_add is actually much worse under MSVC (lock xadd).
275 };
276#else
278 {
279 WeakReferenceCount.fetch_add(1, std::memory_order_relaxed);
280 };
281#endif
282
283 // If the transaction would abort, we need to undo adding the reference.
285 {
287 };
288 }
289 else
290 {
292 }
293 }
294
297 {
298 if constexpr (Mode == ESPMode::ThreadSafe)
299 {
301 {
302 // See ReleaseSharedReference for the same reasons that std::memory_order_acq_rel is used in this function.
303
304 int32 OldWeakCount = WeakReferenceCount.fetch_sub(1, std::memory_order_acq_rel);
306 if (OldWeakCount == 1)
307 {
308 // Disable this if running clang's static analyzer. Passing shared pointers
309 // and references to functions it cannot reason about, produces false
310 // positives about use-after-free in the TSharedPtr/TSharedRef destructors.
311#if !defined(__clang_analyzer__)
312 // No more references to this reference count. Destroy it!
313 delete this;
314#endif
315 }
316 };
317 }
318 else
319 {
321
322 if( --WeakReferenceCount == 0 )
323 {
324 // No more references to this reference count. Destroy it!
325#if !defined(__clang_analyzer__)
326 delete this;
327#endif
328 }
329 }
330 }
331
332 // Non-copyable
335 };
336
337 // A helper class that efficiently stores a custom deleter and is intended to be derived from. If the custom deleter is an empty class,
338 // TDeleterHolder derives from it exploiting empty base optimisation (https://en.cppreference.com/w/cpp/language/ebo). Otherwise
339 // it stores the custom deleter as a member to allow a function pointer to be used as a custom deleter (a function pointer can't
340 // be a base class)
341 template <typename DeleterType, bool bIsZeroSize = std::is_empty_v<DeleterType>>
342 struct TDeleterHolder : private DeleterType
343 {
344 explicit TDeleterHolder(DeleterType&& Arg)
345 : DeleterType(MoveTemp(Arg))
346 {
347 }
348
349 template <typename ObjectType>
350 void InvokeDeleter(ObjectType * Object)
351 {
352 Invoke(*static_cast<DeleterType*>(this), Object);
353 }
354 };
355
356 template <typename DeleterType>
357 struct TDeleterHolder<DeleterType, false>
358 {
359 explicit TDeleterHolder(DeleterType&& Arg)
360 : Deleter(MoveTemp(Arg))
361 {
362 }
363
364 template <typename ObjectType>
365 void InvokeDeleter(ObjectType * Object)
366 {
367 Invoke(Deleter, Object);
368 }
369
370 private:
371 DeleterType Deleter;
372 };
373
374 template <typename ObjectType, typename DeleterType, ESPMode Mode>
376 {
377 public:
378 explicit TReferenceControllerWithDeleter(ObjectType* InObject, DeleterType&& Deleter)
379 : TDeleterHolder<DeleterType>(MoveTemp(Deleter))
380 , Object(InObject)
381 {
382 }
383
384 virtual void DestroyObject() override
385 {
386 this->InvokeDeleter(Object);
387 }
388
389 // Non-copyable
392
393 private:
395 ObjectType* Object;
396 };
397
398 template <typename ObjectType, ESPMode Mode>
400 {
401 public:
402 template <typename... ArgTypes>
404 {
405 // If this fails to compile when trying to call MakeShared with a non-public constructor,
406 // do not make SharedPointerInternals::TIntrusiveReferenceController a friend.
407 //
408 // Instead, prefer this pattern:
409 //
410 // class FMyType
411 // {
412 // private:
413 // struct FPrivateToken { explicit FPrivateToken() = default; };
414 //
415 // public:
416 // // This has an equivalent access level to a private constructor,
417 // // as only friends of FMyType will have access to FPrivateToken,
418 // // but MakeShared can legally call it since it's public.
419 // explicit FMyType(FPrivateToken, int32 Int, float Real, const TCHAR* String);
420 // };
421 //
422 // // Won't compile if the caller doesn't have access to FMyType::FPrivateToken
423 // TSharedPtr<FMyType> Val = MakeShared<FMyType>(FMyType::FPrivateToken{}, 5, 3.14f, TEXT("Banana"));
424 //
425 ::new ((void*)&ObjectStorage) ObjectType(Forward<ArgTypes>(Args)...);
426 }
427
428 ObjectType* GetObjectPtr() const
429 {
430 return (ObjectType*)&ObjectStorage;
431 }
432
433 virtual void DestroyObject() override
434 {
435 DestructItem((ObjectType*)&ObjectStorage);
436 }
437
438 // Non-copyable
441
442 private:
444 mutable TTypeCompatibleBytes<ObjectType> ObjectStorage;
445 };
446
447
449 template <typename Type>
451 {
453 {
454 delete Object;
455 }
456 };
457
459 template <ESPMode Mode, typename ObjectType>
464
466 template <ESPMode Mode, typename ObjectType, typename DeleterType>
471
473 template <ESPMode Mode, typename ObjectType, typename... ArgTypes>
478
479
481 // NOTE: The following is an Unreal extension to standard shared_ptr behavior
482 template <class ObjectType>
484 {
486 ObjectType* Object;
487
493
495 explicit UE_FORCEINLINE_HINT TRawPtrProxy( ObjectType* InObject )
496 : Object( InObject )
497 {
498 }
499 };
500
501
503 // NOTE: The following is an Unreal extension to standard shared_ptr behavior
504 template <class ObjectType, typename DeleterType>
506 {
508 ObjectType* Object;
509
511 DeleterType Deleter;
512
514 inline TRawPtrProxyWithDeleter( ObjectType* InObject, const DeleterType& InDeleter )
515 : Object ( InObject )
516 , Deleter( InObject, InDeleter )
517 {
518 }
519
521 inline TRawPtrProxyWithDeleter( ObjectType* InObject, DeleterType&& InDeleter )
522 : Object ( InObject )
524 {
525 }
526 };
527
528
533 template< ESPMode Mode >
535 {
536 public:
537
540 : ReferenceController( nullptr )
541 { }
542
545 : ReferenceController( InReferenceController )
546 { }
547
550 : ReferenceController( InSharedReference.ReferenceController )
551 {
552 // If the incoming reference had an object associated with it, then go ahead and increment the
553 // shared reference count
554 if( ReferenceController != nullptr )
555 {
556 ReferenceController->AddSharedReference();
557 }
558 }
559
562 : ReferenceController( InSharedReference.ReferenceController )
563 {
564 InSharedReference.ReferenceController = nullptr;
565 }
566
570 : ReferenceController(InWeakReference.ReferenceController)
571 {
572 // If the incoming reference had an object associated with it, then go ahead and increment the
573 // shared reference count
574 if (ReferenceController != nullptr)
575 {
576 // Attempt to elevate a weak reference to a shared one. For this to work, the object this
577 // weak counter is associated with must already have at least one shared reference. We'll
578 // never revive a pointer that has already expired!
579 if (!ReferenceController->ConditionallyAddSharedReference())
580 {
581 ReferenceController = nullptr;
582 }
583 }
584 }
585
589 : ReferenceController( InWeakReference.ReferenceController )
590 {
591 // If the incoming reference had an object associated with it, then go ahead and increment the
592 // shared reference count
593 if( ReferenceController != nullptr )
594 {
595 // Attempt to elevate a weak reference to a shared one. For this to work, the object this
596 // weak counter is associated with must already have at least one shared reference. We'll
597 // never revive a pointer that has already expired!
598 if( !ReferenceController->ConditionallyAddSharedReference() )
599 {
600 ReferenceController = nullptr;
601 }
602
603 // Tell the reference counter object that we're no longer referencing the object with
604 // this weak pointer
605 InWeakReference.ReferenceController->ReleaseWeakReference();
606 InWeakReference.ReferenceController = nullptr;
607 }
608 }
609
615
619 {
620 // Make sure we're not be reassigned to ourself!
621 auto NewReferenceController = InSharedReference.ReferenceController;
622 if( NewReferenceController != ReferenceController )
623 {
624 // First, add a shared reference to the new object
625 if( NewReferenceController != nullptr )
626 {
627 NewReferenceController->AddSharedReference();
628 }
629
630 // Release shared reference to the old object
631 if( ReferenceController != nullptr )
632 {
633 ReferenceController->ReleaseSharedReference();
634 }
635
636 // Assume ownership of the assigned reference counter
637 ReferenceController = NewReferenceController;
638 }
639
640 return *this;
641 }
642
646 {
647 // Make sure we're not be reassigned to ourself!
648 auto NewReferenceController = InSharedReference.ReferenceController;
649 auto OldReferenceController = ReferenceController;
651 {
652 // Assume ownership of the assigned reference counter
653 InSharedReference.ReferenceController = nullptr;
654 ReferenceController = NewReferenceController;
655
656 // Release shared reference to the old object
657 if( OldReferenceController != nullptr )
658 {
659 OldReferenceController->ReleaseSharedReference();
660 }
661 }
662
663 return *this;
664 }
665
671 UE_FORCEINLINE_HINT const bool IsValid() const
672 {
673 return ReferenceController != nullptr;
674 }
675
682 {
683 return ReferenceController != nullptr ? ReferenceController->GetSharedReferenceCount() : 0;
684 }
685
692 UE_FORCEINLINE_HINT const bool IsUnique() const
693 {
694 return ReferenceController != nullptr && ReferenceController->IsUnique();
695 }
696
697 private:
698
699 // Expose access to ReferenceController to FWeakReferencer
700 template< ESPMode OtherMode > friend class FWeakReferencer;
701
702 private:
703
705 TReferenceControllerBase<Mode>* ReferenceController;
706 };
707
708
713 template< ESPMode Mode >
715 {
716 public:
717
720 : ReferenceController( nullptr )
721 { }
722
725 : ReferenceController( InWeakRefCountPointer.ReferenceController )
726 {
727 // If the weak referencer has a valid controller, then go ahead and add a weak reference to it!
728 if( ReferenceController != nullptr )
729 {
730 ReferenceController->AddWeakReference();
731 }
732 }
733
736 : ReferenceController( InWeakRefCountPointer.ReferenceController )
737 {
738 InWeakRefCountPointer.ReferenceController = nullptr;
739 }
740
743 : ReferenceController( InSharedRefCountPointer.ReferenceController )
744 {
745 // If the shared referencer had a valid controller, then go ahead and add a weak reference to it!
746 if( ReferenceController != nullptr )
747 {
748 ReferenceController->AddWeakReference();
749 }
750 }
751
754 {
755 if( ReferenceController != nullptr )
756 {
757 // Tell the reference counter object that we're no longer referencing the object with
758 // this weak pointer
759 ReferenceController->ReleaseWeakReference();
760 }
761 }
762
766 {
767 AssignReferenceController( InWeakReference.ReferenceController );
768
769 return *this;
770 }
771
775 {
776 auto OldReferenceController = ReferenceController;
777 ReferenceController = InWeakReference.ReferenceController;
778 InWeakReference.ReferenceController = nullptr;
779 if( OldReferenceController != nullptr )
780 {
781 OldReferenceController->ReleaseWeakReference();
782 }
783
784 return *this;
785 }
786
790 {
791 AssignReferenceController( InSharedReference.ReferenceController );
792
793 return *this;
794 }
795
801 UE_FORCEINLINE_HINT const bool IsValid() const
802 {
803 return ReferenceController != nullptr && ReferenceController->GetSharedReferenceCount() > 0;
804 }
805
806 private:
807
810 inline void AssignReferenceController( TReferenceControllerBase<Mode>* NewReferenceController )
811 {
812 // Only proceed if the new reference counter is different than our current
813 if( NewReferenceController != ReferenceController )
814 {
815 // First, add a weak reference to the new object
816 if( NewReferenceController != nullptr )
817 {
818 NewReferenceController->AddWeakReference();
819 }
820
821 // Release weak reference to the old object
822 if( ReferenceController != nullptr )
823 {
824 ReferenceController->ReleaseWeakReference();
825 }
826
827 // Assume ownership of the assigned reference counter
828 ReferenceController = NewReferenceController;
829 }
830 }
831
832 private:
833
835 template< ESPMode OtherMode > friend class FSharedReferencer;
836
837 private:
838
840 TReferenceControllerBase<Mode>* ReferenceController;
841 };
842}
843
844
845namespace UE::Core::Private
846{
847 // This base class only exists to implement IsDerivedFromSharedFromThis
848 struct FSharedFromThisBase
849 {
850 };
851}
852
853template <typename T>
855{
856 return std::is_base_of_v<UE::Core::Private::FSharedFromThisBase, T>;
857}
858
859
861{
863 template< class SharedPtrType, class ObjectType >
864 inline void EnableSharedFromThis( SharedPtrType* InSharedPtrOrRef, ObjectType const* InObject )
865 {
867 // If you get an 'ambiguous call' compile error in this function, it means you have multiple //
868 // TSharedFromThis bases in your inheritance hierarchy. This is not supported. //
870
872 {
873 if( InObject != nullptr )
874 {
875 InObject->UpdateWeakReferenceInternal( InSharedPtrOrRef, const_cast< ObjectType* >( InObject ) );
876 }
877 }
878 }
879}
#define FORCENOINLINE
Definition AndroidPlatform.h:142
#define checkSlow(expr)
Definition AssertionMacros.h:332
FPlatformTypes::TYPE_OF_NULLPTR TYPE_OF_NULLPTR
The type of the C++ nullptr keyword.
Definition Platform.h:1157
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
AUTORTFM_INFER UE_FORCEINLINE_HINT constexpr auto Invoke(FuncType &&Func, ArgTypes &&... Args) -> decltype(((FuncType &&) Func)((ArgTypes &&) Args...))
Definition Invoke.h:44
FORCEINLINE constexpr void DestructItem(ElementType *Element)
Definition MemoryOps.h:56
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
ESPMode
Definition SharedPointerFwd.h:12
constexpr bool IsDerivedFromSharedFromThis()
Definition SharedPointerInternals.h:854
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
Definition SharedPointerInternals.h:535
FSharedReferencer(FSharedReferencer const &InSharedReference)
Definition SharedPointerInternals.h:549
FSharedReferencer & operator=(FSharedReferencer &&InSharedReference)
Definition SharedPointerInternals.h:645
UE_FORCEINLINE_HINT FSharedReferencer()
Definition SharedPointerInternals.h:539
FSharedReferencer(FWeakReferencer< Mode > &&InWeakReference)
Definition SharedPointerInternals.h:588
UE_FORCEINLINE_HINT const int32 GetSharedReferenceCount() const
Definition SharedPointerInternals.h:681
UE_FORCEINLINE_HINT const bool IsUnique() const
Definition SharedPointerInternals.h:692
FSharedReferencer & operator=(FSharedReferencer const &InSharedReference)
Definition SharedPointerInternals.h:618
UE_FORCEINLINE_HINT const bool IsValid() const
Definition SharedPointerInternals.h:671
FSharedReferencer(FWeakReferencer< Mode > const &InWeakReference)
Definition SharedPointerInternals.h:569
~FSharedReferencer()
Definition SharedPointerInternals.h:611
FSharedReferencer(TReferenceControllerBase< Mode > *InReferenceController)
Definition SharedPointerInternals.h:544
FSharedReferencer(FSharedReferencer &&InSharedReference)
Definition SharedPointerInternals.h:561
Definition SharedPointerInternals.h:715
FWeakReferencer(FWeakReferencer const &InWeakRefCountPointer)
Definition SharedPointerInternals.h:724
FWeakReferencer & operator=(FSharedReferencer< Mode > const &InSharedReference)
Definition SharedPointerInternals.h:789
UE_FORCEINLINE_HINT const bool IsValid() const
Definition SharedPointerInternals.h:801
~FWeakReferencer()
Definition SharedPointerInternals.h:753
FWeakReferencer(FSharedReferencer< Mode > const &InSharedRefCountPointer)
Definition SharedPointerInternals.h:742
FWeakReferencer & operator=(FWeakReferencer const &InWeakReference)
Definition SharedPointerInternals.h:765
FWeakReferencer(FWeakReferencer &&InWeakRefCountPointer)
Definition SharedPointerInternals.h:735
FWeakReferencer & operator=(FWeakReferencer &&InWeakReference)
Definition SharedPointerInternals.h:774
UE_FORCEINLINE_HINT FWeakReferencer()
Definition SharedPointerInternals.h:719
Definition SharedPointerInternals.h:400
TIntrusiveReferenceController & operator=(const TIntrusiveReferenceController &)=delete
ObjectType * GetObjectPtr() const
Definition SharedPointerInternals.h:428
TIntrusiveReferenceController(ArgTypes &&... Args)
Definition SharedPointerInternals.h:403
TIntrusiveReferenceController(const TIntrusiveReferenceController &)=delete
virtual void DestroyObject() override
Definition SharedPointerInternals.h:433
Definition SharedPointerInternals.h:45
void ReleaseWeakReference()
Definition SharedPointerInternals.h:296
static FORCENOINLINE void ReleaseSharedReferenceNoInline(TReferenceControllerBase< Mode > *ReferenceController)
Definition SharedPointerInternals.h:252
void AddWeakReference()
Definition SharedPointerInternals.h:263
void ReleaseSharedReference()
Definition SharedPointerInternals.h:212
void AddSharedReference()
Definition SharedPointerInternals.h:106
bool ConditionallyAddSharedReference()
Definition SharedPointerInternals.h:144
int32 GetSharedReferenceCount() const
Definition SharedPointerInternals.h:73
TReferenceControllerBase(const TReferenceControllerBase &)=delete
RefCountType WeakReferenceCount
Definition SharedPointerInternals.h:63
RefCountType SharedReferenceCount
Definition SharedPointerInternals.h:56
UE_FORCEINLINE_HINT bool IsUnique() const
Definition SharedPointerInternals.h:100
TReferenceControllerBase & operator=(const TReferenceControllerBase &)=delete
virtual ~TReferenceControllerBase()
Definition SharedPointerInternals.h:68
UE_FORCEINLINE_HINT TReferenceControllerBase()=default
Definition SharedPointerInternals.h:376
virtual void DestroyObject() override
Definition SharedPointerInternals.h:384
TReferenceControllerWithDeleter(ObjectType *InObject, DeleterType &&Deleter)
Definition SharedPointerInternals.h:378
TReferenceControllerWithDeleter & operator=(const TReferenceControllerWithDeleter &)=delete
TReferenceControllerWithDeleter(const TReferenceControllerWithDeleter &)=delete
Definition SharedPointerInternals.h:32
TIntrusiveReferenceController< ObjectType, Mode > * NewIntrusiveReferenceController(ArgTypes &&... Args)
Definition SharedPointerInternals.h:474
TReferenceControllerBase< Mode > * NewCustomReferenceController(ObjectType *Object, DeleterType &&Deleter)
Definition SharedPointerInternals.h:467
void EnableSharedFromThis(SharedPtrType *InSharedPtrOrRef, ObjectType const *InObject)
Definition SharedPointerInternals.h:864
TReferenceControllerBase< Mode > * NewDefaultReferenceController(ObjectType *Object)
Definition SharedPointerInternals.h:460
implementation
Definition PlayInEditorLoadingScope.h:8
@ false
Definition radaudio_common.h:23
Definition SharedPointerInternals.h:451
UE_FORCEINLINE_HINT void operator()(Type *Object) const
Definition SharedPointerInternals.h:452
Definition SharedPointerInternals.h:38
Definition SharedPointerInternals.h:41
Definition SharedPointerInternals.h:37
TDeleterHolder(DeleterType &&Arg)
Definition SharedPointerInternals.h:359
void InvokeDeleter(ObjectType *Object)
Definition SharedPointerInternals.h:365
Definition SharedPointerInternals.h:343
void InvokeDeleter(ObjectType *Object)
Definition SharedPointerInternals.h:350
TDeleterHolder(DeleterType &&Arg)
Definition SharedPointerInternals.h:344
Definition SharedPointerInternals.h:506
TRawPtrProxyWithDeleter(ObjectType *InObject, DeleterType &&InDeleter)
Definition SharedPointerInternals.h:521
DeleterType Deleter
Definition SharedPointerInternals.h:511
TRawPtrProxyWithDeleter(ObjectType *InObject, const DeleterType &InDeleter)
Definition SharedPointerInternals.h:514
ObjectType * Object
Definition SharedPointerInternals.h:508
Definition SharedPointerInternals.h:484
UE_FORCEINLINE_HINT TRawPtrProxy(TYPE_OF_NULLPTR)
Definition SharedPointerInternals.h:489
ObjectType * Object
Definition SharedPointerInternals.h:486
UE_FORCEINLINE_HINT TRawPtrProxy(ObjectType *InObject)
Definition SharedPointerInternals.h:495
Definition TypeCompatibleBytes.h:24