From 172a92edfedf65620f4823c2b91f6f1deafa9329 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Thu, 3 Feb 2022 16:45:34 +0800 Subject: [PATCH] feat(templates): add basic tools such as Templates/Templates.h --- .../Source/Public/Templates/Container.h | 45 ++++++++++ .../Source/Public/Templates/Noncopyable.h | 25 ++++++ .../Source/Public/Templates/Templates.h | 6 ++ .../Source/Public/Templates/Utility.h | 85 +++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 Redcraft.Utility/Source/Public/Templates/Container.h create mode 100644 Redcraft.Utility/Source/Public/Templates/Noncopyable.h create mode 100644 Redcraft.Utility/Source/Public/Templates/Templates.h create mode 100644 Redcraft.Utility/Source/Public/Templates/Utility.h diff --git a/Redcraft.Utility/Source/Public/Templates/Container.h b/Redcraft.Utility/Source/Public/Templates/Container.h new file mode 100644 index 0000000..99dd079 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Templates/Container.h @@ -0,0 +1,45 @@ +#pragma once + +#include "CoreTypes.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +template requires requires(T Container) { Container.GetData(); } +constexpr auto GetData(T&& Container) +{ + return Container.GetData(); +} + +template constexpr T* GetData(T(&Container)[N]) { return Container; } +template constexpr T* GetData(T(&& Container)[N]) { return Container; } +template constexpr const T* GetData(const T(&Container)[N]) { return Container; } +template constexpr const T* GetData(const T(&& Container)[N]) { return Container; } + +template requires requires(T Container) { Container.data(); } +constexpr auto GetData(T&& Container) +{ + return Container.data(); +} + +template requires requires(T Container) { Container.Num(); } +constexpr auto GetNum(T&& Container) +{ + return Container.Num(); +} + +template constexpr size_t GetNum(T(&Container)[N]) { return N; } +template constexpr size_t GetNum(T(&& Container)[N]) { return N; } +template constexpr size_t GetNum(const T(&Container)[N]) { return N; } +template constexpr size_t GetNum(const T(&& Container)[N]) { return N; } + +template requires requires(T Container) { Container.size(); } +constexpr auto GetNum(T&& Container) +{ + return Container.size(); +} + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Templates/Noncopyable.h b/Redcraft.Utility/Source/Public/Templates/Noncopyable.h new file mode 100644 index 0000000..d970585 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Templates/Noncopyable.h @@ -0,0 +1,25 @@ +#pragma once + +#include "CoreTypes.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +struct FNoncopyable +{ + FNoncopyable(const FNoncopyable&) = delete; + FNoncopyable& operator=(const FNoncopyable&) = delete; +}; + +struct FNonmovable +{ + FNonmovable(const FNonmovable&&) = delete; + FNonmovable& operator=(const FNonmovable&&) = delete; +}; + +struct FSingleton : public FNoncopyable, public FNonmovable { }; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Templates/Templates.h b/Redcraft.Utility/Source/Public/Templates/Templates.h new file mode 100644 index 0000000..f1e8c87 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Templates/Templates.h @@ -0,0 +1,6 @@ +#pragma once + +#include "CoreTypes.h" +#include "Templates/Utility.h" +#include "Templates/Container.h" +#include "Templates/Noncopyable.h" diff --git a/Redcraft.Utility/Source/Public/Templates/Utility.h b/Redcraft.Utility/Source/Public/Templates/Utility.h new file mode 100644 index 0000000..d3f79a1 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Templates/Utility.h @@ -0,0 +1,85 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/TypeTraits.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +template +constexpr const T& AsConst(T& Ref) +{ + return Ref; +} + +template +void AsConst(const T&& Ref) = delete; + +template +constexpr const T(&AsConst(T(&Array)[N]))[N] +{ + return Array; +} + +template +FORCEINLINE typename TRemoveReference::Type&& MoveTemp(T&& Obj) +{ + typedef typename TRemoveReference::Type CastType; + + static_assert(TIsLValueReference::Value, "MoveTemp called on an rvalue."); + static_assert(!TIsConst::Value, "MoveTemp called on a const object."); + + return (CastType&&)Obj; +} + +template +FORCEINLINE T CopyTemp(T& Val) +{ + return const_cast(Val); +} + +template +FORCEINLINE T CopyTemp(const T& Val) +{ + return Val; +} + +template +FORCEINLINE T&& CopyTemp(T&& Val) +{ + return MoveTemp(Val); +} + +template +FORCEINLINE T&& Forward(typename TRemoveReference::Type& Obj) +{ + return (T&&)Obj; +} + +template +FORCEINLINE T&& Forward(typename TRemoveReference::Type&& Obj) +{ + return (T&&)Obj; +} + +template +FORCEINLINE void Swap(T& A, T& B) +{ + T Temp = MoveTemp(A); + A = MoveTemp(B); + B = MoveTemp(Temp); +} + +template +FORCEINLINE void Exchange(T& A, T& B) +{ + Swap(A, B); +} + +template +T&& DeclVal(); + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END