feat(templates): add TReferenceWrapper and the corresponding testing
This commit is contained in:
parent
ad80dcd78f
commit
2fa4bcea13
@ -9,6 +9,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
|
||||
void TestTemplates()
|
||||
{
|
||||
TestInvoke();
|
||||
TestReferenceWrapper();
|
||||
TestMiscellaneous();
|
||||
}
|
||||
|
||||
@ -45,6 +46,26 @@ void TestInvoke()
|
||||
always_check(TempE == 123);
|
||||
}
|
||||
|
||||
void TestReferenceWrapper()
|
||||
{
|
||||
typedef int32(*FuncType)(int32, int32, int32);
|
||||
FuncType TempA = [](int32 A, int32 B, int32 C) -> int32 { return A * B * C; };
|
||||
TReferenceWrapper<FuncType> TempB(TempA);
|
||||
always_check(TempB(1, 1, 1) == 1);
|
||||
TempB.Get() = &TestFunctionA;
|
||||
always_check(TempA(1, 1, 1) == 3);
|
||||
|
||||
int32 ArrayA[3] = { 1, 2, 3 };
|
||||
TReferenceWrapper<int32> ArrayB[3] = { ArrayA[1], ArrayA[0], ArrayA[2] };
|
||||
always_check(ArrayB[0] == 2);
|
||||
always_check(ArrayB[1] == 1);
|
||||
always_check(ArrayB[2] == 3);
|
||||
for (int32& Element : ArrayB) Element *= 2;
|
||||
always_check(ArrayA[0] == 2);
|
||||
always_check(ArrayA[1] == 4);
|
||||
always_check(ArrayA[2] == 6);
|
||||
}
|
||||
|
||||
NAMESPACE_UNNAMED_BEGIN
|
||||
|
||||
template <typename T>
|
||||
|
45
Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h
Normal file
45
Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
template <typename T>
|
||||
class TReferenceWrapper
|
||||
{
|
||||
public:
|
||||
|
||||
using Type = T;
|
||||
|
||||
template <typename U> requires !TIsSame<TReferenceWrapper, typename TRemoveCVRef<U>::Type>::Value
|
||||
constexpr TReferenceWrapper(U&& Object) : Ptr(AddressOf(Forward<U>(Object))) { }
|
||||
|
||||
TReferenceWrapper(const TReferenceWrapper&) = default;
|
||||
TReferenceWrapper& operator=(const TReferenceWrapper& x) = default;
|
||||
|
||||
constexpr operator T&() const { return *Ptr; }
|
||||
constexpr T& Get() const { return *Ptr; }
|
||||
|
||||
template <typename... Types>
|
||||
constexpr TInvokeResult<T&, Types...>::Type operator()(Types&&... Args) const
|
||||
{
|
||||
return Invoke(Get(), Forward<Types>(Args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T* Ptr;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
TReferenceWrapper(T&) -> TReferenceWrapper<T>;
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -5,3 +5,4 @@
|
||||
#include "Templates/Container.h"
|
||||
#include "Templates/Noncopyable.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Templates/ReferenceWrapper.h"
|
||||
|
@ -8,6 +8,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
void REDCRAFTUTILITY_API TestTemplates();
|
||||
void REDCRAFTUTILITY_API TestInvoke();
|
||||
void REDCRAFTUTILITY_API TestReferenceWrapper();
|
||||
void REDCRAFTUTILITY_API TestMiscellaneous();
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
|
Loading…
Reference in New Issue
Block a user