feat(templates): add TRetainedRef and the corresponding testing
This commit is contained in:
parent
2ef2c4a729
commit
1b2ea5c2a6
@ -1475,8 +1475,8 @@ void TestPropagateConst()
|
||||
{
|
||||
struct FTestA
|
||||
{
|
||||
void Check(bool bFlag) { check(!bFlag); }
|
||||
void Check(bool bFlag) const { check(bFlag); }
|
||||
void Check(bool bFlag) { always_check(!bFlag); }
|
||||
void Check(bool bFlag) const { always_check( bFlag); }
|
||||
};
|
||||
|
||||
struct FTestB
|
||||
@ -1504,9 +1504,9 @@ void TestPropagateConst()
|
||||
TempA = TempB;
|
||||
TempB = TempC;
|
||||
|
||||
check(TempA.IsValid());
|
||||
check(TempA == &IntA);
|
||||
check(TempB == TempC);
|
||||
always_check(TempA.IsValid());
|
||||
always_check(TempA == &IntA);
|
||||
always_check(TempB == TempC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1544,6 +1544,12 @@ void TestMiscTemplates()
|
||||
always_check(TestFunctionB(AddressOf(ObjectA)) == 0);
|
||||
always_check(AddressOf(TestMiscTemplates) == &TestMiscTemplates);
|
||||
|
||||
struct FTestRetainedRef { explicit FTestRetainedRef(TRetainedRef<const int64> InRef) { } };
|
||||
|
||||
int64 IntA;
|
||||
FTestRetainedRef TempA(IntA);
|
||||
// FTestRetainedRef TempB(114514);
|
||||
|
||||
}
|
||||
|
||||
NAMESPACE_END(Testing)
|
||||
|
73
Redcraft.Utility/Source/Public/Templates/RetainedReference.h
Normal file
73
Redcraft.Utility/Source/Public/Templates/RetainedReference.h
Normal file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
/**
|
||||
* A helper class which replaces T& as a function parameter when the reference is
|
||||
* intended to be retained by the function (e.g. as a class member). The benefit
|
||||
* of this class is that it is a compile error to pass an rvalue which might otherwise
|
||||
* bind to a const reference, which is dangerous when the reference is retained.
|
||||
*
|
||||
* struct FRAIIType
|
||||
* {
|
||||
* explicit FRAIIType(TRetainedRef<const FThing> InThing) : Ref(InThing) { }
|
||||
*
|
||||
* void DoSomething() { Ref.Something(); }
|
||||
*
|
||||
* FThing& Ref;
|
||||
* };
|
||||
*
|
||||
*/
|
||||
template <typename T>
|
||||
struct TRetainedRef
|
||||
{
|
||||
/** Retain a non-const lvalue reference. */
|
||||
FORCEINLINE constexpr TRetainedRef(T& InRef) : Ref(InRef) { }
|
||||
|
||||
/** Can't retain a rvalue reference. */
|
||||
TRetainedRef(const T& ) = delete;
|
||||
TRetainedRef( T&&) = delete;
|
||||
TRetainedRef(const T&&) = delete;
|
||||
|
||||
/** @return The managed reference. */
|
||||
FORCEINLINE constexpr operator T&() const { return Ref; }
|
||||
FORCEINLINE constexpr T& Get() const { return Ref; }
|
||||
|
||||
private:
|
||||
|
||||
T& Ref;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TRetainedRef<const T>
|
||||
{
|
||||
/** Retain a non-const lvalue reference. */
|
||||
FORCEINLINE constexpr TRetainedRef(T& InRef) : Ref(InRef) { }
|
||||
|
||||
/** Retain a const lvalue reference. */
|
||||
FORCEINLINE constexpr TRetainedRef(const T& InRef) : Ref(InRef) { }
|
||||
|
||||
/** Can't retain a rvalue reference. */
|
||||
TRetainedRef( T&&) = delete;
|
||||
TRetainedRef(const T&&) = delete;
|
||||
|
||||
/** @return The managed reference. */
|
||||
FORCEINLINE constexpr operator const T&() const { return Ref; }
|
||||
FORCEINLINE constexpr const T& Get() const { return Ref; }
|
||||
|
||||
private:
|
||||
|
||||
const T& Ref;
|
||||
|
||||
};
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -16,3 +16,4 @@
|
||||
#include "Templates/Atomic.h"
|
||||
#include "Templates/ScopeHelper.h"
|
||||
#include "Templates/PropagateConst.h"
|
||||
#include "Templates/RetainedReference.h"
|
||||
|
Loading…
Reference in New Issue
Block a user