UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SharedBuffer.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "CoreTypes.h"
7#include "Memory/MemoryFwd.h"
8#include "Memory/MemoryView.h"
10#include "Misc/EnumClassFlags.h"
11#include "Templates/Invoke.h"
12#include "Templates/TypeHash.h"
14
15#include <atomic>
16#include <type_traits>
17
18template <typename T> struct TIsWeakPointerType;
19template <typename T> struct TIsZeroConstructType;
20
22
23namespace UE::SharedBuffer::Private { struct FSharedOps; }
24namespace UE::SharedBuffer::Private { struct FWeakOps; }
25
27
52{
53private:
54 enum class EBufferOwnerFlags : uint8;
56
57protected:
58 FBufferOwner() = default;
59
60 FBufferOwner(const FBufferOwner&) = delete;
62
63 inline FBufferOwner(void* InData, uint64 InSize);
64 virtual ~FBufferOwner();
65
73 virtual void MaterializeBuffer();
74
82 virtual void FreeBuffer() = 0;
83
84 inline void* GetData();
85 inline uint64 GetSize();
86 inline void SetBuffer(void* InData, uint64 InSize);
87
88 inline bool IsOwned() const;
89 inline void SetIsOwned();
90
91 inline bool IsImmutable() const;
92 inline void SetIsImmutable();
93
94 inline void Materialize();
95 inline bool IsMaterialized() const;
96 inline void SetIsMaterialized();
97
98 inline uint32 GetTotalRefCount() const;
99
100private:
101 static constexpr uint32 RefCountMask = 0x3fffffff;
102
103 static constexpr inline uint32 GetTotalRefCount(uint64 RefCountsAndFlags);
104 static constexpr inline uint32 GetSharedRefCount(uint64 RefCountsAndFlags) { return uint32(RefCountsAndFlags >> 0) & RefCountMask; }
105 static constexpr inline uint64 SetSharedRefCount(uint32 RefCount) { return uint64(RefCount) << 0; }
106 static constexpr inline uint32 GetWeakRefCount(uint64 RefCountsAndFlags) { return uint32(RefCountsAndFlags >> 30) & RefCountMask; }
107 static constexpr inline uint64 SetWeakRefCount(uint32 RefCount) { return uint64(RefCount) << 30; }
108 static constexpr inline EBufferOwnerFlags GetFlags(uint64 RefCountsAndFlags) { return EBufferOwnerFlags(RefCountsAndFlags >> 60); }
109 static constexpr inline uint64 SetFlags(EBufferOwnerFlags Flags) { return uint64(Flags) << 60; }
110
112 inline bool IsUniqueOwnedMutable() const;
113
114 inline void AddSharedReference();
115 inline void ReleaseSharedReference();
116 inline bool TryAddSharedReference();
117 inline void AddWeakReference();
118 inline void ReleaseWeakReference();
119
120 friend class FUniqueBuffer;
121 friend class FSharedBuffer;
122 friend class FWeakSharedBuffer;
125
126private:
127 void* Data = nullptr;
128 uint64 Size = 0;
129 std::atomic<uint64> ReferenceCountsAndFlags{0};
130};
131
133
135{
136
137struct FSharedOps final
138{
139 static inline bool HasRef(FBufferOwner& Owner) { return Owner.GetTotalRefCount() > 0; }
140 static inline bool TryAddRef(FBufferOwner& Owner) { return Owner.TryAddSharedReference(); }
141 static inline void AddRef(FBufferOwner& Owner) { Owner.AddSharedReference(); }
142 static inline void Release(FBufferOwner* Owner) { if (Owner) { Owner->ReleaseSharedReference(); } }
143};
144
145struct FWeakOps final
146{
147 static inline bool HasRef(FBufferOwner& Owner) { return Owner.GetTotalRefCount() > 0; }
148 static inline bool TryAddRef(FBufferOwner& Owner) { AddRef(Owner); return true; }
149 static inline void AddRef(FBufferOwner& Owner) { Owner.AddWeakReference(); }
150 static inline void Release(FBufferOwner* Owner) { if (Owner) { Owner->ReleaseWeakReference(); } }
151};
152
153template <typename FOps>
154class TBufferOwnerPtr final
155{
156 static constexpr bool bIsWeak = std::is_same<FOps, FWeakOps>::value;
157
158 template <typename FOtherOps>
159 friend class TBufferOwnerPtr;
160
161 template <typename FOtherOps>
162 static inline FBufferOwner* CopyFrom(const TBufferOwnerPtr<FOtherOps>& Ptr);
163
164 template <typename FOtherOps>
165 static inline FBufferOwner* MoveFrom(TBufferOwnerPtr<FOtherOps>&& Ptr);
166
167public:
168 inline TBufferOwnerPtr() = default;
169 inline explicit TBufferOwnerPtr(FBufferOwner* const InOwner);
170
171 inline TBufferOwnerPtr(const TBufferOwnerPtr& Ptr);
172 inline TBufferOwnerPtr(TBufferOwnerPtr&& Ptr);
173
174 template <typename FOtherOps>
175 inline explicit TBufferOwnerPtr(const TBufferOwnerPtr<FOtherOps>& Ptr);
176 template <typename FOtherOps>
177 inline explicit TBufferOwnerPtr(TBufferOwnerPtr<FOtherOps>&& Ptr);
178
179 inline ~TBufferOwnerPtr();
180
181 inline TBufferOwnerPtr& operator=(const TBufferOwnerPtr& Ptr);
182 inline TBufferOwnerPtr& operator=(TBufferOwnerPtr&& Ptr);
183
184 template <typename FOtherOps>
185 inline TBufferOwnerPtr& operator=(const TBufferOwnerPtr<FOtherOps>& Ptr);
186 template <typename FOtherOps>
187 inline TBufferOwnerPtr& operator=(TBufferOwnerPtr<FOtherOps>&& Ptr);
188
189 template <typename FOtherOps>
190 inline bool operator==(const TBufferOwnerPtr<FOtherOps>& Ptr) const;
191 template <typename FOtherOps>
192 inline bool operator!=(const TBufferOwnerPtr<FOtherOps>& Ptr) const;
193
194 inline FBufferOwner* Get() const { return Owner; }
195 inline FBufferOwner* operator->() const { return Get(); }
196 inline explicit operator bool() const { return !IsNull(); }
197 inline bool IsNull() const { return Owner == nullptr; }
198
199 inline void Reset();
200
201private:
202 FBufferOwner* Owner = nullptr;
203};
204
205} // UE::SharedBuffer::Private
206
208
218{
219public:
224
227 [[nodiscard]] CORE_API static FUniqueBuffer Clone(const void* Data, uint64 Size);
228
231 [[nodiscard]] CORE_API static FUniqueBuffer MakeView(void* Data, uint64 Size);
232
238 template <typename DeleteFunctionType,
239 decltype(Invoke(std::declval<DeleteFunctionType>(), std::declval<void*>()))* = nullptr>
240 [[nodiscard]] static inline FUniqueBuffer TakeOwnership(void* Data, uint64 Size, DeleteFunctionType&& DeleteFunction);
241
247 template <typename DeleteFunctionType,
248 decltype(Invoke(std::declval<DeleteFunctionType>(), std::declval<void*>(), std::declval<uint64>()))* = nullptr>
249 [[nodiscard]] static inline FUniqueBuffer TakeOwnership(void* Data, uint64 Size, DeleteFunctionType&& DeleteFunction);
250
252 FUniqueBuffer() = default;
253
255 CORE_API explicit FUniqueBuffer(FBufferOwner* Owner);
256
259
260 FUniqueBuffer(const FUniqueBuffer&) = delete;
262
264 CORE_API void Reset();
265
267 [[nodiscard]] inline void* GetData() { return Owner ? Owner->GetData() : nullptr; }
268 [[nodiscard]] inline const void* GetData() const { return Owner ? Owner->GetData() : nullptr; }
269
271 [[nodiscard]] inline uint64 GetSize() const { return Owner ? Owner->GetSize() : 0; }
272
275 [[nodiscard]] inline FMemoryView GetView() const { return FMemoryView(GetData(), GetSize()); }
276 [[nodiscard]] inline operator FMutableMemoryView() { return GetView(); }
277 [[nodiscard]] inline operator FMemoryView() const { return GetView(); }
278
280 [[nodiscard]] inline explicit operator bool() const { return !IsNull(); }
281
287 [[nodiscard]] inline bool IsNull() const { return Owner.IsNull(); }
288
290 [[nodiscard]] inline bool IsOwned() const { return !Owner || Owner->IsOwned(); }
291
294
296 [[nodiscard]] inline bool IsMaterialized() const { return !Owner || Owner->IsMaterialized(); }
297
303 CORE_API void Materialize() const;
304
311
312 friend class FSharedBuffer;
313
314private:
315 using FOwnerPtrType = UE::SharedBuffer::Private::TBufferOwnerPtr<UE::SharedBuffer::Private::FSharedOps>;
316
317 explicit FUniqueBuffer(FOwnerPtrType&& SharedOwner);
318
319 inline friend const FOwnerPtrType& ToPrivateOwnerPtr(const FUniqueBuffer& Buffer) { return Buffer.Owner; }
320 inline friend FOwnerPtrType ToPrivateOwnerPtr(FUniqueBuffer&& Buffer) { return MoveTemp(Buffer.Owner); }
321
322 FOwnerPtrType Owner;
323
324public:
326
327 inline bool operator==(const FUniqueBuffer& BufferB) const { return ToPrivateOwnerPtr(*this) == ToPrivateOwnerPtr(BufferB); }
328#if !PLATFORM_COMPILER_HAS_GENERATED_COMPARISON_OPERATORS
329 inline bool operator!=(const FUniqueBuffer& BufferB) const { return ToPrivateOwnerPtr(*this) != ToPrivateOwnerPtr(BufferB); }
330#endif
331};
332
334
341{
342public:
344 [[nodiscard]] CORE_API static FSharedBuffer Clone(FMemoryView View);
345 [[nodiscard]] CORE_API static FSharedBuffer Clone(const void* Data, uint64 Size);
346
348 [[nodiscard]] CORE_API static FSharedBuffer MakeView(FMemoryView View);
349 [[nodiscard]] CORE_API static FSharedBuffer MakeView(const void* Data, uint64 Size);
350
352 [[nodiscard]] CORE_API static FSharedBuffer MakeView(FMemoryView View, FSharedBuffer&& OuterBuffer);
353 [[nodiscard]] CORE_API static FSharedBuffer MakeView(FMemoryView View, const FSharedBuffer& OuterBuffer);
354 [[nodiscard]] CORE_API static FSharedBuffer MakeView(const void* Data, uint64 Size, FSharedBuffer&& OuterBuffer);
355 [[nodiscard]] CORE_API static FSharedBuffer MakeView(const void* Data, uint64 Size, const FSharedBuffer& OuterBuffer);
356
362 template <typename DeleteFunctionType,
363 decltype(Invoke(std::declval<DeleteFunctionType>(), std::declval<void*>()))* = nullptr>
364 [[nodiscard]] static inline FSharedBuffer TakeOwnership(const void* Data, uint64 Size, DeleteFunctionType&& DeleteFunction);
365
371 template <typename DeleteFunctionType,
372 decltype(Invoke(std::declval<DeleteFunctionType>(), std::declval<void*>(), std::declval<uint64>()))* = nullptr>
373 [[nodiscard]] static inline FSharedBuffer TakeOwnership(const void* Data, uint64 Size, DeleteFunctionType&& DeleteFunction);
374
376 FSharedBuffer() = default;
377
380
382 CORE_API void Reset();
383
385 [[nodiscard]] inline const void* GetData() const { return Owner ? Owner->GetData() : nullptr; }
386
388 [[nodiscard]] inline uint64 GetSize() const { return Owner ? Owner->GetSize() : 0; }
389
391 [[nodiscard]] inline FMemoryView GetView() const { return FMemoryView(GetData(), GetSize()); }
392 [[nodiscard]] inline operator FMemoryView() const { return GetView(); }
393
395 [[nodiscard]] inline explicit operator bool() const { return !IsNull(); }
396
402 [[nodiscard]] inline bool IsNull() const { return Owner.IsNull(); }
403
405 [[nodiscard]] inline bool IsOwned() const { return !Owner || Owner->IsOwned(); }
406
408 [[nodiscard]] CORE_API FSharedBuffer MakeOwned() const &;
409 [[nodiscard]] CORE_API FSharedBuffer MakeOwned() &&;
410
412 [[nodiscard]] inline bool IsMaterialized() const { return !Owner || Owner->IsMaterialized(); }
413
419 CORE_API void Materialize() const;
420
427 [[nodiscard]] CORE_API FUniqueBuffer MoveToUnique();
428
429 friend class FUniqueBuffer;
430 friend class FWeakSharedBuffer;
431
432private:
433 using FOwnerPtrType = UE::SharedBuffer::Private::TBufferOwnerPtr<UE::SharedBuffer::Private::FSharedOps>;
434 using FWeakOwnerPtrType = UE::SharedBuffer::Private::TBufferOwnerPtr<UE::SharedBuffer::Private::FWeakOps>;
435
436 explicit FSharedBuffer(FOwnerPtrType&& SharedOwner);
437 explicit FSharedBuffer(const FWeakOwnerPtrType& WeakOwner);
438
439 inline friend const FOwnerPtrType& ToPrivateOwnerPtr(const FSharedBuffer& Buffer) { return Buffer.Owner; }
440 inline friend FOwnerPtrType ToPrivateOwnerPtr(FSharedBuffer&& Buffer) { return MoveTemp(Buffer.Owner); }
441
442 FOwnerPtrType Owner;
443
444public:
445 friend inline uint32 GetTypeHash(const FSharedBuffer& Buffer) { return PointerHash(ToPrivateOwnerPtr(Buffer).Get()); }
446 inline bool operator==(const FSharedBuffer& BufferB) const { return ToPrivateOwnerPtr(*this) == ToPrivateOwnerPtr(BufferB); }
447 friend inline bool operator==(const FSharedBuffer& BufferA, const FUniqueBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) == ToPrivateOwnerPtr(BufferB); }
448
449#if !PLATFORM_COMPILER_HAS_GENERATED_COMPARISON_OPERATORS
450 inline bool operator!=(const FSharedBuffer& BufferB) const { return ToPrivateOwnerPtr(*this) != ToPrivateOwnerPtr(BufferB); }
451 friend inline bool operator!=(const FSharedBuffer& BufferA, const FUniqueBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) != ToPrivateOwnerPtr(BufferB); }
452 friend inline bool operator==(const FUniqueBuffer& BufferA, const FSharedBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) == ToPrivateOwnerPtr(BufferB); }
453 friend inline bool operator!=(const FUniqueBuffer& BufferA, const FSharedBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) != ToPrivateOwnerPtr(BufferB); }
454#endif
455};
456
458
465{
466public:
468 FWeakSharedBuffer() = default;
469
472
475
477 CORE_API void Reset();
478
480 [[nodiscard]] CORE_API FSharedBuffer Pin() const;
481
482private:
483 using FWeakOwnerPtrType = UE::SharedBuffer::Private::TBufferOwnerPtr<UE::SharedBuffer::Private::FWeakOps>;
484
485 inline friend const FWeakOwnerPtrType& ToPrivateOwnerPtr(const FWeakSharedBuffer& Buffer) { return Buffer.Owner; }
486
487 FWeakOwnerPtrType Owner;
488
489public:
490 friend inline uint32 GetTypeHash(const FWeakSharedBuffer& Buffer) { return PointerHash(ToPrivateOwnerPtr(Buffer).Get()); }
491 inline bool operator==(const FWeakSharedBuffer& BufferB) const { return ToPrivateOwnerPtr(*this) == ToPrivateOwnerPtr(BufferB); }
492 friend inline bool operator==(const FWeakSharedBuffer& BufferA, const FUniqueBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) == ToPrivateOwnerPtr(BufferB); }
493 friend inline bool operator==(const FWeakSharedBuffer& BufferA, const FSharedBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) == ToPrivateOwnerPtr(BufferB); }
494
495#if !PLATFORM_COMPILER_HAS_GENERATED_COMPARISON_OPERATORS
496 friend inline bool operator==(const FUniqueBuffer& BufferA, const FWeakSharedBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) == ToPrivateOwnerPtr(BufferB); }
497 friend inline bool operator==(const FSharedBuffer& BufferA, const FWeakSharedBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) == ToPrivateOwnerPtr(BufferB); }
498
499 inline bool operator!=(const FWeakSharedBuffer& BufferB) const { return ToPrivateOwnerPtr(*this) != ToPrivateOwnerPtr(BufferB); }
500 friend inline bool operator!=(const FWeakSharedBuffer& BufferA, const FUniqueBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) != ToPrivateOwnerPtr(BufferB); }
501 friend inline bool operator!=(const FUniqueBuffer& BufferA, const FWeakSharedBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) != ToPrivateOwnerPtr(BufferB); }
502 friend inline bool operator!=(const FWeakSharedBuffer& BufferA, const FSharedBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) != ToPrivateOwnerPtr(BufferB); }
503 friend inline bool operator!=(const FSharedBuffer& BufferA, const FWeakSharedBuffer& BufferB) { return ToPrivateOwnerPtr(BufferA) != ToPrivateOwnerPtr(BufferB); }
504#endif
505};
506
508
509template<> struct TIsZeroConstructType<FUniqueBuffer> { enum { Value = true }; };
510template<> struct TIsZeroConstructType<FSharedBuffer> { enum { Value = true }; };
511template<> struct TIsZeroConstructType<FWeakSharedBuffer> { enum { Value = true }; };
512
513template<> struct TIsWeakPointerType<FWeakSharedBuffer> { enum { Value = true }; };
514
516
518{
519
520template <typename DeleteFunctionType>
522{
523public:
525 : FBufferOwner(Data, Size)
527 {
528 SetIsMaterialized();
529 SetIsOwned();
530 }
531
537
538private:
539 virtual void FreeBuffer() final
540 {
541 Invoke(DeleteFunction, GetData(), GetSize());
542 }
543
544 std::decay_t<DeleteFunctionType> DeleteFunction;
545};
546
547} // UE::SharedBuffer::Private
548
549template <typename DeleteFunctionType,
550 decltype(Invoke(std::declval<DeleteFunctionType>(), std::declval<void*>()))*>
552{
553 return TakeOwnership(Data, Size, [Delete = Forward<DeleteFunctionType>(DeleteFunction)](void* InData, uint64 InSize)
554 {
556 });
557}
558
559template <typename DeleteFunctionType,
560 decltype(Invoke(std::declval<DeleteFunctionType>(), std::declval<void*>(), std::declval<uint64>()))*>
561inline FUniqueBuffer FUniqueBuffer::TakeOwnership(void* Data, uint64 Size, DeleteFunctionType&& DeleteFunction)
562{
564 return FUniqueBuffer(new OwnerType(Data, Size, Forward<DeleteFunctionType>(DeleteFunction)));
565}
566
567template <typename DeleteFunctionType,
568 decltype(Invoke(std::declval<DeleteFunctionType>(), std::declval<void*>()))*>
570{
571 return TakeOwnership(Data, Size, [Delete = Forward<DeleteFunctionType>(DeleteFunction)](void* InData, uint64 InSize)
572 {
574 });
575}
576
577template <typename DeleteFunctionType,
578 decltype(Invoke(std::declval<DeleteFunctionType>(), std::declval<void*>(), std::declval<uint64>()))*>
579inline FSharedBuffer FSharedBuffer::TakeOwnership(const void* Data, uint64 Size, DeleteFunctionType&& DeleteFunction)
580{
582 return FSharedBuffer(new OwnerType(Data, Size, Forward<DeleteFunctionType>(DeleteFunction)));
583}
584
586
588{
589 None = 0,
590 Owned = 1 << 0,
591 Immutable = 1 << 1,
592 Materialized = 1 << 2,
593};
594
596
598 : Data(InData)
599 , Size(InSize)
600{
601}
602
607
612
614{
615 Materialize();
616 return Data;
617}
618
620{
621 Materialize();
622 return Size;
623}
624
626{
627 Data = InData;
628 Size = InSize;
629}
630
631inline bool FBufferOwner::IsOwned() const
632{
633 return EnumHasAnyFlags(GetFlags(ReferenceCountsAndFlags.load(std::memory_order_relaxed)), EBufferOwnerFlags::Owned);
634}
635
637{
638 ReferenceCountsAndFlags.fetch_or(SetFlags(EBufferOwnerFlags::Owned), std::memory_order_relaxed);
639}
640
641inline bool FBufferOwner::IsImmutable() const
642{
643 return EnumHasAnyFlags(GetFlags(ReferenceCountsAndFlags.load(std::memory_order_relaxed)), EBufferOwnerFlags::Immutable);
644}
645
647{
648 ReferenceCountsAndFlags.fetch_or(SetFlags(EBufferOwnerFlags::Immutable), std::memory_order_relaxed);
649}
650
652{
653 if (!IsMaterialized())
654 {
657 }
658}
659
661{
662 return EnumHasAnyFlags(GetFlags(ReferenceCountsAndFlags.load(std::memory_order_acquire)), EBufferOwnerFlags::Materialized);
663}
664
666{
667 ReferenceCountsAndFlags.fetch_or(SetFlags(EBufferOwnerFlags::Materialized), std::memory_order_release);
668}
669
671{
672 return GetTotalRefCount(ReferenceCountsAndFlags.load(std::memory_order_relaxed));
673}
674
676{
677 const uint32 SharedRefCount = GetSharedRefCount(RefCountsAndFlags);
678 // A non-zero SharedRefCount adds 1 to WeakRefCount to keep the owner alive.
679 // Subtract that extra reference when it is present to return an accurate count.
680 return GetWeakRefCount(RefCountsAndFlags) + SharedRefCount - !!SharedRefCount;
681}
682
683inline bool FBufferOwner::IsUniqueOwnedMutable() const
684{
685 const uint64 RefCountsAndFlags = ReferenceCountsAndFlags.load(std::memory_order_relaxed);
686 return GetTotalRefCount(RefCountsAndFlags) == 1 &&
688}
689
690inline void FBufferOwner::AddSharedReference()
691{
692 const uint64 PreviousValue = ReferenceCountsAndFlags.fetch_add(SetSharedRefCount(1), std::memory_order_relaxed);
693 checkSlow(GetSharedRefCount(PreviousValue) < RefCountMask);
694 if (GetSharedRefCount(PreviousValue) == 0)
695 {
696 AddWeakReference();
697 }
698}
699
700inline void FBufferOwner::ReleaseSharedReference()
701{
702 const uint64 PreviousValue = ReferenceCountsAndFlags.fetch_sub(SetSharedRefCount(1), std::memory_order_acq_rel);
703 checkSlow(GetSharedRefCount(PreviousValue) > 0);
704 if (GetSharedRefCount(PreviousValue) == 1)
705 {
706 FreeBuffer();
707 Data = nullptr;
708 Size = 0;
709 ReleaseWeakReference();
710 }
711}
712
713inline bool FBufferOwner::TryAddSharedReference()
714{
715 for (uint64 Value = ReferenceCountsAndFlags.load(std::memory_order_relaxed);;)
716 {
717 if (GetSharedRefCount(Value) == 0)
718 {
719 return false;
720 }
721 if (ReferenceCountsAndFlags.compare_exchange_weak(Value, Value + SetSharedRefCount(1),
722 std::memory_order_relaxed, std::memory_order_relaxed))
723 {
724 return true;
725 }
726 }
727}
728
729inline void FBufferOwner::AddWeakReference()
730{
731 const uint64 PreviousValue = ReferenceCountsAndFlags.fetch_add(SetWeakRefCount(1), std::memory_order_relaxed);
732 checkSlow(GetWeakRefCount(PreviousValue) < RefCountMask);
733}
734
735inline void FBufferOwner::ReleaseWeakReference()
736{
737 const uint64 PreviousValue = ReferenceCountsAndFlags.fetch_sub(SetWeakRefCount(1), std::memory_order_acq_rel);
738 checkSlow(GetWeakRefCount(PreviousValue) > 0);
739 if (GetWeakRefCount(PreviousValue) == 1)
740 {
741 delete this;
742 }
743}
744
746
748{
749
750template <typename FOps>
751template <typename FOtherOps>
752inline FBufferOwner* TBufferOwnerPtr<FOps>::CopyFrom(const TBufferOwnerPtr<FOtherOps>& Ptr)
753{
754 FBufferOwner* NewOwner = Ptr.Owner;
755 if (NewOwner)
756 {
757 if constexpr (bIsWeak || !TBufferOwnerPtr<FOtherOps>::bIsWeak)
758 {
759 FOps::AddRef(*NewOwner);
760 }
761 else if (!FOps::TryAddRef(*NewOwner))
762 {
763 NewOwner = nullptr;
764 }
765 }
766 return NewOwner;
767}
768
769template <typename FOps>
770template <typename FOtherOps>
771inline FBufferOwner* TBufferOwnerPtr<FOps>::MoveFrom(TBufferOwnerPtr<FOtherOps>&& Ptr)
772{
773 FBufferOwner* NewOwner = Ptr.Owner;
774 if constexpr (bIsWeak == TBufferOwnerPtr<FOtherOps>::bIsWeak)
775 {
776 Ptr.Owner = nullptr;
777 }
778 else if (NewOwner)
779 {
780 if constexpr (bIsWeak)
781 {
782 FOps::AddRef(*NewOwner);
783 }
784 else if (!FOps::TryAddRef(*NewOwner))
785 {
786 NewOwner = nullptr;
787 }
788 }
789 return NewOwner;
790}
791
792template <typename FOps>
793inline TBufferOwnerPtr<FOps>::TBufferOwnerPtr(const TBufferOwnerPtr& Ptr)
794 : Owner(CopyFrom(Ptr))
795{
796}
797
798template <typename FOps>
799inline TBufferOwnerPtr<FOps>::TBufferOwnerPtr(TBufferOwnerPtr&& Ptr)
800 : Owner(MoveFrom(MoveTemp(Ptr)))
801{
802}
803
804template <typename FOps>
805template <typename FOtherOps>
806inline TBufferOwnerPtr<FOps>::TBufferOwnerPtr(const TBufferOwnerPtr<FOtherOps>& Ptr)
807 : Owner(CopyFrom(Ptr))
808{
809}
810
811template <typename FOps>
812template <typename FOtherOps>
813inline TBufferOwnerPtr<FOps>::TBufferOwnerPtr(TBufferOwnerPtr<FOtherOps>&& Ptr)
814 : Owner(MoveFrom(MoveTemp(Ptr)))
815{
816}
817
818template <typename FOps>
819inline TBufferOwnerPtr<FOps>::~TBufferOwnerPtr()
820{
821 FOps::Release(Owner);
822}
823
824template <typename FOps>
825inline TBufferOwnerPtr<FOps>& TBufferOwnerPtr<FOps>::operator=(const TBufferOwnerPtr& Ptr)
826{
827 FBufferOwner* const OldOwner = Owner;
828 Owner = CopyFrom(Ptr);
829 FOps::Release(OldOwner);
830 return *this;
831}
832
833template <typename FOps>
834inline TBufferOwnerPtr<FOps>& TBufferOwnerPtr<FOps>::operator=(TBufferOwnerPtr&& Ptr)
835{
836 FBufferOwner* const OldOwner = Owner;
837 Owner = MoveFrom(MoveTemp(Ptr));
838 FOps::Release(OldOwner);
839 return *this;
840}
841
842template <typename FOps>
843template <typename FOtherOps>
844inline TBufferOwnerPtr<FOps>& TBufferOwnerPtr<FOps>::operator=(const TBufferOwnerPtr<FOtherOps>& Ptr)
845{
846 FBufferOwner* const OldOwner = Owner;
847 Owner = CopyFrom(Ptr);
848 FOps::Release(OldOwner);
849 return *this;
850}
851
852template <typename FOps>
853template <typename FOtherOps>
854inline TBufferOwnerPtr<FOps>& TBufferOwnerPtr<FOps>::operator=(TBufferOwnerPtr<FOtherOps>&& Ptr)
855{
856 FBufferOwner* const OldOwner = Owner;
857 Owner = MoveFrom(MoveTemp(Ptr));
858 FOps::Release(OldOwner);
859 return *this;
860}
861
862template <typename FOps>
863template <typename FOtherOps>
864inline bool TBufferOwnerPtr<FOps>::operator==(const TBufferOwnerPtr<FOtherOps>& Ptr) const
865{
866 return Owner == Ptr.Owner;
867}
868
869template <typename FOps>
870template <typename FOtherOps>
871inline bool TBufferOwnerPtr<FOps>::operator!=(const TBufferOwnerPtr<FOtherOps>& Ptr) const
872{
873 return Owner != Ptr.Owner;
874}
875
876} // UE::SharedBuffer::Private
877
879
881{
882
883template <typename T, typename Allocator>
885{
886public:
889 {
890 SetBuffer(Array.GetData(), uint64(Array.Num()) * sizeof(T));
891 SetIsMaterialized();
892 SetIsOwned();
893 }
894
895private:
896 virtual void FreeBuffer() final
897 {
898 Array.Empty();
899 }
900
902};
903
904} // UE::SharedBuffer::Private
905
907template <typename T, typename Allocator>
912
914template <typename T, typename Allocator>
919
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define checkSlow(expr)
Definition AssertionMacros.h:332
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
FSharedBuffer MakeSharedBufferFromArray(TArray< T, Allocator > &&Array)
Definition SharedBuffer.h:915
FUniqueBuffer MakeUniqueBufferFromArray(TArray< T, Allocator > &&Array)
Definition SharedBuffer.h:908
AUTORTFM_INFER UE_FORCEINLINE_HINT constexpr auto Invoke(FuncType &&Func, ArgTypes &&... Args) -> decltype(((FuncType &&) Func)((ArgTypes &&) Args...))
Definition Invoke.h:44
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
constexpr bool EnumHasAnyFlags(Enum Flags, Enum Contains)
Definition EnumClassFlags.h:35
#define FRIEND_ENUM_CLASS_FLAGS(Enum)
Definition EnumClassFlags.h:17
#define ENUM_CLASS_FLAGS(Enum)
Definition EnumClassFlags.h:6
UE_FORCEINLINE_HINT bool operator!=(const FIndexedPointer &Other) const
Definition LockFreeList.h:76
TMemoryView< const void > FMemoryView
Definition MemoryFwd.h:11
TMemoryView< void > FMutableMemoryView
Definition MemoryFwd.h:14
const bool
Definition NetworkReplayStreaming.h:178
auto GetData(const TStringConversion< Converter, DefaultConversionSize > &Conversion) -> decltype(Conversion.Get())
Definition StringConv.h:802
uint32 PointerHash(const void *Key)
Definition TypeHash.h:91
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition SharedBuffer.h:52
void SetBuffer(void *InData, uint64 InSize)
Definition SharedBuffer.h:625
bool IsImmutable() const
Definition SharedBuffer.h:641
EBufferOwnerFlags
Definition SharedBuffer.h:588
void SetIsOwned()
Definition SharedBuffer.h:636
FBufferOwner()=default
void Materialize()
Definition SharedBuffer.h:651
void * GetData()
Definition SharedBuffer.h:613
virtual void FreeBuffer()=0
bool IsMaterialized() const
Definition SharedBuffer.h:660
bool IsOwned() const
Definition SharedBuffer.h:631
uint64 GetSize()
Definition SharedBuffer.h:619
friend struct UE::SharedBuffer::Private::FSharedOps
Definition SharedBuffer.h:123
void SetIsImmutable()
Definition SharedBuffer.h:646
virtual ~FBufferOwner()
Definition SharedBuffer.h:603
friend struct UE::SharedBuffer::Private::FWeakOps
Definition SharedBuffer.h:124
FBufferOwner & operator=(const FBufferOwner &)=delete
virtual void MaterializeBuffer()
Definition SharedBuffer.h:608
void SetIsMaterialized()
Definition SharedBuffer.h:665
FBufferOwner(const FBufferOwner &)=delete
uint32 GetTotalRefCount() const
Definition SharedBuffer.h:670
Definition SharedBuffer.h:341
friend FOwnerPtrType ToPrivateOwnerPtr(FSharedBuffer &&Buffer)
Definition SharedBuffer.h:440
FMemoryView GetView() const
Definition SharedBuffer.h:391
friend class FWeakSharedBuffer
Definition SharedBuffer.h:430
bool IsOwned() const
Definition SharedBuffer.h:405
bool IsMaterialized() const
Definition SharedBuffer.h:412
friend class FUniqueBuffer
Definition SharedBuffer.h:429
static FSharedBuffer TakeOwnership(const void *Data, uint64 Size, DeleteFunctionType &&DeleteFunction)
friend const FOwnerPtrType & ToPrivateOwnerPtr(const FSharedBuffer &Buffer)
Definition SharedBuffer.h:439
friend uint32 GetTypeHash(const FSharedBuffer &Buffer)
Definition SharedBuffer.h:445
FSharedBuffer()=default
uint64 GetSize() const
Definition SharedBuffer.h:388
const void * GetData() const
Definition SharedBuffer.h:385
friend bool operator==(const FSharedBuffer &BufferA, const FUniqueBuffer &BufferB)
Definition SharedBuffer.h:447
bool operator!=(const FSharedBuffer &BufferB) const
Definition SharedBuffer.h:450
friend bool operator!=(const FSharedBuffer &BufferA, const FUniqueBuffer &BufferB)
Definition SharedBuffer.h:451
static FSharedBuffer TakeOwnership(const void *Data, uint64 Size, DeleteFunctionType &&DeleteFunction)
Definition SharedBuffer.h:569
friend bool operator==(const FUniqueBuffer &BufferA, const FSharedBuffer &BufferB)
Definition SharedBuffer.h:452
bool operator==(const FSharedBuffer &BufferB) const
Definition SharedBuffer.h:446
bool IsNull() const
Definition SharedBuffer.h:402
friend bool operator!=(const FUniqueBuffer &BufferA, const FSharedBuffer &BufferB)
Definition SharedBuffer.h:453
Definition SharedBuffer.h:218
FUniqueBuffer & operator=(FUniqueBuffer &&)=default
static CORE_API FUniqueBuffer Alloc(uint64 Size)
Definition SharedBuffer.cpp:103
CORE_API FUniqueBuffer MakeOwned() &&
Definition SharedBuffer.cpp:152
FUniqueBuffer(const FUniqueBuffer &)=delete
const void * GetData() const
Definition SharedBuffer.h:268
FMemoryView GetView() const
Definition SharedBuffer.h:275
CORE_API FSharedBuffer MoveToShared()
Definition SharedBuffer.cpp:165
static FUniqueBuffer TakeOwnership(void *Data, uint64 Size, DeleteFunctionType &&DeleteFunction)
Definition SharedBuffer.h:551
FUniqueBuffer(FUniqueBuffer &&)=default
friend class FSharedBuffer
Definition SharedBuffer.h:312
static FUniqueBuffer TakeOwnership(void *Data, uint64 Size, DeleteFunctionType &&DeleteFunction)
FUniqueBuffer()=default
bool operator==(const FUniqueBuffer &BufferB) const
Definition SharedBuffer.h:327
static CORE_API FUniqueBuffer Clone(FMemoryView View)
Definition SharedBuffer.cpp:115
bool IsNull() const
Definition SharedBuffer.h:287
CORE_API void Materialize() const
Definition SharedBuffer.cpp:157
friend FOwnerPtrType ToPrivateOwnerPtr(FUniqueBuffer &&Buffer)
Definition SharedBuffer.h:320
CORE_API void Reset()
Definition SharedBuffer.cpp:147
static CORE_API FUniqueBuffer MakeView(FMutableMemoryView View)
Definition SharedBuffer.cpp:127
friend uint32 GetTypeHash(const FUniqueBuffer &Buffer)
Definition SharedBuffer.h:325
FUniqueBuffer & operator=(const FUniqueBuffer &)=delete
void * GetData()
Definition SharedBuffer.h:267
uint64 GetSize() const
Definition SharedBuffer.h:271
FMutableMemoryView GetView()
Definition SharedBuffer.h:274
bool IsMaterialized() const
Definition SharedBuffer.h:296
bool operator!=(const FUniqueBuffer &BufferB) const
Definition SharedBuffer.h:329
friend const FOwnerPtrType & ToPrivateOwnerPtr(const FUniqueBuffer &Buffer)
Definition SharedBuffer.h:319
bool IsOwned() const
Definition SharedBuffer.h:290
static CORE_API FUniqueBuffer AllocZeroed(uint64 Size)
Definition SharedBuffer.cpp:108
Definition SharedBuffer.h:465
friend bool operator!=(const FWeakSharedBuffer &BufferA, const FSharedBuffer &BufferB)
Definition SharedBuffer.h:502
bool operator!=(const FWeakSharedBuffer &BufferB) const
Definition SharedBuffer.h:499
friend bool operator!=(const FUniqueBuffer &BufferA, const FWeakSharedBuffer &BufferB)
Definition SharedBuffer.h:501
friend bool operator!=(const FSharedBuffer &BufferA, const FWeakSharedBuffer &BufferB)
Definition SharedBuffer.h:503
bool operator==(const FWeakSharedBuffer &BufferB) const
Definition SharedBuffer.h:491
friend bool operator==(const FSharedBuffer &BufferA, const FWeakSharedBuffer &BufferB)
Definition SharedBuffer.h:497
FWeakSharedBuffer()=default
friend bool operator==(const FWeakSharedBuffer &BufferA, const FUniqueBuffer &BufferB)
Definition SharedBuffer.h:492
friend bool operator==(const FWeakSharedBuffer &BufferA, const FSharedBuffer &BufferB)
Definition SharedBuffer.h:493
friend bool operator!=(const FWeakSharedBuffer &BufferA, const FUniqueBuffer &BufferB)
Definition SharedBuffer.h:500
friend const FWeakOwnerPtrType & ToPrivateOwnerPtr(const FWeakSharedBuffer &Buffer)
Definition SharedBuffer.h:485
friend uint32 GetTypeHash(const FWeakSharedBuffer &Buffer)
Definition SharedBuffer.h:490
friend bool operator==(const FUniqueBuffer &BufferA, const FWeakSharedBuffer &BufferB)
Definition SharedBuffer.h:496
Definition Array.h:670
TBufferOwnerDeleteFunction(void *Data, uint64 Size, DeleteFunctionType &&InDeleteFunction)
Definition SharedBuffer.h:524
TBufferOwnerDeleteFunction(const void *Data, uint64 Size, DeleteFunctionType &&InDeleteFunction)
Definition SharedBuffer.h:532
TBufferOwnerTArray(TArray< T, Allocator > &&InArray)
Definition SharedBuffer.h:887
GeometryCollection::Facades::FMuscleActivationData Data
Definition MuscleActivationConstraints.h:15
FORCEINLINE T * Get(const FObjectPtr &ObjectPtr)
Definition ObjectPtr.h:426
bool operator==(const FCachedAssetKey &A, const FCachedAssetKey &B)
Definition AssetDataMap.h:501
Definition SharedBuffer.cpp:11
Definition UnrealTypeTraits.h:181
Definition UnrealTypeTraits.h:172