Compare commits
4 Commits
10b8e0fc45
...
c38714220e
Author | SHA1 | Date | |
---|---|---|---|
c38714220e | |||
5c2c1b4a48 | |||
78979b414a | |||
caabc51803 |
@ -31,6 +31,28 @@ class TWeakPtr;
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
|
template <typename T> struct TIsTSharedRef : FFalse { };
|
||||||
|
template <typename T> struct TIsTSharedRef<TSharedRef<T>> : FTrue { };
|
||||||
|
|
||||||
|
template <typename T> struct TIsTSharedPtr : FFalse { };
|
||||||
|
template <typename T> struct TIsTSharedPtr<TSharedPtr<T>> : FTrue { };
|
||||||
|
|
||||||
|
template <typename T> struct TIsTWeakPtr : FFalse { };
|
||||||
|
template <typename T> struct TIsTWeakPtr<TWeakPtr<T>> : FTrue { };
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept CTSharedRef = NAMESPACE_PRIVATE::TIsTSharedRef<TRemoveCV<T>>::Value;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept CTSharedPtr = NAMESPACE_PRIVATE::TIsTSharedPtr<TRemoveCV<T>>::Value;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept CTWeakPtr = NAMESPACE_PRIVATE::TIsTWeakPtr<TRemoveCV<T>>::Value;
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
// This is the base object for TSharedPtr and uses constructive interference alignment for performance.
|
// This is the base object for TSharedPtr and uses constructive interference alignment for performance.
|
||||||
class alignas(Memory::ConstructiveInterference) FSharedController : private FSingleton
|
class alignas(Memory::ConstructiveInterference) FSharedController : private FSingleton
|
||||||
{
|
{
|
||||||
@ -281,6 +303,130 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FSharedHelper
|
||||||
|
{
|
||||||
|
template <typename T, typename U> requires (CSameAs<T, TDecay<T>> && CSameAs<U, TDecay<U>>
|
||||||
|
&& (CTSharedRef<T> || CTSharedPtr<T>) && (CTSharedRef<U> || CTSharedPtr<U>))
|
||||||
|
static T& CopySharedReference(T& This, const U& InValue)
|
||||||
|
{
|
||||||
|
if (This.Controller == InValue.Controller)
|
||||||
|
{
|
||||||
|
This.Pointer = InValue.Pointer;
|
||||||
|
return This;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (CTSharedRef<T>)
|
||||||
|
{
|
||||||
|
This.Controller->ReleaseSharedReference();
|
||||||
|
}
|
||||||
|
else if (This.Controller != nullptr)
|
||||||
|
{
|
||||||
|
This.Controller->ReleaseSharedReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
This.Pointer = InValue.Pointer;
|
||||||
|
This.Controller = InValue.Controller;
|
||||||
|
|
||||||
|
if constexpr (CTSharedRef<T> || CTSharedRef<U>)
|
||||||
|
{
|
||||||
|
This.Controller->AddSharedReference();
|
||||||
|
}
|
||||||
|
else if (This.Controller != nullptr)
|
||||||
|
{
|
||||||
|
This.Controller->AddSharedReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
return This;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U> requires (CSameAs<T, TDecay<T>> && CSameAs<U, TDecay<U>>
|
||||||
|
&& (CTSharedRef<T> || CTSharedPtr<T>) && (CTSharedRef<U> || CTSharedPtr<U>))
|
||||||
|
static T& MoveSharedReference(T& This, U&& InValue)
|
||||||
|
{
|
||||||
|
if constexpr (CTSharedRef<T>)
|
||||||
|
{
|
||||||
|
Swap(This.Pointer, InValue.Pointer);
|
||||||
|
Swap(This.Controller, InValue.Controller);
|
||||||
|
}
|
||||||
|
else if constexpr (CTSharedPtr<T> && CTSharedPtr<U>)
|
||||||
|
{
|
||||||
|
if (&InValue == &This) UNLIKELY return This;
|
||||||
|
|
||||||
|
if (This.Controller != nullptr)
|
||||||
|
{
|
||||||
|
This.Controller->ReleaseSharedReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
This.Pointer = Exchange(InValue.Pointer, nullptr);
|
||||||
|
This.Controller = Exchange(InValue.Controller, nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CopySharedReference(This, InValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return This;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U> requires (CSameAs<T, TDecay<T>> && CSameAs<U, TDecay<U>>
|
||||||
|
&& CTWeakPtr<T> && (CTSharedRef<U> || CTSharedPtr<U> || CTWeakPtr<U>))
|
||||||
|
static T& CopyWeakReference(T& This, const U& InValue)
|
||||||
|
{
|
||||||
|
if constexpr (CTWeakPtr<T> && CTWeakPtr<U>)
|
||||||
|
{
|
||||||
|
if (This.Controller == InValue.Controller)
|
||||||
|
{
|
||||||
|
This.Pointer = InValue.Pointer;
|
||||||
|
return This;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (This.Controller != nullptr)
|
||||||
|
{
|
||||||
|
This.Controller->ReleaseWeakReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
This.Pointer = InValue.Pointer;
|
||||||
|
This.Controller = InValue.Controller;
|
||||||
|
|
||||||
|
if constexpr (CTSharedRef<U>)
|
||||||
|
{
|
||||||
|
This.Controller->AddWeakReference();
|
||||||
|
}
|
||||||
|
else if (This.Controller != nullptr)
|
||||||
|
{
|
||||||
|
This.Controller->AddWeakReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
return This;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U> requires (CSameAs<T, TDecay<T>> && CSameAs<U, TDecay<U>>
|
||||||
|
&& CTWeakPtr<T> && (CTSharedRef<U> || CTSharedPtr<U> || CTWeakPtr<U>))
|
||||||
|
static T& MoveWeakReference(T& This, U&& InValue)
|
||||||
|
{
|
||||||
|
if constexpr (CTWeakPtr<T> && CTWeakPtr<U>)
|
||||||
|
{
|
||||||
|
if (&InValue == &This) UNLIKELY return This;
|
||||||
|
|
||||||
|
if (This.Controller != nullptr)
|
||||||
|
{
|
||||||
|
This.Controller->ReleaseWeakReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
This.Pointer = Exchange(InValue.Pointer, nullptr);
|
||||||
|
This.Controller = Exchange(InValue.Controller, nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CopyWeakReference(This, InValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return This;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class TSharedProxy : private FSingleton
|
class TSharedProxy : private FSingleton
|
||||||
{
|
{
|
||||||
@ -319,6 +465,10 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FSharedPtrConstructor { explicit FSharedPtrConstructor() = default; };
|
||||||
|
|
||||||
|
inline constexpr FSharedPtrConstructor SharedPtrConstructor{ };
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -375,15 +525,18 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
FORCEINLINE TSharedFromThis() = default;
|
FORCEINLINE constexpr TSharedFromThis() : WeakThis() { }
|
||||||
FORCEINLINE TSharedFromThis(const TSharedFromThis&) = default;
|
|
||||||
FORCEINLINE TSharedFromThis(TSharedFromThis&&) = default;
|
FORCEINLINE TSharedFromThis(const TSharedFromThis&) : TSharedFromThis() { }
|
||||||
FORCEINLINE TSharedFromThis& operator=(const TSharedFromThis&) = default;
|
|
||||||
FORCEINLINE TSharedFromThis& operator=(TSharedFromThis&&) = default;
|
FORCEINLINE TSharedFromThis& operator=(const TSharedFromThis&) { return *this; }
|
||||||
|
|
||||||
FORCEINLINE ~TSharedFromThis() = default;
|
FORCEINLINE ~TSharedFromThis() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
using SharedFromThisType = TSharedFromThis;
|
||||||
|
|
||||||
// Here it is updated by the private constructor of TSharedRef or TSharedPtr.
|
// Here it is updated by the private constructor of TSharedRef or TSharedPtr.
|
||||||
mutable TWeakPtr<T> WeakThis;
|
mutable TWeakPtr<T> WeakThis;
|
||||||
|
|
||||||
@ -397,6 +550,10 @@ private:
|
|||||||
template <typename T> requires (CObject<T> && !CBoundedArray<T>)
|
template <typename T> requires (CObject<T> && !CBoundedArray<T>)
|
||||||
class TSharedRef final
|
class TSharedRef final
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
using Helper = NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using ElementType = T;
|
using ElementType = T;
|
||||||
@ -466,38 +623,18 @@ public:
|
|||||||
FORCEINLINE ~TSharedRef() { Controller->ReleaseSharedReference(); }
|
FORCEINLINE ~TSharedRef() { Controller->ReleaseSharedReference(); }
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
TSharedRef& operator=(const TSharedRef& InValue)
|
FORCEINLINE TSharedRef& operator=(const TSharedRef& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller == InValue.Controller)
|
|
||||||
{
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller->ReleaseSharedReference();
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
Controller->AddSharedReference();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TSharedRef& operator=(const TSharedRef<U>& InValue) { return *this = *reinterpret_cast<const TSharedRef*>(&InValue); }
|
FORCEINLINE TSharedRef& operator=(const TSharedRef<U>& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
FORCEINLINE TSharedRef& operator=(TSharedRef&& InValue)
|
FORCEINLINE TSharedRef& operator=(TSharedRef&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||||
{
|
|
||||||
Swap(*this, InValue);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TSharedRef& operator=(TSharedRef<U>&& InValue) { return *this = MoveTemp(*reinterpret_cast<TSharedRef*>(&InValue)); }
|
FORCEINLINE TSharedRef& operator=(TSharedRef<U>&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||||
|
|
||||||
/** Compares the pointer values of two TSharedRef. */
|
/** Compares the pointer values of two TSharedRef. */
|
||||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); }
|
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); }
|
||||||
@ -581,35 +718,33 @@ private:
|
|||||||
T* Pointer;
|
T* Pointer;
|
||||||
NAMESPACE_PRIVATE::FSharedController* Controller;
|
NAMESPACE_PRIVATE::FSharedController* Controller;
|
||||||
|
|
||||||
template <typename U>
|
FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::FSharedPtrConstructor, const TSharedPtr<T>& InValue)
|
||||||
FORCEINLINE TSharedRef(const TSharedPtr<U>& InValue, T* InPtr)
|
: Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
: Pointer(InPtr), Controller(InValue.Controller)
|
|
||||||
{
|
{
|
||||||
Controller->AddSharedReference();
|
Controller->AddSharedReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::FSharedPtrConstructor, TSharedPtr<T>&& InValue)
|
||||||
FORCEINLINE TSharedRef(TSharedPtr<U>&& InValue, T* InPtr)
|
: Pointer(Exchange(InValue.Pointer, nullptr))
|
||||||
: Pointer(InPtr), Controller(InValue.Controller)
|
, Controller(Exchange(InValue.Controller, nullptr))
|
||||||
{
|
{ }
|
||||||
InValue.Pointer = nullptr;
|
|
||||||
InValue.Controller = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE TSharedRef(T* InPtr, NAMESPACE_PRIVATE::FSharedController* InController)
|
FORCEINLINE TSharedRef(T* InPtr, NAMESPACE_PRIVATE::FSharedController* InController)
|
||||||
: Pointer(InPtr), Controller(InController)
|
: Pointer(InPtr), Controller(InController)
|
||||||
{
|
{
|
||||||
check(!((Pointer == nullptr) ^ (Controller == nullptr)));
|
check(!((Pointer == nullptr) ^ (Controller == nullptr)));
|
||||||
|
|
||||||
if constexpr (CClass<T>)
|
if constexpr (CClass<T> && !CVolatile<T> && requires { typename T::SharedFromThisType; })
|
||||||
{
|
{
|
||||||
if constexpr (CDerivedFrom<T, TSharedFromThis<T>>)
|
using SharedFromThisType = T::SharedFromThisType;
|
||||||
|
|
||||||
|
if constexpr (CDerivedFrom<T, SharedFromThisType>)
|
||||||
{
|
{
|
||||||
if (Pointer != nullptr)
|
if (Pointer != nullptr)
|
||||||
{
|
{
|
||||||
const TSharedFromThis<T>& SharedFromThis = *Pointer;
|
const SharedFromThisType& SharedFromThis = *Pointer;
|
||||||
checkf(!SharedFromThis.DoesSharedInstanceExist(), TEXT("This object is incorrectly managed by multiple TSharedRef or TSharedPtr."));
|
checkf(!SharedFromThis.DoesSharedInstanceExist(), TEXT("This object is incorrectly managed by multiple TSharedRef or TSharedPtr."));
|
||||||
SharedFromThis.WeakThis = *this;
|
SharedFromThis.WeakThis = ConstCast<TRemoveCV<T>>(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,12 +756,18 @@ private:
|
|||||||
|
|
||||||
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
||||||
|
|
||||||
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Shared-ownership non-nullable smart pointer. Use this when you need an array's lifetime to be managed by a shared smart pointer. */
|
/** Shared-ownership non-nullable smart pointer. Use this when you need an array's lifetime to be managed by a shared smart pointer. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class TSharedRef<T[]> final
|
class TSharedRef<T[]> final
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
using Helper = NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using ElementType = T;
|
using ElementType = T;
|
||||||
@ -698,38 +839,18 @@ public:
|
|||||||
FORCEINLINE ~TSharedRef() { Controller->ReleaseSharedReference(); }
|
FORCEINLINE ~TSharedRef() { Controller->ReleaseSharedReference(); }
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
TSharedRef& operator=(const TSharedRef& InValue)
|
FORCEINLINE TSharedRef& operator=(const TSharedRef& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller == InValue.Controller)
|
|
||||||
{
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller->ReleaseSharedReference();
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
Controller->AddSharedReference();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TSharedRef& operator=(const TSharedRef<U>& InValue) { return *this = *reinterpret_cast<const TSharedRef*>(&InValue); }
|
FORCEINLINE TSharedRef& operator=(const TSharedRef<U>& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
FORCEINLINE TSharedRef& operator=(TSharedRef&& InValue)
|
FORCEINLINE TSharedRef& operator=(TSharedRef&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||||
{
|
|
||||||
Swap(*this, InValue);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TSharedRef& operator=(TSharedRef<U>&& InValue) { return *this = MoveTemp(*reinterpret_cast<TSharedRef*>(&InValue)); }
|
FORCEINLINE TSharedRef& operator=(TSharedRef<U>&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||||
|
|
||||||
/** Compares the pointer values of two TSharedRef. */
|
/** Compares the pointer values of two TSharedRef. */
|
||||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); }
|
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); }
|
||||||
@ -815,20 +936,16 @@ private:
|
|||||||
T* Pointer;
|
T* Pointer;
|
||||||
NAMESPACE_PRIVATE::FSharedController* Controller;
|
NAMESPACE_PRIVATE::FSharedController* Controller;
|
||||||
|
|
||||||
template <typename U>
|
FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::FSharedPtrConstructor, const TSharedPtr<T[]>& InValue)
|
||||||
FORCEINLINE TSharedRef(const TSharedPtr<U>& InValue, T* InPtr)
|
: Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
: Pointer(InPtr), Controller(InValue.Controller)
|
|
||||||
{
|
{
|
||||||
Controller->AddSharedReference();
|
Controller->AddSharedReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::FSharedPtrConstructor, TSharedPtr<T[]>&& InValue)
|
||||||
FORCEINLINE TSharedRef(TSharedPtr<U>&& InValue, T* InPtr)
|
: Pointer(Exchange(InValue.Pointer, nullptr))
|
||||||
: Pointer(InPtr), Controller(InValue.Controller)
|
, Controller(Exchange(InValue.Controller, nullptr))
|
||||||
{
|
{ }
|
||||||
InValue.Pointer = nullptr;
|
|
||||||
InValue.Controller = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE TSharedRef(T* InPtr, NAMESPACE_PRIVATE::FSharedController* InController)
|
FORCEINLINE TSharedRef(T* InPtr, NAMESPACE_PRIVATE::FSharedController* InController)
|
||||||
: Pointer(InPtr), Controller(InController)
|
: Pointer(InPtr), Controller(InController)
|
||||||
@ -842,12 +959,18 @@ private:
|
|||||||
|
|
||||||
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
||||||
|
|
||||||
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Shared-ownership smart pointer. Use this when you need an object's lifetime to be managed by a shared smart pointer. */
|
/** Shared-ownership smart pointer. Use this when you need an object's lifetime to be managed by a shared smart pointer. */
|
||||||
template <typename T> requires (CObject<T> && !CBoundedArray<T>)
|
template <typename T> requires (CObject<T> && !CBoundedArray<T>)
|
||||||
class TSharedPtr final
|
class TSharedPtr final
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
using Helper = NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using ElementType = T;
|
using ElementType = T;
|
||||||
@ -921,20 +1044,6 @@ public:
|
|||||||
InValue.Controller = nullptr;
|
InValue.Controller = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Aliasing constructor used to create a shared reference which shares its reference count with
|
|
||||||
* another shared object, but pointing to a different object, typically a subobject.
|
|
||||||
* Must not be nullptr.
|
|
||||||
*
|
|
||||||
* @param InValue - The shared reference whose reference count should be shared.
|
|
||||||
* @param InPtr - The object pointer to use (instead of the incoming shared pointer's object).
|
|
||||||
*/
|
|
||||||
template <typename U>
|
|
||||||
FORCEINLINE TSharedPtr(TSharedRef<U>&& InValue, T* InPtr)
|
|
||||||
{
|
|
||||||
new (this) TSharedRef<T>(MoveTemp(InValue), InPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructs a TSharedPtr which shares ownership of the object managed by 'InValue'. */
|
/** Constructs a TSharedPtr which shares ownership of the object managed by 'InValue'. */
|
||||||
FORCEINLINE TSharedPtr(const TSharedPtr& InValue) : TSharedPtr(InValue, InValue.Get()) { }
|
FORCEINLINE TSharedPtr(const TSharedPtr& InValue) : TSharedPtr(InValue, InValue.Get()) { }
|
||||||
|
|
||||||
@ -953,10 +1062,6 @@ public:
|
|||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TSharedPtr(TSharedPtr<U>&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { }
|
FORCEINLINE TSharedPtr(TSharedPtr<U>&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { }
|
||||||
|
|
||||||
/** Constructs a TSharedPtr which shares ownership of the object managed by 'InValue'. */
|
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
|
||||||
FORCEINLINE TSharedPtr(TSharedRef<U>&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { }
|
|
||||||
|
|
||||||
/** Constructs a TSharedPtr which gets ownership of the object managed by 'InValue'. */
|
/** Constructs a TSharedPtr which gets ownership of the object managed by 'InValue'. */
|
||||||
template <typename U, typename E> requires (CConvertibleTo<U*, T*> && !CArray<U> && (CDestructible<E> || CLValueReference<E>))
|
template <typename U, typename E> requires (CConvertibleTo<U*, T*> && !CArray<U> && (CDestructible<E> || CLValueReference<E>))
|
||||||
FORCEINLINE TSharedPtr(TUniquePtr<U, E>&& InValue) : TSharedPtr(InValue.Release(), Forward<E>(InValue.GetDeleter())) { }
|
FORCEINLINE TSharedPtr(TUniquePtr<U, E>&& InValue) : TSharedPtr(InValue.Release(), Forward<E>(InValue.GetDeleter())) { }
|
||||||
@ -965,61 +1070,22 @@ public:
|
|||||||
FORCEINLINE ~TSharedPtr() { if (Controller != nullptr) Controller->ReleaseSharedReference(); }
|
FORCEINLINE ~TSharedPtr() { if (Controller != nullptr) Controller->ReleaseSharedReference(); }
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
TSharedPtr& operator=(const TSharedPtr& InValue)
|
FORCEINLINE TSharedPtr& operator=(const TSharedPtr& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller == InValue.Controller)
|
|
||||||
{
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseSharedReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->AddSharedReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TSharedPtr& operator=(const TSharedPtr<U>& InValue) { return *this = *reinterpret_cast<const TSharedPtr*>(&InValue); }
|
FORCEINLINE TSharedPtr& operator=(const TSharedPtr<U>& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TSharedPtr& operator=(const TSharedRef<U>& InValue) { return *reinterpret_cast<TSharedRef<T>*>(this) = InValue; }
|
FORCEINLINE TSharedPtr& operator=(const TSharedRef<U>& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
TSharedPtr& operator=(TSharedPtr&& InValue)
|
FORCEINLINE TSharedPtr& operator=(TSharedPtr&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||||
{
|
|
||||||
if (&InValue == this) UNLIKELY return *this;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseSharedReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = Exchange(InValue.Pointer, nullptr);
|
|
||||||
Controller = Exchange(InValue.Controller, nullptr);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TSharedPtr& operator=(TSharedPtr<U>&& InValue) { return *this = MoveTemp(*reinterpret_cast<TSharedPtr*>(&InValue)); }
|
FORCEINLINE TSharedPtr& operator=(TSharedPtr<U>&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
|
||||||
FORCEINLINE TSharedPtr& operator=(TSharedRef<U>&& InValue) { return *reinterpret_cast<TSharedRef<T>*>(this) = MoveTemp(InValue); }
|
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
template <typename U, typename E> requires (CConvertibleTo<U*, T*> && !CArray<U> && (CDestructible<E> || CLValueReference<E>))
|
template <typename U, typename E> requires (CConvertibleTo<U*, T*> && !CArray<U> && (CDestructible<E> || CLValueReference<E>))
|
||||||
@ -1041,25 +1107,19 @@ public:
|
|||||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; }
|
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; }
|
||||||
|
|
||||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
||||||
FORCEINLINE TSharedRef<T> ToSharedRef(T* InPtr) const&
|
FORCEINLINE TSharedRef<T> ToSharedRef() const&
|
||||||
{
|
{
|
||||||
checkf(IsValid() && InPtr != nullptr, TEXT("TSharedRef cannot be initialized by nullptr."));
|
checkf(IsValid(), TEXT("TSharedRef cannot be initialized by nullptr."));
|
||||||
return TSharedRef<T>(*this, InPtr);
|
return TSharedRef<T>(NAMESPACE_PRIVATE::SharedPtrConstructor, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
||||||
FORCEINLINE TSharedRef<T> ToSharedRef(T* InPtr) &&
|
FORCEINLINE TSharedRef<T> ToSharedRef() &&
|
||||||
{
|
{
|
||||||
checkf(IsValid() && InPtr != nullptr, TEXT("TSharedRef cannot be initialized by nullptr."));
|
checkf(IsValid(), TEXT("TSharedRef cannot be initialized by nullptr."));
|
||||||
return TSharedRef<T>(MoveTemp(*this), InPtr);
|
return TSharedRef<T>(NAMESPACE_PRIVATE::SharedPtrConstructor, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
|
||||||
FORCEINLINE TSharedRef<T> ToSharedRef() const& { return ToSharedRef(Get()); }
|
|
||||||
|
|
||||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
|
||||||
FORCEINLINE TSharedRef<T> ToSharedRef() && { return ToSharedRef(Get()); }
|
|
||||||
|
|
||||||
/** Replaces the managed object. */
|
/** Replaces the managed object. */
|
||||||
FORCEINLINE void Reset(T* InPtr = nullptr) { *this = MoveTemp(TSharedPtr(InPtr)); }
|
FORCEINLINE void Reset(T* InPtr = nullptr) { *this = MoveTemp(TSharedPtr(InPtr)); }
|
||||||
|
|
||||||
@ -1141,15 +1201,17 @@ private:
|
|||||||
{
|
{
|
||||||
check(!((Pointer == nullptr) ^ (Controller == nullptr)));
|
check(!((Pointer == nullptr) ^ (Controller == nullptr)));
|
||||||
|
|
||||||
if constexpr (CClass<T>)
|
if constexpr (CClass<T> && !CVolatile<T> && requires { typename T::SharedFromThisType; })
|
||||||
{
|
{
|
||||||
if constexpr (CDerivedFrom<T, TSharedFromThis<T>>)
|
using SharedFromThisType = T::SharedFromThisType;
|
||||||
|
|
||||||
|
if constexpr (CDerivedFrom<T, SharedFromThisType>)
|
||||||
{
|
{
|
||||||
if (Pointer != nullptr)
|
if (Pointer != nullptr)
|
||||||
{
|
{
|
||||||
const TSharedFromThis<T>& SharedFromThis = *Pointer;
|
const SharedFromThisType& SharedFromThis = *Pointer;
|
||||||
checkf(!SharedFromThis.DoesSharedInstanceExist(), TEXT("This object is incorrectly managed by multiple TSharedRef or TSharedPtr."));
|
checkf(!SharedFromThis.DoesSharedInstanceExist(), TEXT("This object is incorrectly managed by multiple TSharedRef or TSharedPtr."));
|
||||||
SharedFromThis.WeakThis = *this;
|
SharedFromThis.WeakThis = ConstCast<TRemoveCV<T>>(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1161,12 +1223,18 @@ private:
|
|||||||
|
|
||||||
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
||||||
|
|
||||||
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Shared-ownership smart pointer. Use this when you need an array's lifetime to be managed by a shared smart pointer. */
|
/** Shared-ownership smart pointer. Use this when you need an array's lifetime to be managed by a shared smart pointer. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class TSharedPtr<T[]> final
|
class TSharedPtr<T[]> final
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
using Helper = NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using ElementType = T;
|
using ElementType = T;
|
||||||
@ -1242,20 +1310,6 @@ public:
|
|||||||
InValue.Controller = nullptr;
|
InValue.Controller = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Aliasing constructor used to create a shared reference which shares its reference count with
|
|
||||||
* another shared array, but pointing to a different array, typically a subobject.
|
|
||||||
* Must not be nullptr.
|
|
||||||
*
|
|
||||||
* @param InValue - The shared reference whose reference count should be shared.
|
|
||||||
* @param InPtr - The array pointer to use (instead of the incoming shared pointer's array).
|
|
||||||
*/
|
|
||||||
template <typename U, typename V = T*> requires (CNullPointer<V> || (CPointer<V> && CConvertibleTo<TRemovePointer<V>(*)[], T(*)[]>))
|
|
||||||
FORCEINLINE TSharedPtr(TSharedRef<U>&& InValue, V InPtr)
|
|
||||||
{
|
|
||||||
new (this) TSharedRef<T[]>(MoveTemp(InValue), InPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructs a TSharedPtr which shares ownership of the array managed by 'InValue'. */
|
/** Constructs a TSharedPtr which shares ownership of the array managed by 'InValue'. */
|
||||||
FORCEINLINE TSharedPtr(const TSharedPtr& InValue) : TSharedPtr(InValue, InValue.Get()) { }
|
FORCEINLINE TSharedPtr(const TSharedPtr& InValue) : TSharedPtr(InValue, InValue.Get()) { }
|
||||||
|
|
||||||
@ -1274,10 +1328,6 @@ public:
|
|||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TSharedPtr(TSharedPtr<U>&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { }
|
FORCEINLINE TSharedPtr(TSharedPtr<U>&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { }
|
||||||
|
|
||||||
/** Constructs a TSharedPtr which shares ownership of the array managed by 'InValue'. */
|
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
|
||||||
FORCEINLINE TSharedPtr(TSharedRef<U>&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { }
|
|
||||||
|
|
||||||
/** Constructs a TSharedPtr which gets ownership of the array managed by 'InValue'. */
|
/** Constructs a TSharedPtr which gets ownership of the array managed by 'InValue'. */
|
||||||
template <typename U, typename E> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U> && (CDestructible<E> || CLValueReference<E>))
|
template <typename U, typename E> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U> && (CDestructible<E> || CLValueReference<E>))
|
||||||
FORCEINLINE TSharedPtr(TUniquePtr<U, E>&& InValue) : TSharedPtr(InValue.Release(), Forward<E>(InValue.GetDeleter())) { }
|
FORCEINLINE TSharedPtr(TUniquePtr<U, E>&& InValue) : TSharedPtr(InValue.Release(), Forward<E>(InValue.GetDeleter())) { }
|
||||||
@ -1286,61 +1336,22 @@ public:
|
|||||||
FORCEINLINE ~TSharedPtr() { if (Controller != nullptr) Controller->ReleaseSharedReference(); }
|
FORCEINLINE ~TSharedPtr() { if (Controller != nullptr) Controller->ReleaseSharedReference(); }
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
TSharedPtr& operator=(const TSharedPtr& InValue)
|
FORCEINLINE TSharedPtr& operator=(const TSharedPtr& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller == InValue.Controller)
|
|
||||||
{
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseSharedReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->AddSharedReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TSharedPtr& operator=(const TSharedPtr<U>& InValue) { return *this = *reinterpret_cast<const TSharedPtr*>(&InValue); }
|
FORCEINLINE TSharedPtr& operator=(const TSharedPtr<U>& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TSharedPtr& operator=(const TSharedRef<U>& InValue) { return *reinterpret_cast<TSharedRef<T[]>*>(this) = InValue; }
|
FORCEINLINE TSharedPtr& operator=(const TSharedRef<U>& InValue) { return Helper::CopySharedReference(*this, InValue); }
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
TSharedPtr& operator=(TSharedPtr&& InValue)
|
FORCEINLINE TSharedPtr& operator=(TSharedPtr&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||||
{
|
|
||||||
if (&InValue == this) UNLIKELY return *this;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseSharedReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = Exchange(InValue.Pointer, nullptr);
|
|
||||||
Controller = Exchange(InValue.Controller, nullptr);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TSharedPtr& operator=(TSharedPtr<U>&& InValue) { return *this = MoveTemp(*reinterpret_cast<TSharedPtr*>(&InValue)); }
|
FORCEINLINE TSharedPtr& operator=(TSharedPtr<U>&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
|
||||||
FORCEINLINE TSharedPtr& operator=(TSharedRef<U>&& InValue) { return *reinterpret_cast<TSharedRef<T[]>*>(this) = MoveTemp(InValue); }
|
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
template <typename U, typename E> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U> && (CDestructible<E> || CLValueReference<E>))
|
template <typename U, typename E> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U> && (CDestructible<E> || CLValueReference<E>))
|
||||||
@ -1364,27 +1375,19 @@ public:
|
|||||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; }
|
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; }
|
||||||
|
|
||||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
||||||
template <typename U = T*> requires (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>)
|
FORCEINLINE TSharedRef<T[]> ToSharedRef() const&
|
||||||
FORCEINLINE TSharedRef<T[]> ToSharedRef(U InPtr) const&
|
|
||||||
{
|
{
|
||||||
checkf(IsValid() && InPtr != nullptr, TEXT("TSharedRef cannot be initialized by nullptr."));
|
checkf(IsValid(), TEXT("TSharedRef cannot be initialized by nullptr."));
|
||||||
return TSharedRef<T[]>(*this, InPtr);
|
return TSharedRef<T[]>(NAMESPACE_PRIVATE::SharedPtrConstructor, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
||||||
template <typename U = T*> requires (CPointer<U>&& CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>)
|
FORCEINLINE TSharedRef<T[]> ToSharedRef() &&
|
||||||
FORCEINLINE TSharedRef<T[]> ToSharedRef(U InPtr)&&
|
|
||||||
{
|
{
|
||||||
checkf(IsValid() && InPtr != nullptr, TEXT("TSharedRef cannot be initialized by nullptr."));
|
checkf(IsValid(), TEXT("TSharedRef cannot be initialized by nullptr."));
|
||||||
return TSharedRef<T[]>(MoveTemp(*this), InPtr);
|
return TSharedRef<T[]>(NAMESPACE_PRIVATE::SharedPtrConstructor, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
|
||||||
FORCEINLINE TSharedRef<T[]> ToSharedRef() const& { return ToSharedRef(Get()); }
|
|
||||||
|
|
||||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
|
||||||
FORCEINLINE TSharedRef<T[]> ToSharedRef() && { return ToSharedRef(Get()); }
|
|
||||||
|
|
||||||
/** Replaces the managed array. */
|
/** Replaces the managed array. */
|
||||||
template <typename U = T*> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
template <typename U = T*> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||||
FORCEINLINE void Reset(U InPtr = nullptr) { *this = MoveTemp(TSharedPtr(InPtr)); }
|
FORCEINLINE void Reset(U InPtr = nullptr) { *this = MoveTemp(TSharedPtr(InPtr)); }
|
||||||
@ -1473,12 +1476,18 @@ private:
|
|||||||
|
|
||||||
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
||||||
|
|
||||||
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** TWeakPtr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by shared pointer. */
|
/** TWeakPtr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by shared pointer. */
|
||||||
template <typename T> requires (CObject<T> && !CBoundedArray<T>)
|
template <typename T> requires (CObject<T> && !CBoundedArray<T>)
|
||||||
class TWeakPtr final
|
class TWeakPtr final
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
using Helper = NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using ElementType = T;
|
using ElementType = T;
|
||||||
@ -1490,8 +1499,7 @@ public:
|
|||||||
FORCEINLINE constexpr TWeakPtr(nullptr_t) : TWeakPtr() { }
|
FORCEINLINE constexpr TWeakPtr(nullptr_t) : TWeakPtr() { }
|
||||||
|
|
||||||
/** Constructs new TWeakPtr which shares an object managed by 'InValue'. */
|
/** Constructs new TWeakPtr which shares an object managed by 'InValue'. */
|
||||||
FORCEINLINE TWeakPtr(const TWeakPtr& InValue)
|
FORCEINLINE TWeakPtr(const TWeakPtr& InValue) : Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
: Pointer(InValue.Pointer), Controller(InValue.Controller)
|
|
||||||
{
|
{
|
||||||
if (Controller != nullptr)
|
if (Controller != nullptr)
|
||||||
{
|
{
|
||||||
@ -1501,14 +1509,20 @@ public:
|
|||||||
|
|
||||||
/** Constructs new TWeakPtr which shares an object managed by 'InValue'. */
|
/** Constructs new TWeakPtr which shares an object managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE constexpr TWeakPtr(const TWeakPtr<U>& InValue) : TWeakPtr(*reinterpret_cast<const TWeakPtr*>(&InValue)) { }
|
FORCEINLINE constexpr TWeakPtr(const TWeakPtr<U>& InValue) : Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
|
{
|
||||||
|
if (Controller != nullptr)
|
||||||
|
{
|
||||||
|
Controller->AddWeakReference();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */
|
/** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */
|
||||||
FORCEINLINE TWeakPtr(TWeakPtr&& InValue) : Pointer(Exchange(InValue.Pointer, nullptr)), Controller(Exchange(InValue.Controller, nullptr)) { }
|
FORCEINLINE TWeakPtr(TWeakPtr&& InValue) : Pointer(Exchange(InValue.Pointer, nullptr)), Controller(Exchange(InValue.Controller, nullptr)) { }
|
||||||
|
|
||||||
/** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */
|
/** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE constexpr TWeakPtr(TWeakPtr<U>&& InValue) : TWeakPtr(MoveTemp(*reinterpret_cast<TWeakPtr*>(&InValue))) { }
|
FORCEINLINE constexpr TWeakPtr(TWeakPtr<U>&& InValue) : Pointer(Exchange(InValue.Pointer, nullptr)), Controller(Exchange(InValue.Controller, nullptr)) { }
|
||||||
|
|
||||||
/** Constructs a weak pointer from a shared reference. */
|
/** Constructs a weak pointer from a shared reference. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
@ -1531,90 +1545,26 @@ public:
|
|||||||
FORCEINLINE ~TWeakPtr() { if (Controller != nullptr) Controller->ReleaseWeakReference(); }
|
FORCEINLINE ~TWeakPtr() { if (Controller != nullptr) Controller->ReleaseWeakReference(); }
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
TWeakPtr& operator=(const TWeakPtr& InValue)
|
FORCEINLINE TWeakPtr& operator=(const TWeakPtr& InValue) { return Helper::CopyWeakReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller == InValue.Controller)
|
|
||||||
{
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->AddWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TWeakPtr& operator=(const TWeakPtr<U>& InValue) { return *this = *reinterpret_cast<const TWeakPtr*>(&InValue); }
|
FORCEINLINE TWeakPtr& operator=(const TWeakPtr<U>& InValue) { return Helper::CopyWeakReference(*this, InValue); }
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
TWeakPtr& operator=(TWeakPtr&& InValue)
|
FORCEINLINE TWeakPtr& operator=(TWeakPtr&& InValue) { return Helper::MoveWeakReference(*this, MoveTemp(InValue)); }
|
||||||
{
|
|
||||||
if (&InValue == this) UNLIKELY return *this;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = Exchange(InValue.Pointer, nullptr);
|
|
||||||
Controller = Exchange(InValue.Controller, nullptr);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed object with the one managed by 'InValue'. */
|
/** Replaces the managed object with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TWeakPtr& operator=(TWeakPtr<U>&& InValue) { return *this = MoveTemp(*reinterpret_cast<TWeakPtr*>(&InValue)); }
|
FORCEINLINE TWeakPtr& operator=(TWeakPtr<U>&& InValue) { return Helper::MoveWeakReference(*this, MoveTemp(InValue)); }
|
||||||
|
|
||||||
/** Assignment operator sets this weak pointer from a shared reference. */
|
/** Assignment operator sets this weak pointer from a shared reference. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TWeakPtr& operator=(const TSharedRef<U>& InValue)
|
FORCEINLINE TWeakPtr& operator=(const TSharedRef<U>& InValue) { return Helper::CopyWeakReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
Controller->AddWeakReference();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Assignment operator sets this weak pointer from a shared pointer. */
|
/** Assignment operator sets this weak pointer from a shared pointer. */
|
||||||
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
FORCEINLINE TWeakPtr& operator=(const TSharedPtr<U>& InValue)
|
FORCEINLINE TWeakPtr& operator=(const TSharedPtr<U>& InValue) { return Helper::CopyWeakReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->AddWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Effectively the same as calling Reset(). */
|
/** Effectively the same as calling Reset(). */
|
||||||
FORCEINLINE TWeakPtr& operator=(nullptr_t) { Reset(); return *this; }
|
FORCEINLINE TWeakPtr& operator=(nullptr_t) { Reset(); return *this; }
|
||||||
@ -1660,12 +1610,18 @@ private:
|
|||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
||||||
|
|
||||||
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** TWeakPtr is a smart pointer that holds a non-owning ("weak") reference to an array that is managed by shared pointer. */
|
/** TWeakPtr is a smart pointer that holds a non-owning ("weak") reference to an array that is managed by shared pointer. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class TWeakPtr<T[]> final
|
class TWeakPtr<T[]> final
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
using Helper = NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using ElementType = T;
|
using ElementType = T;
|
||||||
@ -1677,8 +1633,7 @@ public:
|
|||||||
FORCEINLINE constexpr TWeakPtr(nullptr_t) : TWeakPtr() { }
|
FORCEINLINE constexpr TWeakPtr(nullptr_t) : TWeakPtr() { }
|
||||||
|
|
||||||
/** Constructs new TWeakPtr which shares an array managed by 'InValue'. */
|
/** Constructs new TWeakPtr which shares an array managed by 'InValue'. */
|
||||||
FORCEINLINE TWeakPtr(const TWeakPtr& InValue)
|
FORCEINLINE TWeakPtr(const TWeakPtr& InValue) : Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
: Pointer(InValue.Pointer), Controller(InValue.Controller)
|
|
||||||
{
|
{
|
||||||
if (Controller != nullptr)
|
if (Controller != nullptr)
|
||||||
{
|
{
|
||||||
@ -1688,14 +1643,20 @@ public:
|
|||||||
|
|
||||||
/** Constructs new TWeakPtr which shares an array managed by 'InValue'. */
|
/** Constructs new TWeakPtr which shares an array managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE constexpr TWeakPtr(const TWeakPtr<U>& InValue) : TWeakPtr(*reinterpret_cast<const TWeakPtr*>(&InValue)) { }
|
FORCEINLINE constexpr TWeakPtr(const TWeakPtr<U>& InValue) : Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
|
{
|
||||||
|
if (Controller != nullptr)
|
||||||
|
{
|
||||||
|
Controller->AddWeakReference();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */
|
/** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */
|
||||||
FORCEINLINE TWeakPtr(TWeakPtr&& InValue) : Pointer(Exchange(InValue.Pointer, nullptr)), Controller(Exchange(InValue.Controller, nullptr)) { }
|
FORCEINLINE TWeakPtr(TWeakPtr&& InValue) : Pointer(Exchange(InValue.Pointer, nullptr)), Controller(Exchange(InValue.Controller, nullptr)) { }
|
||||||
|
|
||||||
/** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */
|
/** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE constexpr TWeakPtr(TWeakPtr<U>&& InValue) : TWeakPtr(MoveTemp(*reinterpret_cast<TWeakPtr*>(&InValue))) { }
|
FORCEINLINE constexpr TWeakPtr(TWeakPtr<U>&& InValue) : Pointer(Exchange(InValue.Pointer, nullptr)), Controller(Exchange(InValue.Controller, nullptr)) { }
|
||||||
|
|
||||||
/** Constructs a weak pointer from a shared reference. */
|
/** Constructs a weak pointer from a shared reference. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
@ -1718,90 +1679,26 @@ public:
|
|||||||
FORCEINLINE ~TWeakPtr() { if (Controller != nullptr) Controller->ReleaseWeakReference(); }
|
FORCEINLINE ~TWeakPtr() { if (Controller != nullptr) Controller->ReleaseWeakReference(); }
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
TWeakPtr& operator=(const TWeakPtr& InValue)
|
FORCEINLINE TWeakPtr& operator=(const TWeakPtr& InValue) { return Helper::CopyWeakReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller == InValue.Controller)
|
|
||||||
{
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->AddWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TWeakPtr& operator=(const TWeakPtr<U>& InValue) { return *this = *reinterpret_cast<const TWeakPtr*>(&InValue); }
|
FORCEINLINE TWeakPtr& operator=(const TWeakPtr<U>& InValue) { return Helper::CopyWeakReference(*this, InValue); }
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
TWeakPtr& operator=(TWeakPtr&& InValue)
|
FORCEINLINE TWeakPtr& operator=(TWeakPtr&& InValue) { return Helper::MoveWeakReference(*this, MoveTemp(InValue)); }
|
||||||
{
|
|
||||||
if (&InValue == this) UNLIKELY return *this;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = Exchange(InValue.Pointer, nullptr);
|
|
||||||
Controller = Exchange(InValue.Controller, nullptr);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaces the managed array with the one managed by 'InValue'. */
|
/** Replaces the managed array with the one managed by 'InValue'. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TWeakPtr& operator=(TWeakPtr<U>&& InValue) { return *this = MoveTemp(*reinterpret_cast<TWeakPtr*>(&InValue)); }
|
FORCEINLINE TWeakPtr& operator=(TWeakPtr<U>&& InValue) { return Helper::MoveWeakReference(*this, MoveTemp(InValue)); }
|
||||||
|
|
||||||
/** Assignment operator sets this weak pointer from a shared reference. */
|
/** Assignment operator sets this weak pointer from a shared reference. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TWeakPtr& operator=(const TSharedRef<U>& InValue)
|
FORCEINLINE TWeakPtr& operator=(const TSharedRef<U>& InValue) { return Helper::CopyWeakReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
Controller->AddWeakReference();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Assignment operator sets this weak pointer from a shared pointer. */
|
/** Assignment operator sets this weak pointer from a shared pointer. */
|
||||||
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
FORCEINLINE TWeakPtr& operator=(const TSharedPtr<U>& InValue)
|
FORCEINLINE TWeakPtr& operator=(const TSharedPtr<U>& InValue) { return Helper::CopyWeakReference(*this, InValue); }
|
||||||
{
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->ReleaseWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer = InValue.Pointer;
|
|
||||||
Controller = InValue.Controller;
|
|
||||||
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
Controller->AddWeakReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Effectively the same as calling Reset(). */
|
/** Effectively the same as calling Reset(). */
|
||||||
FORCEINLINE TWeakPtr& operator=(nullptr_t) { Reset(); return *this; }
|
FORCEINLINE TWeakPtr& operator=(nullptr_t) { Reset(); return *this; }
|
||||||
@ -1847,6 +1744,8 @@ private:
|
|||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
||||||
|
|
||||||
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Constructs an object of type T and wraps it in a TSharedRef or TSharedPtr. Without initialization. */
|
/** Constructs an object of type T and wraps it in a TSharedRef or TSharedPtr. Without initialization. */
|
||||||
|
@ -123,8 +123,30 @@ struct TDefaultDelete<T[]>
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** This is essentially a reference version of TUniquePtr. */
|
|
||||||
template <typename T, CInvocable<TRemoveExtent<T>*> E = TDefaultDelete<T>> requires (CObject<T> && !CBoundedArray<T> && (CDestructible<E> || CLValueReference<E>))
|
template <typename T, CInvocable<TRemoveExtent<T>*> E = TDefaultDelete<T>> requires (CObject<T> && !CBoundedArray<T> && (CDestructible<E> || CLValueReference<E>))
|
||||||
|
class TUniqueRef;
|
||||||
|
|
||||||
|
template <typename T, CInvocable<TRemoveExtent<T>*> E = TDefaultDelete<T>> requires (CObject<T> && !CBoundedArray<T> && (CDestructible<E> || CLValueReference<E>))
|
||||||
|
class TUniquePtr;
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
|
template <typename T> struct TIsTUniqueRef : FFalse { };
|
||||||
|
template <typename T> struct TIsTUniqueRef<TUniqueRef<T>> : FTrue { };
|
||||||
|
|
||||||
|
template <typename T> struct TIsTUniquePtr : FFalse { };
|
||||||
|
template <typename T> struct TIsTUniquePtr<TUniquePtr<T>> : FTrue { };
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept CTUniqueRef = NAMESPACE_PRIVATE::TIsTUniqueRef<TRemoveCV<T>>::Value;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept CTUniquePtr = NAMESPACE_PRIVATE::TIsTUniquePtr<TRemoveCV<T>>::Value;
|
||||||
|
|
||||||
|
/** This is essentially a reference version of TUniquePtr. */
|
||||||
|
template <typename T, CInvocable<TRemoveExtent<T>*> E> requires (CObject<T> && !CBoundedArray<T> && (CDestructible<E> || CLValueReference<E>))
|
||||||
class TUniqueRef final : private FSingleton
|
class TUniqueRef final : private FSingleton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -364,7 +386,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Single-ownership smart pointer. Use this when you need an object's lifetime to be strictly bound to the lifetime of a single smart pointer. */
|
/** Single-ownership smart pointer. Use this when you need an object's lifetime to be strictly bound to the lifetime of a single smart pointer. */
|
||||||
template <typename T, CInvocable<TRemoveExtent<T>*> E = TDefaultDelete<T>> requires (CObject<T> && !CBoundedArray<T> && (CDestructible<E> || CLValueReference<E>))
|
template <typename T, CInvocable<TRemoveExtent<T>*> E> requires (CObject<T> && !CBoundedArray<T> && (CDestructible<E> || CLValueReference<E>))
|
||||||
class TUniquePtr final : private FNoncopyable
|
class TUniquePtr final : private FNoncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user