diff --git a/Engine/Source/Common/Include/Common/Serialization.h b/Engine/Source/Common/Include/Common/Serialization.h index 38c317d4..f46c739d 100644 --- a/Engine/Source/Common/Include/Common/Serialization.h +++ b/Engine/Source/Common/Include/Common/Serialization.h @@ -559,6 +559,8 @@ namespace Common { template <> struct Serializer { static constexpr size_t typeId = HashUtils::StrCrc32("std::wstring"); + // windows: 16, macOS: 32 + static_assert(sizeof(std::wstring::value_type) <= sizeof(uint32_t)); static size_t Serialize(BinarySerializeStream& stream, const std::wstring& value) { @@ -567,12 +569,12 @@ namespace Common { const uint64_t size = value.size(); serialized += Serializer::Serialize(stream, size); - const auto* data = reinterpret_cast(value.data()); + const auto* data = value.data(); for (auto i = 0; i < size; i++) { - stream.Write(data[i]); + stream.Write(data[i]); } - serialized += size * sizeof(std::wstring::value_type); + serialized += size * sizeof(uint32_t); return serialized; } @@ -584,12 +586,14 @@ namespace Common { deserialized += Serializer::Deserialize(stream, size); value.resize(size); - auto* data = reinterpret_cast(value.data()); + auto* data = value.data(); for (auto i = 0; i < size; i++) { - stream.Read(data[i]); + uint32_t tempValue; + stream.Read(tempValue); + data[i] = static_cast(tempValue); } - deserialized += size * sizeof(std::wstring::value_type); + deserialized += size * sizeof(uint32_t); return deserialized; } }; diff --git a/Engine/Source/Mirror/Include/Mirror/Mirror.h b/Engine/Source/Mirror/Include/Mirror/Mirror.h index 28f9acc0..b15e9ba1 100644 --- a/Engine/Source/Mirror/Include/Mirror/Mirror.h +++ b/Engine/Source/Mirror/Include/Mirror/Mirror.h @@ -85,10 +85,15 @@ namespace Mirror { class Any; + using TemplateViewId = uint32_t; + using TemplateViewRttiPtr = const void*; + struct AnyRtti { using DetorFunc = void(void*) noexcept; using CopyConstructFunc = void(void*, const void*); using MoveConstructFunc = void(void*, void*) noexcept; + using CopyAssignFunc = void(void*, const void*); + using MoveAssignFunc = void(void*, void*) noexcept; using EqualFunc = bool(const void*, const void*); using GetTypeInfoFunc = const TypeInfo*(); using GetPtrFunc = Any(void*); @@ -99,10 +104,13 @@ namespace Mirror { using JsonSerializeFunc = void(const void*, rapidjson::Value&, rapidjson::Document::AllocatorType&); using JsonDeserializeFunc = void(void*, const rapidjson::Value&); using ToStringFunc = std::string(const void*); + using GetTemplateViewRttiFunc = std::pair(); template static void Detor(void* inThis) noexcept; template static void CopyConstruct(void* inThis, const void* inOther); template static void MoveConstruct(void* inThis, void* inOther) noexcept; + template static void CopyAssign(void* inThis, const void* inOther); + template static void MoveAssign(void* inThis, void* inOther) noexcept; template static bool Equal(const void* inThis, const void* inOther) noexcept; template static const TypeInfo* GetValueType(); template static const TypeInfo* GetConstValueType(); @@ -119,10 +127,13 @@ namespace Mirror { template static void JsonSerialize(const void* inThis, rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator); template static void JsonDeserialize(void* inThis, const rapidjson::Value& inJsonValue); template static std::string ToString(const void* inThis); + template static std::pair GetTemplateViewRtti(); DetorFunc* detor; CopyConstructFunc* copyConstruct; MoveConstructFunc* moveConstruct; + CopyAssignFunc* copyAssign; + MoveAssignFunc* moveAssign; EqualFunc* equal; GetTypeInfoFunc* getValueType; GetTypeInfoFunc* getConstValueType; @@ -139,6 +150,7 @@ namespace Mirror { JsonSerializeFunc* jsonSerialize; JsonDeserializeFunc* jsonDeserialize; ToStringFunc* toString; + GetTemplateViewRttiFunc* getTemplateViewRtti; }; template @@ -146,6 +158,8 @@ namespace Mirror { &AnyRtti::Detor, &AnyRtti::CopyConstruct, &AnyRtti::MoveConstruct, + &AnyRtti::CopyAssign, + &AnyRtti::MoveAssign, &AnyRtti::Equal, &AnyRtti::GetValueType, &AnyRtti::GetConstValueType, @@ -161,7 +175,20 @@ namespace Mirror { &AnyRtti::Deserialize, &AnyRtti::JsonSerialize, &AnyRtti::JsonDeserialize, - &AnyRtti::ToString + &AnyRtti::ToString, + &AnyRtti::GetTemplateViewRtti + }; + + template + struct TemplateViewRttiGetter { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + template + concept ValidTemplateView = requires(T object) + { + { T::id } -> std::convertible_to; }; class MIRROR_API Any { @@ -184,9 +211,10 @@ namespace Mirror { template Any(std::reference_wrapper&& inArrayRef); // NOLINT template Any(const std::reference_wrapper& inArrayRef); // NOLINT + // NOTICE: Any::operator=() is designed to reset this and re-construct from new value + // if you want to call assign operator, use CopyAssign() and MoveAssign() instead. Any& operator=(const Any& inOther); Any& operator=(Any&& inOther) noexcept; - template Any& operator=(T&& inValue); template Any& operator=(std::reference_wrapper& inRef); template Any& operator=(std::reference_wrapper&& inRef); @@ -197,6 +225,15 @@ namespace Mirror { template Any& operator=(std::reference_wrapper&& inArrayRef); // NOLINT template Any& operator=(const std::reference_wrapper& inArrayRef); // NOLINT + Any& CopyAssign(Any& inOther); + Any& CopyAssign(const Any& inOther); + Any& MoveAssign(Any& inOther) noexcept; + Any& MoveAssign(const Any& inOther) noexcept; + const Any& CopyAssign(Any& inOther) const; + const Any& CopyAssign(const Any& inOther) const; + const Any& MoveAssign(Any& inOther) const noexcept; + const Any& MoveAssign(const Any& inOther) const noexcept; + template bool Convertible(); template bool Convertible() const; @@ -207,6 +244,9 @@ namespace Mirror { template T PolyAs(); template T PolyAs() const; + template bool CanAsTemplateView() const; + TemplateViewRttiPtr GetTemplateViewRtti() const; + bool IsArray() const; Any At(uint32_t inIndex); Any At(uint32_t inIndex) const; @@ -290,11 +330,12 @@ namespace Mirror { template void ConstructFromArrayValue(T (&inValue)[N]); template void ConstructFromArrayValue(T (&&inValue)[N]); template void ConstructFromArrayRef(std::reference_wrapper inRef); - void PerformCopyConstruct(const Any& inOther); void PerformCopyConstructWithPolicy(const Any& inOther, AnyPolicy inPolicy); void PerformCopyConstructForElementWithPolicy(const Any& inOther, AnyPolicy inPolicy, uint32_t inIndex); - void PerformMoveConstruct(Any&& inOther); + void PerformMoveConstruct(Any&& inOther) noexcept; + void PerformCopyAssign(const Any& inOther) const; + void PerformMoveAssign(const Any& inOther) const noexcept; uint32_t ElementNum() const; uint32_t arrayLength; @@ -320,6 +361,9 @@ namespace Mirror { template T As() const; + template bool CanAsTemplateView() const; + TemplateViewRttiPtr GetTemplateViewRtti() const; + bool IsMemoryHolder() const; bool IsRef() const; bool IsNonConstRef() const; @@ -329,6 +373,8 @@ namespace Mirror { const TypeInfo* AddPointerType() const; const TypeInfo* RemovePointerType() const; + // TODO more proxy func + private: template decltype(auto) Delegate(F&& inFunc) const; @@ -337,6 +383,13 @@ namespace Mirror { using ArgumentList = std::vector; + template Any ForwardAsAny(T&& value); + template Argument ForwardAsArg(T&& value); + template ArgumentList ForwardAsArgList(Args&&... args); + template Any ForwardAsAnyByValue(T&& value); + template Argument ForwardAsArgByValue(T&& value); + template ArgumentList ForwardAsArgListByValue(Args&&... args); + struct MIRROR_API Id { static Id null; @@ -541,13 +594,15 @@ namespace Mirror { public: ~Destructor() override; - template void Invoke(C&& object) const; + template void Destruct(C&& object) const; + template void Delete(C* object) const; const std::string& GetOwnerName() const; const Id& GetOwnerId() const; const Class& GetOwner() const; FieldAccess GetAccess() const; - void InvokeDyn(const Argument& argument) const; + void DestructDyn(const Argument& argument) const; + void DeleteDyn(const Argument& argument) const; private: friend class Registry; @@ -560,6 +615,7 @@ namespace Mirror { Id owner; FieldAccess access; Invoker destructor; + Invoker deleter; }; explicit Destructor(ConstructParams&& params); @@ -567,6 +623,7 @@ namespace Mirror { Id owner; FieldAccess access; Invoker destructor; + Invoker deleter; }; class MIRROR_API MemberVariable final : public ReflNode { @@ -708,9 +765,12 @@ namespace Mirror { ~Class() override; - template Any Construct(Args&&... args); - template Any New(Args&&... args); - template Any InplaceNew(void* ptr, Args&&... args); + template Any Construct(Args&&... args) const; + template Any New(Args&&... args) const; + template Any InplaceNew(void* ptr, Args&&... args) const; + template void Destruct(C&& object) const; + template void Delete(C* object) const; + Any InplaceGetObject(void* ptr) const; void ForEachStaticVariable(const VariableTraverser& func) const; void ForEachStaticFunction(const FunctionTraverser& func) const; @@ -749,6 +809,8 @@ namespace Mirror { Any ConstructDyn(const ArgumentList& arguments) const; Any NewDyn(const ArgumentList& arguments) const; Any InplaceNewDyn(void* ptr, const ArgumentList& arguments) const; + void DestructDyn(const Argument& argument) const; + void DeleteDyn(const Argument& argument) const; private: static std::unordered_map typeToIdMap; @@ -757,12 +819,14 @@ namespace Mirror { template friend class ClassRegistry; using BaseClassGetter = std::function; + using InplaceGetter = std::function; struct ConstructParams { Id id; const TypeInfo* typeInfo; size_t memorySize; BaseClassGetter baseClassGetter; + InplaceGetter inplaceGetter; std::function defaultObjectCreator; std::optional destructorParams; std::optional defaultConstructorParams; @@ -781,6 +845,7 @@ namespace Mirror { const TypeInfo* typeInfo; size_t memorySize; BaseClassGetter baseClassGetter; + InplaceGetter inplaceGetter; Any defaultObject; std::optional destructor; std::unordered_map constructors; @@ -890,6 +955,702 @@ namespace Mirror { }; } +namespace Mirror { + // ---------------- begin std::optional ---------------- + struct StdOptionalViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdOptionalView"); + + using GetBaseTypeFunc = const TypeInfo*(); + using HasValueFunc = bool(const Argument&); + using GetValueFunc = Any(const Argument&); + + template static const TypeInfo* GetBaseType(); + template static bool HasValue(const Argument& inArg); + template static Any GetValue(const Argument& inArg); + + GetBaseTypeFunc* getBaseType; + HasValueFunc* hasValue; + GetValueFunc* getValue; + }; + + template + static constexpr StdOptionalViewRtti stdOptionalViewRttiImpl = { + &StdOptionalViewRtti::GetBaseType, + &StdOptionalViewRtti::HasValue, + &StdOptionalViewRtti::GetValue + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdOptionalView { + public: + static constexpr TemplateViewId id = StdOptionalViewRtti::id; + + explicit StdOptionalView(const Argument& inObj); + NonCopyable(StdOptionalView) + NonMovable(StdOptionalView) + + const TypeInfo* BaseType() const; + bool HasValue() const; + Any GetValue() const; + + private: + const Argument& obj; + const StdOptionalViewRtti* rtti; + }; + // ---------------- end std::optional-- ---------------- + + // ---------------- begin std::pair ----------------- + struct StdPairViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdPairView"); + + using GetKeyTypeFunc = const TypeInfo*(); + using GetValueTypeFunc = const TypeInfo*(); + using GetKeyFunc = Any(const Argument&); + using GetValueFunc = Any(const Argument&); + + template static const TypeInfo* GetKeyType(); + template static const TypeInfo* GetValueType(); + template static Any GetKey(const Argument& inObj); + template static Any GetValue(const Argument& inObj); + template static Any GetConstKey(const Argument& inObj); + template static Any GetConstValue(const Argument& inObj); + + GetKeyTypeFunc* getKeyType; + GetValueTypeFunc* getValueType; + GetKeyFunc* getKey; + GetValueFunc* getValue; + GetKeyFunc* getConstKey; + GetValueFunc* getConstValue; + }; + + template + static constexpr StdPairViewRtti stdPairViewRttiImpl = { + &StdPairViewRtti::GetKeyType, + &StdPairViewRtti::GetValueType, + &StdPairViewRtti::GetKey, + &StdPairViewRtti::GetValue, + &StdPairViewRtti::GetConstKey, + &StdPairViewRtti::GetConstValue + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdPairView { + public: + static constexpr TemplateViewId id = StdPairViewRtti::id; + + explicit StdPairView(const Argument& inObj); + NonCopyable(StdPairView) + NonMovable(StdPairView) + + const TypeInfo* GetKeyType() const; + const TypeInfo* GetValueType() const; + Any GetKey() const; + Any GetValue() const; + Any GetConstKey() const; + Any GetConstValue() const; + + private: + const Argument& obj; + const StdPairViewRtti* rtti; + }; + // ---------------- end std::pair ------------------- + + // ---------------- begin std::array ------------------- + struct StdArrayViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdArrayView"); + + using GetElementTypeFunc = const TypeInfo*(); + using GetSizeFunc = size_t(); + using GetElementFunc = Any(const Argument&, size_t); + using GetConstElementFunc = Any(const Argument&, size_t); + + template static const TypeInfo* GetElementType(); + template static size_t GetSize(); + template static Any GetElement(const Argument& inObj, size_t inIndex); + template static Any GetConstElement(const Argument& inObj, size_t inIndex); + + GetElementTypeFunc* getElementType; + GetSizeFunc* getSize; + GetElementFunc* getElement; + GetConstElementFunc* getConstElement; + }; + + template + static constexpr StdArrayViewRtti stdArrayViewRttiImpl = { + &StdArrayViewRtti::GetElementType, + &StdArrayViewRtti::GetSize, + &StdArrayViewRtti::GetElement, + &StdArrayViewRtti::GetConstElement, + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdArrayView { + public: + static constexpr TemplateViewId id = StdArrayViewRtti::id; + + explicit StdArrayView(const Argument& inObj); + NonCopyable(StdArrayView) + NonMovable(StdArrayView) + + const TypeInfo* GetElementType() const; + size_t GetSize() const; + Any GetElement(size_t inIndex) const; + Any GetConstElement(size_t inIndex) const; + + private: + const Argument& obj; + const StdArrayViewRtti* rtti; + }; + // ---------------- end std::array --------------------- + + // ---------------- begin std::vector ------------------ + struct StdVectorViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdVectorView"); + + using GetElementTypeFunc = const TypeInfo*(); + using GetSizeFunc = size_t(const Argument&); + using GetElementFunc = Any(const Argument&, size_t); + using GetConstElementFunc = Any(const Argument&, size_t); + using EmplaceBackFunc = Any(const Argument&, const Argument&); + using EraseFunc = void(const Argument&, size_t); + + template static const TypeInfo* GetElementType(); + template static size_t GetSize(const Argument& inObj); + template static Any GetElement(const Argument& inObj, size_t inIndex); + template static Any GetConstElement(const Argument& inObj, size_t inIndex); + template static Any EmplaceBack(const Argument& inObj, const Argument& inTempObj); + template static void Erase(const Argument& inObj, size_t inIndex); + + GetElementTypeFunc* getElementType; + GetSizeFunc* getSize; + GetElementFunc* getElement; + GetConstElementFunc* getConstElement; + EmplaceBackFunc* emplaceBack; + EraseFunc* erase; + }; + + template + static constexpr StdVectorViewRtti stdVectorViewRttiImpl = { + &StdVectorViewRtti::GetElementType, + &StdVectorViewRtti::GetSize, + &StdVectorViewRtti::GetElement, + &StdVectorViewRtti::GetConstElement, + &StdVectorViewRtti::EmplaceBack, + &StdVectorViewRtti::Erase + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdVectorView { + public: + static constexpr TemplateViewId id = StdVectorViewRtti::id; + + explicit StdVectorView(const Argument& inObj); + NonCopyable(StdVectorView) + NonMovable(StdVectorView) + + const TypeInfo* ElementType() const; + size_t GetSize() const; + Any GetElement(size_t inIndex) const; + Any GetConstElement(size_t inIndex) const; + Any EmplaceBack(const Argument& inNewObj) const; + void Erase(size_t inIndex) const; + + private: + const Argument& obj; + const StdVectorViewRtti* rtti; + }; + // ---------------- end std::vector -------------------- + + // ---------------- begin std::list -------------------- + struct StdListViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdListViewRtti"); + + using GetElementTypeFunc = const TypeInfo*(); + using GetSizeFunc = size_t(const Argument&); + using TraverseFunc = void(const Argument&, const std::function&); + using ConstTraverseFunc = void(const Argument&, const std::function&); + using EmplaceFrontFunc = Any(const Argument&, const Argument&); + using EmplaceBackFunc = Any(const Argument&, const Argument&); + using GetBeginIterFunc = Any(const Argument&); + using GetEndIterFunc = Any(const Argument&); + using GetBeginConstIterFunc = Any(const Argument&); + using GetEndConstIterFunc = Any(const Argument&); + using GetNextIterFunc = Any(const Argument&); + using GetLastIterFunc = Any(const Argument&); + using GetNextConstIterFunc = Any(const Argument&); + using GetLastConstIterFunc = Any(const Argument&); + using DerefIterFunc = Any(const Argument&); + using DerefConstIterFunc = Any(const Argument&); + + template static const TypeInfo* GetElementType(); + template static size_t GetSize(const Argument& inObj); + template static void Traverse(const Argument& inObj, const std::function& inTraverser); + template static void ConstTraverse(const Argument& inObj, const std::function& inTraverser); + template static Any EmplaceFront(const Argument& inObj, const Argument& inTempObj); + template static Any EmplaceBack(const Argument& inObj, const Argument& inTempObj); + template static Any GetBeginIter(const Argument& inObj); + template static Any GetEndIter(const Argument& inObj); + template static Any GetBeginConstIter(const Argument& inObj); + template static Any GetEndConstIter(const Argument& inObj); + template static Any GetNextIter(const Argument& inIter); + template static Any GetLastIter(const Argument& inIter); + template static Any GetNextConstIter(const Argument& inIter); + template static Any GetLastConstIter(const Argument& inIter); + template static Any DerefIter(const Argument& inIter); + template static Any DerefConstIter(const Argument& inIter); + + GetElementTypeFunc* getElementType; + GetSizeFunc* getSize; + TraverseFunc* traverse; + ConstTraverseFunc* constTraverse; + EmplaceFrontFunc* emplaceFront; + EmplaceBackFunc* emplaceBack; + GetBeginIterFunc* getBeginIter; + GetEndIterFunc* getEndIter; + GetBeginConstIterFunc* getBeginConstIter; + GetEndConstIterFunc* getEndConstIter; + GetNextIterFunc* getNextIter; + GetLastIterFunc* getLastIter; + GetNextConstIterFunc* getNextConstIter; + GetLastConstIterFunc* getLastConstIter; + DerefIterFunc* derefIter; + DerefConstIterFunc* derefConstIter; + }; + + template + static constexpr StdListViewRtti stdListViewRttiImpl = { + &StdListViewRtti::GetElementType, + &StdListViewRtti::GetSize, + &StdListViewRtti::Traverse, + &StdListViewRtti::ConstTraverse, + &StdListViewRtti::EmplaceFront, + &StdListViewRtti::EmplaceBack, + &StdListViewRtti::GetBeginIter, + &StdListViewRtti::GetEndIter, + &StdListViewRtti::GetBeginConstIter, + &StdListViewRtti::GetEndConstIter, + &StdListViewRtti::GetNextIter, + &StdListViewRtti::GetLastIter, + &StdListViewRtti::GetNextConstIter, + &StdListViewRtti::GetLastConstIter, + &StdListViewRtti::DerefIter, + &StdListViewRtti::DerefConstIter, + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdListView { + public: + using ElementTraverser = std::function; + static constexpr TemplateViewId id = StdListViewRtti::id; + + explicit StdListView(const Argument& inObj); + NonCopyable(StdListView) + NonMovable(StdListView) + + const TypeInfo* GetElementType() const; + size_t GetSize() const; + void Traverse(const ElementTraverser& inTraverser) const; + void ConstTraverse(const ElementTraverser& inTraverser) const; + Any EmplaceFront(const Argument& inTempObj) const; + Any EmplaceBack(const Argument& inTempObj) const; + Any GetBeginIter() const; + Any GetEndIter() const; + Any GetBeginConstIter() const; + Any GetEndConstIter() const; + Any GetNextIter(const Argument& inIter) const; + Any GetLastIter(const Argument& inIter) const; + Any GetNextConstIter(const Argument& inIter) const; + Any GetLastConstIter(const Argument& inIter) const; + Any DerefIter(const Argument& inIter) const; + Any DerefConstIter(const Argument& inIter) const; + + private: + const Argument& obj; + const StdListViewRtti* rtti; + }; + // ---------------- end std::list ---------------------- + + // ------------- begin std::unordered_set -------------- + struct StdUnorderedSetViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdUnorderedSetView"); + + using GetElementTypeFunc = const TypeInfo*(); + using GetSizeFunc = size_t(const Argument&); + using TraverseFunc = void(const Argument&, const std::function&); + using ConstTraverseFunc = void(const Argument&, const std::function&); + using ContainsFunc = bool(const Argument&, const Argument&); + using EmplaceFunc = void(const Argument&, const Argument&); + using EraseFunc = void(const Argument&, const Argument&); + + template static const TypeInfo* GetElementType(); + template static size_t GetSize(const Argument& inObj); + template static void Traverse(const Argument& inObj, const std::function& inTraverser); + template static void ConstTraverse(const Argument& inObj, const std::function& inTraverser); + template static bool Contains(const Argument& inObj, const Argument& inElement); + template static void Emplace(const Argument& inObj, const Argument& inTempObj); + template static void Erase(const Argument& inObj, const Argument& inElement); + + GetElementTypeFunc* getElementType; + GetSizeFunc* getSize; + TraverseFunc* traverse; + ConstTraverseFunc* constTraverse; + ContainsFunc* contains; + EmplaceFunc* emplace; + EraseFunc* erase; + }; + + template + static constexpr StdUnorderedSetViewRtti stdUnorderedSetViewRttiImpl = { + &StdUnorderedSetViewRtti::GetElementType, + &StdUnorderedSetViewRtti::GetSize, + &StdUnorderedSetViewRtti::Traverse, + &StdUnorderedSetViewRtti::ConstTraverse, + &StdUnorderedSetViewRtti::Contains, + &StdUnorderedSetViewRtti::Emplace, + &StdUnorderedSetViewRtti::Erase, + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdUnorderedSetView { + public: + using ElementTraverser = std::function; + static constexpr TemplateViewId id = StdUnorderedSetViewRtti::id; + + explicit StdUnorderedSetView(const Argument& inObj); + NonCopyable(StdUnorderedSetView) + NonMovable(StdUnorderedSetView) + + const TypeInfo* GetElementType() const; + size_t GetSize() const; + void Traverse(const ElementTraverser& inTraverser) const; + void ConstTraverse(const ElementTraverser& inTraverser) const; + bool Contains(const Argument& inElement) const; + void Emplace(const Argument& inTempObj) const; + void Erase(const Argument& inElement) const; + + private: + const Argument& obj; + const StdUnorderedSetViewRtti* rtti; + }; + // ------------- end std::unordered_set ---------------- + + // ----------------- begin std::set -------------------- + struct StdSetViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdSetView"); + + using GetElementTypeFunc = const TypeInfo*(); + using GetSizeFunc = size_t(const Argument&); + using TraverseFunc = void(const Argument&, const std::function&); + using ContainsFunc = bool(const Argument&, const Argument&); + using EmplaceFunc = void(const Argument&, const Argument&); + using EraseFunc = void(const Argument&, const Argument&); + + template static const TypeInfo* GetElementType(); + template static size_t GetSize(const Argument& inObj); + template static void Traverse(const Argument& inObj, const std::function& inTraverser); + template static bool Contains(const Argument& inObj, const Argument& inElement); + template static void Emplace(const Argument& inObj, const Argument& inTempObj); + template static void Erase(const Argument& inObj, const Argument& inElement); + + GetElementTypeFunc* getElementType; + GetSizeFunc* getSize; + TraverseFunc* traverse; + ContainsFunc* contains; + EmplaceFunc* emplace; + EraseFunc* erase; + }; + + template + static constexpr StdSetViewRtti stdSetViewRttiImpl = { + &StdSetViewRtti::GetElementType, + &StdSetViewRtti::GetSize, + &StdSetViewRtti::Traverse, + &StdSetViewRtti::Contains, + &StdSetViewRtti::Emplace, + &StdSetViewRtti::Erase + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdSetView { + public: + using ElementTraverser = std::function; + static constexpr TemplateViewId id = StdSetViewRtti::id; + + explicit StdSetView(const Argument& inObj); + NonCopyable(StdSetView) + NonMovable(StdSetView) + + const TypeInfo* GetElementType() const; + size_t GetSize() const; + void Traverse(const ElementTraverser& inTraverser) const; + bool Contains(const Argument& inElement) const; + void Emplace(const Argument& inTempObj) const; + void Erase(const Argument& inElement) const; + + private: + const Argument& obj; + const StdSetViewRtti* rtti; + }; + // ----------------- end std::set ---------------------- + + // ------------- begin std::unordered_map ----------- + struct StdUnorderedMapViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdUnorderedMapView"); + + using GetKeyTypeFunc = const TypeInfo*(); + using GetValueTypeFunc = const TypeInfo*(); + using GetSizeFunc = size_t(const Argument&); + using AtFunc = Any(const Argument&, const Argument&); + using GetOrAddFunc = Any(const Argument&, const Argument&); + using TraverseFunc = void(const Argument&, const std::function&); + using ConstTraverseFunc = void(const Argument&, const std::function&); + using ContainsFunc = bool(const Argument&, const Argument&); + using EmplaceFunc = void(const Argument&, const Argument&, const Argument&); + using EraseFunc = void(const Argument&, const Argument&); + + template static const TypeInfo* GetKeyType(); + template static const TypeInfo* GetValueType(); + template static size_t GetSize(const Argument& inObj); + template static Any At(const Argument& inObj, const Argument& inKey); + template static Any GetOrAdd(const Argument& inObj, const Argument& inKey); + template static void Traverse(const Argument& inObj, const std::function& inTraverser); + template static void ConstTraverse(const Argument& inObj, const std::function& inTraverser); + template static bool Contains(const Argument& inObj, const Argument& inKey); + template static void Emplace(const Argument& inObj, const Argument& inTempKey, const Argument& inTempValue); + template static void Erase(const Argument& inObj, const Argument& inKey); + + GetKeyTypeFunc* getKeyType; + GetValueTypeFunc* getValueType; + GetSizeFunc* getSize; + AtFunc* at; + GetOrAddFunc* getOrAdd; + TraverseFunc* traverse; + ConstTraverseFunc* constTraverse; + ContainsFunc* contains; + EmplaceFunc* emplace; + EraseFunc* erase; + }; + + template + static constexpr StdUnorderedMapViewRtti stdUnorderedMapViewRttiImpl = { + &StdUnorderedMapViewRtti::GetKeyType, + &StdUnorderedMapViewRtti::GetValueType, + &StdUnorderedMapViewRtti::GetSize, + &StdUnorderedMapViewRtti::At, + &StdUnorderedMapViewRtti::GetOrAdd, + &StdUnorderedMapViewRtti::Traverse, + &StdUnorderedMapViewRtti::ConstTraverse, + &StdUnorderedMapViewRtti::Contains, + &StdUnorderedMapViewRtti::Emplace, + &StdUnorderedMapViewRtti::Erase + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + };; + + class MIRROR_API StdUnorderedMapView { + public: + using PairTraverser = std::function; + static constexpr TemplateViewId id = StdUnorderedMapViewRtti::id; + + explicit StdUnorderedMapView(const Argument& inObj); + NonCopyable(StdUnorderedMapView) + NonMovable(StdUnorderedMapView) + + const TypeInfo* GetKeyType() const; + const TypeInfo* GetValueType() const; + size_t GetSize() const; + Any At(const Argument& inKey) const; + Any GetOrAdd(const Argument& inKey) const; + void Traverse(const PairTraverser& inTraverser) const; + void ConstTraverse(const PairTraverser& inTraverser) const; + bool Contains(const Argument& inKey) const; + void Emplace(const Argument& inTempKey, const Argument& inTempValue) const; + void Erase(const Argument& inKey) const; + + private: + const Argument& obj; + const StdUnorderedMapViewRtti* rtti; + }; + // ------------- end std::unordered_map ------------- + + // ----------------- begin std::map ----------------- + struct StdMapViewRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdMapView"); + + using GetKeyTypeFunc = const TypeInfo*(); + using GetValueTypeFunc = const TypeInfo*(); + using GetSizeFunc = size_t(const Argument&); + using AtFunc = Any(const Argument&, const Argument&); + using GetOrAddFunc = Any(const Argument&, const Argument&); + using TraverseFunc = void(const Argument&, const std::function&); + using ConstTraverseFunc = void(const Argument&, const std::function&); + using ContainsFunc = bool(const Argument&, const Argument&); + using EmplaceFunc = void(const Argument&, const Argument&, const Argument&); + using EraseFunc = void(const Argument&, const Argument&); + + template static const TypeInfo* GetKeyType(); + template static const TypeInfo* GetValueType(); + template static size_t GetSize(const Argument& inObj); + template static Any At(const Argument& inObj, const Argument& inKey); + template static Any GetOrAdd(const Argument& inObj, const Argument& inKey); + template static void Traverse(const Argument& inObj, const std::function& inTraverser); + template static void ConstTraverse(const Argument& inObj, const std::function& inTraverser); + template static bool Contains(const Argument& inObj, const Argument& inKey); + template static void Emplace(const Argument& inObj, const Argument& inTempKey, const Argument& inTempValue); + template static void Erase(const Argument& inObj, const Argument& inKey); + + GetKeyTypeFunc* getKeyType; + GetValueTypeFunc* getValueType; + GetSizeFunc* getSize; + AtFunc* at; + GetOrAddFunc* getOrAdd; + TraverseFunc* traverse; + ConstTraverseFunc* constTraverse; + ContainsFunc* contains; + EmplaceFunc* emplace; + EraseFunc* erase; + }; + + template + static constexpr StdMapViewRtti stdMapViewRttiImpl = { + &StdMapViewRtti::GetKeyType, + &StdMapViewRtti::GetValueType, + &StdMapViewRtti::GetSize, + &StdMapViewRtti::At, + &StdMapViewRtti::GetOrAdd, + &StdMapViewRtti::Traverse, + &StdMapViewRtti::ConstTraverse, + &StdMapViewRtti::Contains, + &StdMapViewRtti::Emplace, + &StdMapViewRtti::Erase + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdMapView { + public: + using PairTraverser = std::function; + static constexpr TemplateViewId id = StdMapViewRtti::id; + + explicit StdMapView(const Argument& inObj); + NonCopyable(StdMapView) + NonMovable(StdMapView) + + const TypeInfo* GetKeyType() const; + const TypeInfo* GetValueType() const; + size_t GetSize() const; + Any At(const Argument& inKey) const; + Any GetOrAdd(const Argument& inKey) const; + void Traverse(const PairTraverser& inTraverser) const; + void ConstTraverse(const PairTraverser& inTraverser) const; + bool Contains(const Argument& inKey) const; + void Emplace(const Argument& inTempKey, const Argument& inTempValue) const; + void Erase(const Argument& inKey) const; + + private: + const Argument& obj; + const StdMapViewRtti* rtti; + }; + // ----------------- end std::map ------------------- + + // --------------- begin std::tuple ----------------- + struct StdTupleRtti { + static constexpr TemplateViewId id = Common::HashUtils::StrCrc32("Mirror::StdTupleView"); + + using GetSizeFunc = size_t(); + using GetElementTypeFunc = const TypeInfo*(size_t); + using GetElementFunc = Any(const Argument&, size_t); + using VisitFunc = void(const Argument&, const std::function&); + + template static size_t GetSize(); + template static const TypeInfo* GetElementType(size_t inIndex); + template static Any GetElement(const Argument&, size_t inIndex); + template static void Visit(const Argument&, const std::function& inVisitor); + + GetSizeFunc* getSize; + GetElementTypeFunc* getElementType; + GetElementFunc* getElement; + VisitFunc* visit; + }; + + template + static constexpr StdTupleRtti stdTupleRttiImpl = { + &StdTupleRtti::GetSize, + &StdTupleRtti::GetElementType, + &StdTupleRtti::GetElement, + &StdTupleRtti::Visit + }; + + template + struct TemplateViewRttiGetter> { + static constexpr TemplateViewId Id(); + static const void* Get(); + }; + + class MIRROR_API StdTupleView { + public: + using Visitor = std::function; + static constexpr TemplateViewId id = StdTupleRtti::id; + + explicit StdTupleView(const Argument& inObj); + NonCopyable(StdTupleView) + NonMovable(StdTupleView) + + size_t GetSize() const; + const TypeInfo* GetElementType(size_t inIndex) const; + Any GetElement(size_t inIndex) const; + void Visit(const Visitor& inVisitor) const; + + private: + const Argument& obj; + const StdTupleRtti* rtti; + }; + // --------------- end std::tuple ------------------- +} + namespace Mirror::Internal { template void StaticCheckArgumentType() @@ -900,34 +1661,14 @@ namespace Mirror::Internal { "static version reflection method do no support use Any/Any*/const Any*/Argument as argument, please check you arguments"); } - template - Any ForwardAsAny(T&& value) - { - StaticCheckArgumentType(); - - if constexpr (std::is_lvalue_reference_v) { - return { std::ref(std::forward(value)) }; - } else { - return { std::forward(value) }; - } - } - - template - Argument ForwardAsArgument(T&& value) - { - StaticCheckArgumentType(); - return ForwardAsAny(std::forward(value)); - } - - template - ArgumentList ForwardAsArgumentList(Args&&... args) + template + static std::array, sizeof...(T)> BuildTupleGetterArray(std::index_sequence) { - ArgumentList result; - result.reserve(sizeof...(args)); - (void) std::initializer_list { ([&]() -> void { - result.emplace_back(ForwardAsArgument(std::forward(args))); - }(), 0)... }; - return result; + return { + [](const Argument& inObj) -> Any { + return std::get(inObj.As&>()); + }... + }; } } @@ -1056,12 +1797,12 @@ namespace Common { // NOLINT static size_t Serialize(BinarySerializeStream& stream, const T& value) { - return SerializeDyn(stream, Mirror::Class::Get(), Mirror::Internal::ForwardAsArgument(value)); + return SerializeDyn(stream, Mirror::Class::Get(), Mirror::ForwardAsArg(value)); } static size_t Deserialize(BinaryDeserializeStream& stream, T& value) { - return DeserializeDyn(stream, Mirror::Class::Get(), Mirror::Internal::ForwardAsArgument(value)); + return DeserializeDyn(stream, Mirror::Class::Get(), Mirror::ForwardAsArg(value)); } }; @@ -1457,12 +2198,12 @@ namespace Common { // NOLINT static void JsonSerialize(rapidjson::Value& outValue, rapidjson::Document::AllocatorType& inAllocator, const T& inValue) { - JsonSerializeDyn(outValue, inAllocator, Mirror::Class::Get(), Mirror::Internal::ForwardAsArgument(inValue)); + JsonSerializeDyn(outValue, inAllocator, Mirror::Class::Get(), Mirror::ForwardAsArg(inValue)); } static void JsonDeserialize(const rapidjson::Value& inValue, T& outValue) { - JsonDeserializeDyn(inValue, Mirror::Class::Get(), Mirror::Internal::ForwardAsArgument(outValue)); + JsonDeserializeDyn(inValue, Mirror::Class::Get(), Mirror::ForwardAsArg(outValue)); } }; @@ -1824,7 +2565,7 @@ namespace Common { // NOLINT static std::string ToString(const T& inValue) { - return ToStringDyn(Mirror::Class::Get(), Mirror::Internal::ForwardAsArgument(inValue)); + return ToStringDyn(Mirror::Class::Get(), Mirror::ForwardAsArg(inValue)); } }; @@ -2013,6 +2754,26 @@ namespace Mirror { } } + template + void AnyRtti::CopyAssign(void* inThis, const void* inOther) + { + if constexpr (std::is_copy_assignable_v) { + *static_cast(inThis) = *static_cast(inOther); + } else { + QuickFailWithReason(std::format("type {} is no support copy assign", GetTypeInfo()->name)); + } + } + + template + void AnyRtti::MoveAssign(void* inThis, void* inOther) noexcept + { + if constexpr (std::is_move_assignable_v) { + *static_cast(inThis) = std::move(*static_cast(inOther)); + } else { + QuickFailWithReason(std::format("type {} is no support move assign", GetTypeInfo()->name)); + } + } + template bool AnyRtti::Equal(const void* inThis, const void* inOther) noexcept { @@ -2129,6 +2890,27 @@ namespace Mirror { return Common::ToString(*static_cast(inThis)); } + template + std::pair AnyRtti::GetTemplateViewRtti() + { + return { + TemplateViewRttiGetter::Id(), + TemplateViewRttiGetter::Get() + }; + } + + template + constexpr TemplateViewId TemplateViewRttiGetter::Id() + { + return 0; + } + + template + const void* TemplateViewRttiGetter::Get() + { + return nullptr; + } + template Any::Any(T&& inValue) { @@ -2321,6 +3103,13 @@ namespace Mirror { return dynamic_cast(As()); } + template + bool Any::CanAsTemplateView() const + { + Assert(!Empty()); + return rtti->getTemplateViewRtti().first == V::id; + } + template void Any::ConstructFromValue(T&& inValue) { @@ -2341,7 +3130,7 @@ namespace Mirror { arrayLength = 0; policy = std::is_const_v ? AnyPolicy::constRef : AnyPolicy::nonConstRef; rtti = &anyRttiImpl; - info = RefInfo(const_cast(&inRef.get()), sizeof(RawType)); + info = RefInfo(const_cast(std::addressof(inRef.get())), sizeof(RawType)); } template @@ -2391,6 +3180,14 @@ namespace Mirror { }); } + template + bool Argument::CanAsTemplateView() const + { + return Delegate([](auto&& value) -> decltype(auto) { + return value.template CanAsTemplateView(); + }); + } + template decltype(auto) Argument::Delegate(F&& inFunc) const { @@ -2408,6 +3205,62 @@ namespace Mirror { return inFunc(Any {}); } + template + Any ForwardAsAny(T&& value) + { + Internal::StaticCheckArgumentType(); + + if constexpr (std::is_lvalue_reference_v) { + return { std::ref(std::forward(value)) }; + } else { + return { std::forward(value) }; + } + } + + template + Argument ForwardAsArg(T&& value) + { + Internal::StaticCheckArgumentType(); + return ForwardAsAny(std::forward(value)); + } + + template + ArgumentList ForwardAsArgList(Args&&... args) + { + ArgumentList result; + result.reserve(sizeof...(args)); + (void) std::initializer_list { ([&]() -> void { + result.emplace_back(ForwardAsArg(std::forward(args))); + }(), 0)... }; + return result; + } + + template + Any ForwardAsAnyByValue(T&& value) + { + Internal::StaticCheckArgumentType(); + auto any = ForwardAsAny(std::forward(value)); + return any.IsMemoryHolder() ? any : any.Value(); + } + + template + Argument ForwardAsArgByValue(T&& value) + { + Internal::StaticCheckArgumentType(); + return { ForwardAsAnyByValue(std::forward(value)) }; + } + + template + ArgumentList ForwardAsArgListByValue(Args&&... args) + { + ArgumentList result; + result.reserve(sizeof...(args)); + (void) std::initializer_list { ([&]() -> void { + result.emplace_back(ForwardAsArgByValue(std::forward(args))); + }(), 0)... }; + return result; + } + template Id::Id(const char(&inName)[N]) : hash(Common::HashUtils::StrCrc32(inName)) @@ -2418,55 +3271,61 @@ namespace Mirror { template void Variable::Set(T&& value) const { - SetDyn(Internal::ForwardAsArgument(std::forward(value))); + SetDyn(ForwardAsArg(std::forward(value))); } template Any Function::Invoke(Args&&... args) const { - return InvokeDyn(Internal::ForwardAsArgumentList(std::forward(args)...)); + return InvokeDyn(ForwardAsArgList(std::forward(args)...)); } template Any Constructor::Construct(Args&&... args) const { - return ConstructDyn(Internal::ForwardAsArgumentList(std::forward(args)...)); + return ConstructDyn(ForwardAsArgList(std::forward(args)...)); } template Any Constructor::New(Args&&... args) const { - return NewDyn(Internal::ForwardAsArgumentList(std::forward(args)...)); + return NewDyn(ForwardAsArgList(std::forward(args)...)); } template Any Constructor::InplaceNew(Args&&... args) const { - return InplaceNewDyn(Internal::ForwardAsArgumentList(std::forward(args)...)); + return InplaceNewDyn(ForwardAsArgList(std::forward(args)...)); + } + + template + void Destructor::Destruct(C&& object) const + { + DestructDyn(ForwardAsArg(std::forward(object))); } template - void Destructor::Invoke(C&& object) const + void Destructor::Delete(C* object) const { - InvokeDyn(Internal::ForwardAsArgument(std::forward(object))); + DeleteDyn(ForwardAsArg(object)); } template void MemberVariable::Set(C&& object, T&& value) const { - SetDyn(Internal::ForwardAsArgument(std::forward(object)), Internal::ForwardAsArgument(std::forward(value))); + SetDyn(ForwardAsArg(std::forward(object)), ForwardAsArg(std::forward(value))); } template Any MemberVariable::Get(C&& object) const { - return GetDyn(Internal::ForwardAsArgument(std::forward(object))); + return GetDyn(ForwardAsArg(std::forward(object))); } template Any MemberFunction::Invoke(C&& object, Args&&... args) const { - return InvokeDyn(Internal::ForwardAsArgument(std::forward(object)), Internal::ForwardAsArgumentList(std::forward(args)...)); + return InvokeDyn(ForwardAsArg(std::forward(object)), ForwardAsArgList(std::forward(args)...)); } template @@ -2488,29 +3347,41 @@ namespace Mirror { } template - Any Class::Construct(Args&&... args) + Any Class::Construct(Args&&... args) const { - return ConstructDyn(Internal::ForwardAsArgumentList(std::forward(args)...)); + return ConstructDyn(ForwardAsArgList(std::forward(args)...)); } template - Any Class::New(Args&&... args) + Any Class::New(Args&&... args) const { - return NewDyn(Internal::ForwardAsArgumentList(std::forward(args)...)); + return NewDyn(ForwardAsArgList(std::forward(args)...)); } template - Any Class::InplaceNew(void* ptr, Args&&... args) + Any Class::InplaceNew(void* ptr, Args&&... args) const { - return InplaceNewDyn(ptr, Internal::ForwardAsArgumentList(std::forward(args)...)); + return InplaceNewDyn(ptr, ForwardAsArgList(std::forward(args)...)); } - template - const Enum* Enum::Find() + template + void Class::Destruct(C&& object) const { - auto iter = typeToIdMap.find(Mirror::GetTypeInfo()->id); - if (iter == typeToIdMap.end()) { - return nullptr; + DestructDyn(ForwardAsArg(std::forward(object))); + } + + template + void Class::Delete(C* object) const + { + DeleteDyn(ForwardAsArg(object)); + } + + template + const Enum* Enum::Find() + { + auto iter = typeToIdMap.find(Mirror::GetTypeInfo()->id); + if (iter == typeToIdMap.end()) { + return nullptr; } return Find(iter->second); } @@ -2526,30 +3397,636 @@ namespace Mirror { template void EnumValue::Set(E& value) const { - SetDyn(Internal::ForwardAsArgument(value)); + SetDyn(ForwardAsArg(value)); } template bool EnumValue::Compare(const E& value) const { - return Compare(Internal::ForwardAsArgument(value)); + return Compare(ForwardAsArg(value)); } template bool Enum::HasValue(E inValue) const { - return HasValue(Internal::ForwardAsArgument(inValue)); + return HasValue(ForwardAsArg(inValue)); } template const EnumValue* Enum::FindValue(E inValue) const { - return FindValue(Internal::ForwardAsArgument(inValue)); + return FindValue(ForwardAsArg(inValue)); } template const EnumValue& Enum::GetValue(E inValue) const { - return GetValue(Internal::ForwardAsArgument(inValue)); + return GetValue(ForwardAsArg(inValue)); } -} + + template + const TypeInfo* StdOptionalViewRtti::GetBaseType() + { + return GetTypeInfo(); + } + + template + bool StdOptionalViewRtti::HasValue(const Argument& inArg) + { + return inArg.As&>().has_value(); + } + + template + Any StdOptionalViewRtti::GetValue(const Argument& inArg) + { + return std::ref(inArg.As&>().value()); + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdOptionalViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdOptionalViewRttiImpl; + } + + template + const TypeInfo* StdPairViewRtti::GetKeyType() + { + return GetTypeInfo(); + } + + template + const TypeInfo* StdPairViewRtti::GetValueType() + { + return GetTypeInfo(); + } + + template + Any StdPairViewRtti::GetKey(const Argument& inObj) + { + return { std::ref(inObj.As&>().first) }; + } + + template + Any StdPairViewRtti::GetValue(const Argument& inObj) + { + return { std::ref(inObj.As&>().second) }; + } + + template + Any StdPairViewRtti::GetConstKey(const Argument& inObj) + { + return { std::ref(inObj.As&>().first) }; + } + + template + Any StdPairViewRtti::GetConstValue(const Argument& inObj) + { + return { std::ref(inObj.As&>().second) }; + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdPairViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdPairViewRttiImpl; + } + + template + const TypeInfo* StdArrayViewRtti::GetElementType() + { + return GetTypeInfo(); + } + + template + size_t StdArrayViewRtti::GetSize() + { + return N; + } + + template + Any StdArrayViewRtti::GetElement(const Argument& inObj, size_t inIndex) + { + return { std::ref(inObj.As&>()[inIndex]) }; + } + + template + Any StdArrayViewRtti::GetConstElement(const Argument& inObj, size_t inIndex) + { + return { std::ref(inObj.As&>()[inIndex]) }; + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdArrayViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdArrayViewRttiImpl; + } + + template + const TypeInfo* StdVectorViewRtti::GetElementType() + { + return GetTypeInfo(); + } + + template + size_t StdVectorViewRtti::GetSize(const Argument& inObj) + { + return inObj.As&>().size(); + } + + template + Any StdVectorViewRtti::GetElement(const Argument& inObj, size_t inIndex) + { + if constexpr (std::is_same_v) { + return { inObj.As&>()[inIndex] }; + } else { + return { std::ref(inObj.As&>()[inIndex]) }; + } + } + + template + Any StdVectorViewRtti::GetConstElement(const Argument& inObj, size_t inIndex) + { + if constexpr (std::is_same_v) { + return { inObj.As&>()[inIndex] }; + } else { + return { std::ref(inObj.As&>()[inIndex]) }; + } + } + + template + Any StdVectorViewRtti::EmplaceBack(const Argument& inObj, const Argument& inTempObj) + { + if constexpr (std::is_same_v) { + return { inObj.As&>().emplace_back(std::move(inTempObj.As())) }; + } else { + return { std::ref(inObj.As&>().emplace_back(std::move(inTempObj.As()))) }; + } + } + + template + void StdVectorViewRtti::Erase(const Argument& inObj, size_t inIndex) + { + auto& vec = inObj.As&>(); + vec.erase(vec.begin() + inIndex); + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdVectorViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdVectorViewRttiImpl; + } + + template + const TypeInfo* StdListViewRtti::GetElementType() + { + return GetTypeInfo(); + } + + template + size_t StdListViewRtti::GetSize(const Argument& inObj) + { + return inObj.As&>().size(); + } + + template + void StdListViewRtti::Traverse(const Argument& inObj, const std::function& inTraverser) + { + auto& list = inObj.As&>(); // NOLINT + for (auto& element : list) { + inTraverser(std::ref(element)); + } + } + + template + void StdListViewRtti::ConstTraverse(const Argument& inObj, const std::function& inTraverser) + { + const auto& list = inObj.As&>(); // NOLINT + for (const auto& element : list) { + inTraverser(std::ref(element)); + } + } + + template + Any StdListViewRtti::EmplaceFront(const Argument& inObj, const Argument& inTempObj) + { + T& elemRef = inObj.As&>().emplace_front(std::move(inTempObj.As())); + return { std::ref(elemRef) }; + } + + template + Any StdListViewRtti::EmplaceBack(const Argument& inObj, const Argument& inTempObj) + { + T& elemRef = inObj.As&>().emplace_back(std::move(inTempObj.As())); + return { std::ref(elemRef) }; + } + + template + Any StdListViewRtti::GetBeginIter(const Argument& inObj) + { + return { inObj.As&>().begin() }; + } + + template + Any StdListViewRtti::GetEndIter(const Argument& inObj) + { + return { inObj.As&>().end() }; + } + + template + Any StdListViewRtti::GetBeginConstIter(const Argument& inObj) + { + return { inObj.As&>().begin() }; + } + + template + Any StdListViewRtti::GetEndConstIter(const Argument& inObj) + { + return { inObj.As&>().end() }; + } + + template + Any StdListViewRtti::GetNextIter(const Argument& inIter) + { + using Iter = typename std::list::iterator; + return { ++inIter.As() }; + } + + template + Any StdListViewRtti::GetLastIter(const Argument& inIter) + { + using Iter = typename std::list::iterator; + return { --inIter.As() }; + } + + template + Any StdListViewRtti::GetNextConstIter(const Argument& inIter) + { + using ConstIter = typename std::list::const_iterator; + return { ++inIter.As() }; + } + + template + Any StdListViewRtti::GetLastConstIter(const Argument& inIter) + { + using ConstIter = typename std::list::const_iterator; + return { --inIter.As() }; + } + + template + Any StdListViewRtti::DerefIter(const Argument& inIter) + { + using Iter = typename std::list::iterator; + return { std::ref(*inIter.As()) }; + } + + template + Any StdListViewRtti::DerefConstIter(const Argument& inIter) + { + using ConstIter = typename std::list::const_iterator; + return { std::ref(*inIter.As()) }; + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdListViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdListViewRttiImpl; + } + + template + const TypeInfo* StdUnorderedSetViewRtti::GetElementType() + { + return GetTypeInfo(); + } + + template + size_t StdUnorderedSetViewRtti::GetSize(const Argument& inObj) + { + return inObj.As&>().size(); + } + + template + void StdUnorderedSetViewRtti::Traverse(const Argument& inObj, const std::function& inTraverser) + { + auto& set = inObj.As&>(); // NOLINT + for (auto& element : set) { + inTraverser(std::ref(element)); + } + } + + template + void StdUnorderedSetViewRtti::ConstTraverse(const Argument& inObj, const std::function& inTraverser) + { + const auto& set = inObj.As&>(); // NOLINT + for (const auto& element : set) { + inTraverser(std::ref(element)); + } + } + + template + bool StdUnorderedSetViewRtti::Contains(const Argument& inObj, const Argument& inElement) + { + return inObj.As&>().contains(inElement.As()); + } + + template + void StdUnorderedSetViewRtti::Emplace(const Argument& inObj, const Argument& inTempObj) + { + inObj.As&>().emplace(std::move(inTempObj.As())); + } + + template + void StdUnorderedSetViewRtti::Erase(const Argument& inObj, const Argument& inElement) + { + inObj.As&>().erase(inElement.As()); + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdUnorderedSetViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdUnorderedSetViewRttiImpl; + } + + template + const TypeInfo* StdSetViewRtti::GetElementType() + { + return GetTypeInfo(); + } + + template + size_t StdSetViewRtti::GetSize(const Argument& inObj) + { + return inObj.As&>().size(); + } + + template + void StdSetViewRtti::Traverse(const Argument& inObj, const std::function& inTraverser) + { + const auto& set = inObj.As&>(); // NOLINT + for (const auto& element : set) { + inTraverser(std::ref(element)); + } + } + + template + bool StdSetViewRtti::Contains(const Argument& inObj, const Argument& inElement) + { + return inObj.As&>().contains(inElement.As()); + } + + template + void StdSetViewRtti::Emplace(const Argument& inObj, const Argument& inTempObj) + { + inObj.As&>().emplace(inTempObj.As()); + } + + template + void StdSetViewRtti::Erase(const Argument& inObj, const Argument& inElement) + { + inObj.As&>().erase(inElement.As()); + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdSetViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdSetViewRttiImpl; + } + + template + const TypeInfo* StdUnorderedMapViewRtti::GetKeyType() + { + return GetTypeInfo(); + } + + template + const TypeInfo* StdUnorderedMapViewRtti::GetValueType() + { + return GetTypeInfo(); + } + + template + size_t StdUnorderedMapViewRtti::GetSize(const Argument& inObj) + { + return inObj.As&>().size(); + } + + template + Any StdUnorderedMapViewRtti::At(const Argument& inObj, const Argument& inKey) + { + return { std::ref(inObj.As&>().at(inKey.As())) }; + } + + template + Any StdUnorderedMapViewRtti::GetOrAdd(const Argument& inObj, const Argument& inKey) + { + return { std::ref(inObj.As&>()[inKey.As()]) }; + } + + template + void StdUnorderedMapViewRtti::Traverse(const Argument& inObj, const std::function& inTraverser) + { + auto& map = inObj.As&>(); // NOLINT + for (auto& pair : map) { + inTraverser(std::ref(pair.first), std::ref(pair.second)); + } + } + + template + void StdUnorderedMapViewRtti::ConstTraverse(const Argument& inObj, const std::function& inTraverser) + { + const auto& map = inObj.As&>(); // NOLINT + for (const auto& pair : map) { + inTraverser(std::ref(pair.first), std::ref(pair.second)); + } + } + + template + bool StdUnorderedMapViewRtti::Contains(const Argument& inObj, const Argument& inKey) + { + return inObj.As&>().contains(inKey.As()); + } + + template + void StdUnorderedMapViewRtti::Emplace(const Argument& inObj, const Argument& inTempKey, const Argument& inTempValue) + { + inObj.As&>().emplace(std::move(inTempKey.As()), std::move(inTempValue.As())); + } + + template + void StdUnorderedMapViewRtti::Erase(const Argument& inObj, const Argument& inKey) + { + inObj.As&>().erase(inKey.As()); + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdUnorderedMapViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdUnorderedMapViewRttiImpl; + } + + template + const TypeInfo* StdMapViewRtti::GetKeyType() + { + return GetTypeInfo(); + } + + template + const TypeInfo* StdMapViewRtti::GetValueType() + { + return GetTypeInfo(); + } + + template + size_t StdMapViewRtti::GetSize(const Argument& inObj) + { + return inObj.As&>().size(); + } + + template + Any StdMapViewRtti::At(const Argument& inObj, const Argument& inKey) + { + return { std::ref(inObj.As&>().at(inKey.As())) }; + } + + template + Any StdMapViewRtti::GetOrAdd(const Argument& inObj, const Argument& inKey) + { + return { std::ref(inObj.As&>()[inKey.As()]) }; + } + + template + void StdMapViewRtti::Traverse(const Argument& inObj, const std::function& inTraverser) + { + auto& map = inObj.As&>(); // NOLINT + for (auto& pair : map) { + inTraverser(std::ref(pair.first), std::ref(pair.second)); + } + } + + template + void StdMapViewRtti::ConstTraverse(const Argument& inObj, const std::function& inTraverser) + { + const auto& map = inObj.As&>(); // NOLINT + for (const auto& pair : map) { + inTraverser(std::ref(pair.first), std::ref(pair.second)); + } + } + + template + bool StdMapViewRtti::Contains(const Argument& inObj, const Argument& inKey) + { + return inObj.As&>().contains(inKey.As()); + } + + template + void StdMapViewRtti::Emplace(const Argument& inObj, const Argument& inTempKey, const Argument& inTempValue) + { + inObj.As&>().emplace(std::move(inTempKey.As()), std::move(inTempValue.As())); + } + + template + void StdMapViewRtti::Erase(const Argument& inObj, const Argument& inKey) + { + inObj.As&>().erase(inKey.As()); + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdMapViewRtti::id; + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdMapViewRttiImpl; + } + + template + size_t StdTupleRtti::GetSize() + { + return std::tuple_size_v>(); + } + + template + const TypeInfo* StdTupleRtti::GetElementType(size_t inIndex) + { + static std::array types = { GetTypeInfo()... }; + Assert(inIndex < types.size()); + return types[inIndex]; + } + + template + Any StdTupleRtti::GetElement(const Argument& inObj, size_t inIndex) + { + static std::array, sizeof...(T)> getters = Internal::BuildTupleGetterArray(std::make_index_sequence {}); + Assert(inIndex < getters.size()); + return getters[inIndex](inObj); + } + + template + void StdTupleRtti::Visit(const Argument& inObj, const std::function& inVisitor) + { + std::visit([&](auto&& inElement) -> void { // NOLINT + inVisitor(ForwardAsAny(std::forward(inElement))); + }, inObj.As&>()); + } + + template + constexpr TemplateViewId TemplateViewRttiGetter>::Id() + { + return StdTupleRtti::GetSize(); + } + + template + const void* TemplateViewRttiGetter>::Get() + { + return &stdTupleRttiImpl; + } +} // namespace Mirror diff --git a/Engine/Source/Mirror/Include/Mirror/Registry.h b/Engine/Source/Mirror/Include/Mirror/Registry.h index 11a25d0f..d9d0ce2c 100644 --- a/Engine/Source/Mirror/Include/Mirror/Registry.h +++ b/Engine/Source/Mirror/Include/Mirror/Registry.h @@ -250,15 +250,15 @@ namespace Mirror { params.argRemovePointerTypeInfos = { GetTypeInfo>()... }; params.stackConstructor = [](const ArgumentList& args) -> Any { Assert(argsTupleSize == args.size()); - return Internal::ForwardAsAny(Internal::InvokeConstructorStack(args, std::make_index_sequence {})); + return ForwardAsAny(Internal::InvokeConstructorStack(args, std::make_index_sequence {})); }; params.heapConstructor = [](const ArgumentList& args) -> Any { Assert(argsTupleSize == args.size()); - return Internal::ForwardAsAny(Internal::InvokeConstructorNew(args, std::make_index_sequence {})); + return ForwardAsAny(Internal::InvokeConstructorNew(args, std::make_index_sequence {})); }; params.inplaceConstructor = [](void* ptr, const ArgumentList& args) -> Any { Assert(argsTupleSize == args.size()); - return Internal::ForwardAsAny(Internal::InvokeConstructorInplace(ptr, args, std::make_index_sequence {})); + return ForwardAsAny(Internal::InvokeConstructorInplace(ptr, args, std::make_index_sequence {})); }; return MetaDataRegistry::SetContext(&clazz.EmplaceConstructor(inId, std::move(params))); @@ -319,7 +319,7 @@ namespace Mirror { Internal::InvokeFunction(args, std::make_index_sequence {}); return {}; } else { - return Internal::ForwardAsAny(Internal::InvokeFunction(args, std::make_index_sequence {})); + return ForwardAsAny(Internal::InvokeFunction(args, std::make_index_sequence {})); } }; @@ -383,7 +383,7 @@ namespace Mirror { Internal::InvokeMemberFunction(object.As(), args, std::make_index_sequence {}); return {}; } else { - return Internal::ForwardAsAny(Internal::InvokeMemberFunction(object.As(), args, std::make_index_sequence {})); + return ForwardAsAny(Internal::InvokeMemberFunction(object.As(), args, std::make_index_sequence {})); } }; @@ -442,7 +442,7 @@ namespace Mirror { Internal::InvokeFunction(args, std::make_index_sequence {}); return {}; } else { - return Internal::ForwardAsAny(Internal::InvokeFunction(args, std::make_index_sequence {})); + return ForwardAsAny(Internal::InvokeFunction(args, std::make_index_sequence {})); } }; @@ -502,6 +502,9 @@ namespace Mirror { return &Mirror::Class::Get(); } }; + params.inplaceGetter = [](void* ptr) -> Any { + return { std::ref(*static_cast(ptr)) }; + }; if constexpr (std::is_default_constructible_v) { params.defaultObjectCreator = []() -> Any { return { C() }; @@ -512,9 +515,11 @@ namespace Mirror { detorParams.owner = inId; detorParams.access = DetorAccess; detorParams.destructor = [](const Argument& object) -> void { - Assert(!object.IsConstRef()); object.As().~C(); }; + detorParams.deleter = [](const Argument& object) -> void { + delete object.As(); + }; params.destructorParams = detorParams; } if constexpr (std::is_default_constructible_v) { diff --git a/Engine/Source/Mirror/Src/Mirror.cpp b/Engine/Source/Mirror/Src/Mirror.cpp index f769b4e5..3eff2143 100644 --- a/Engine/Source/Mirror/Src/Mirror.cpp +++ b/Engine/Source/Mirror/Src/Mirror.cpp @@ -130,6 +130,66 @@ namespace Mirror { return *this; } + Any& Any::CopyAssign(Any& inOther) + { + Assert(!IsConstRef()); + PerformCopyAssign(inOther); + return *this; + } + + Any& Any::CopyAssign(const Any& inOther) + { + Assert(!IsConstRef()); + PerformCopyAssign(inOther); + return *this; + } + + Any& Any::MoveAssign(Any& inOther) noexcept + { + Assert(!IsConstRef()); + Assert(!inOther.IsRef() || inOther.IsNonConstRef()); + PerformMoveAssign(inOther); + return *this; + } + + Any& Any::MoveAssign(const Any& inOther) noexcept + { + Assert(!IsConstRef()); + Assert(inOther.IsNonConstRef()); + PerformMoveAssign(inOther); + return *this; + } + + const Any& Any::CopyAssign(Any& inOther) const + { + Assert(IsNonConstRef()); + PerformCopyAssign(inOther); + return *this; + } + + const Any& Any::CopyAssign(const Any& inOther) const + { + Assert(IsNonConstRef()); + PerformCopyAssign(inOther); + return *this; + } + + const Any& Any::MoveAssign(Any& inOther) const noexcept + { + Assert(IsNonConstRef()); + Assert(!inOther.IsRef() || inOther.IsNonConstRef()); + PerformMoveAssign(inOther); + return *this; + } + + const Any& Any::MoveAssign(const Any& inOther) const noexcept + { + Assert(IsNonConstRef()); + Assert(inOther.IsNonConstRef()); + PerformMoveAssign(inOther); + return *this; + } + void Any::PerformCopyConstruct(const Any& inOther) { arrayLength = inOther.arrayLength; @@ -189,7 +249,7 @@ namespace Mirror { } } - void Any::PerformMoveConstruct(Any&& inOther) + void Any::PerformMoveConstruct(Any&& inOther) noexcept { arrayLength = inOther.arrayLength; policy = inOther.policy; @@ -210,11 +270,35 @@ namespace Mirror { } } + void Any::PerformCopyAssign(const Any& inOther) const + { + Assert(!Empty() && !inOther.Empty() && arrayLength == inOther.arrayLength && rtti == inOther.rtti); + + for (auto i = 0; i < ElementNum(); i++) { + rtti->copyAssign(Data(i), inOther.Data(i)); + } + } + + void Any::PerformMoveAssign(const Any& inOther) const noexcept + { + Assert(!Empty() && !inOther.Empty() && arrayLength == inOther.arrayLength && rtti == inOther.rtti); + + for (auto i = 0; i < ElementNum(); i++) { + rtti->moveAssign(Data(i), inOther.Data(i)); + } + } + uint32_t Any::ElementNum() const { return std::max(1u, arrayLength); } + TemplateViewRttiPtr Any::GetTemplateViewRtti() const + { + Assert(!Empty()); + return rtti->getTemplateViewRtti().second; + } + bool Any::IsArray() const { return arrayLength > 0; @@ -641,6 +725,13 @@ namespace Mirror { return *this; } + TemplateViewRttiPtr Argument::GetTemplateViewRtti() const + { + return Delegate([](auto&& value) -> decltype(auto) { + return value.GetTemplateViewRtti(); + }); + } + bool Argument::IsMemoryHolder() const { return Delegate([](auto&& value) -> decltype(auto) { @@ -1003,6 +1094,7 @@ namespace Mirror { , owner(std::move(params.owner)) , access(params.access) , destructor(std::move(params.destructor)) + , deleter(std::move(params.deleter)) { } @@ -1030,11 +1122,16 @@ namespace Mirror { return access; } - void Destructor::InvokeDyn(const Argument& argument) const + void Destructor::DestructDyn(const Argument& argument) const { destructor(argument); } + void Destructor::DeleteDyn(const Argument& argument) const + { + deleter(argument); + } + MemberVariable::MemberVariable(ConstructParams&& params) : ReflNode(std::move(params.id)) , owner(std::move(params.owner)) @@ -1235,6 +1332,7 @@ namespace Mirror { , typeInfo(params.typeInfo) , memorySize(params.memorySize) , baseClassGetter(std::move(params.baseClassGetter)) + , inplaceGetter(std::move(params.inplaceGetter)) { CreateDefaultObject(params.defaultObjectCreator); if (params.destructorParams.has_value()) { @@ -1245,6 +1343,8 @@ namespace Mirror { } } + Class::~Class() = default; + bool Class::Has(const Id& inId) { const auto& classes = Registry::Get().classes; @@ -1333,7 +1433,10 @@ namespace Mirror { return result; } - Class::~Class() = default; + Any Class::InplaceGetObject(void* ptr) const + { + return inplaceGetter(ptr); + } void Class::ForEachStaticVariable(const VariableTraverser& func) const { @@ -1482,7 +1585,10 @@ namespace Mirror { const Constructor* Class::FindSuitableConstructor(const ArgumentList& arguments) const { - for (const auto& [constructorName, constructor] : constructors) { + std::vector> candidateAndRates; + candidateAndRates.reserve(constructors.size()); + + for (const auto& constructor : constructors | std::views::values) { const auto& argTypeInfos = constructor.GetArgTypeInfos(); const auto& argRemoveRefTypeInfos = constructor.GetArgRemoveRefTypeInfos(); const auto& argRemovePointerTypeInfos = constructor.GetArgRemovePointerTypeInfos(); @@ -1491,12 +1597,13 @@ namespace Mirror { continue; } - // TODO prefer rvalue params version + uint32_t rate = 0; bool bSuitable = true; for (auto i = 0; i < arguments.size(); i++) { const TypeInfoCompact srcType { arguments[i].Type(), arguments[i].RemoveRefType(), arguments[i].RemovePointerType() }; // NOLINT const TypeInfoCompact dstType { argTypeInfos[i], argRemoveRefTypeInfos[i], argRemovePointerTypeInfos[i] }; // NOLINT if (Convertible(srcType, dstType)) { + rate += dstType.raw->isRValueReference ? 2 : 1; continue; } @@ -1505,10 +1612,11 @@ namespace Mirror { } if (bSuitable) { - return &constructor; + candidateAndRates.emplace_back(&constructor, rate); } } - return nullptr; + std::ranges::sort(candidateAndRates, [](const auto& lhs, const auto& rhs) -> bool { return lhs.second < rhs.second; }); + return candidateAndRates.empty() ? nullptr : candidateAndRates.back().first; } Any Class::ConstructDyn(const ArgumentList& arguments) const @@ -1532,6 +1640,16 @@ namespace Mirror { return constructor->InplaceNewDyn(ptr, arguments); } + void Class::DestructDyn(const Argument& argument) const + { + GetDestructor().DestructDyn(argument); + } + + void Class::DeleteDyn(const Argument& argument) const + { + GetDestructor().DeleteDyn(argument); + } + const Constructor* Class::FindConstructor(const Id& inId) const { const auto iter = constructors.find(inId); @@ -1798,4 +1916,434 @@ namespace Mirror { values.emplace(inId, EnumValue(std::move(inParams))); return values.at(inId); } -} + + StdOptionalView::StdOptionalView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdOptionalView::BaseType() const + { + return rtti->getBaseType(); + } + + bool StdOptionalView::HasValue() const + { + return rtti->hasValue(obj); + } + + Any StdOptionalView::GetValue() const + { + return rtti->getValue(obj); + } + + StdPairView::StdPairView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdPairView::GetKeyType() const + { + return rtti->getKeyType(); + } + + const TypeInfo* StdPairView::GetValueType() const + { + return rtti->getValueType(); + } + + Any StdPairView::GetKey() const + { + return rtti->getKey(obj); + } + + Any StdPairView::GetValue() const + { + return rtti->getValue(obj); + } + + Any StdPairView::GetConstKey() const + { + return rtti->getConstKey(obj); + } + + Any StdPairView::GetConstValue() const + { + return rtti->getConstValue(obj); + } + + StdArrayView::StdArrayView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdArrayView::GetElementType() const + { + return rtti->getElementType(); + } + + size_t StdArrayView::GetSize() const + { + return rtti->getSize(); + } + + Any StdArrayView::GetElement(size_t inIndex) const + { + return rtti->getElement(obj, inIndex); + } + + Any StdArrayView::GetConstElement(size_t inIndex) const + { + return rtti->getConstElement(obj, inIndex); + } + + StdVectorView::StdVectorView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdVectorView::ElementType() const + { + return rtti->getElementType(); + } + + size_t StdVectorView::GetSize() const + { + return rtti->getSize(obj); + } + + Any StdVectorView::GetElement(size_t inIndex) const + { + return rtti->getElement(obj, inIndex); + } + + Any StdVectorView::GetConstElement(size_t inIndex) const + { + return rtti->getConstElement(obj, inIndex); + } + + Any StdVectorView::EmplaceBack(const Argument& inNewObj) const + { + return rtti->emplaceBack(obj, inNewObj); + } + + void StdVectorView::Erase(size_t inIndex) const + { + rtti->erase(obj, inIndex); + } + + StdListView::StdListView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdListView::GetElementType() const + { + return rtti->getElementType(); + } + + size_t StdListView::GetSize() const + { + return rtti->getSize(obj); + } + + void StdListView::Traverse(const ElementTraverser& inTraverser) const + { + rtti->traverse(obj, inTraverser); + } + + void StdListView::ConstTraverse(const ElementTraverser& inTraverser) const + { + rtti->traverse(obj, inTraverser); + } + + Any StdListView::EmplaceFront(const Argument& inTempObj) const + { + return rtti->emplaceFront(obj, inTempObj); + } + + Any StdListView::EmplaceBack(const Argument& inTempObj) const + { + return rtti->emplaceBack(obj, inTempObj); + } + + Any StdListView::GetBeginIter() const + { + return rtti->getBeginIter(obj); + } + + Any StdListView::GetEndIter() const + { + return rtti->getEndIter(obj); + } + + Any StdListView::GetBeginConstIter() const + { + return rtti->getBeginConstIter(obj); + } + + Any StdListView::GetEndConstIter() const + { + return rtti->getEndConstIter(obj); + } + + Any StdListView::GetNextIter(const Argument& inIter) const + { + return rtti->getNextIter(inIter); + } + + Any StdListView::GetLastIter(const Argument& inIter) const + { + return rtti->getLastIter(inIter); + } + + Any StdListView::GetNextConstIter(const Argument& inIter) const + { + return rtti->getNextConstIter(inIter); + } + + Any StdListView::GetLastConstIter(const Argument& inIter) const + { + return rtti->getLastConstIter(inIter); + } + + Any StdListView::DerefIter(const Argument& inIter) const + { + return rtti->derefIter(inIter); + } + + Any StdListView::DerefConstIter(const Argument& inIter) const + { + return rtti->derefConstIter(inIter); + } + + StdUnorderedSetView::StdUnorderedSetView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdUnorderedSetView::GetElementType() const + { + return rtti->getElementType(); + } + + size_t StdUnorderedSetView::GetSize() const + { + return rtti->getSize(obj); + } + + void StdUnorderedSetView::Traverse(const ElementTraverser& inTraverser) const + { + rtti->traverse(obj, inTraverser); + } + + void StdUnorderedSetView::ConstTraverse(const ElementTraverser& inTraverser) const + { + rtti->constTraverse(obj, inTraverser); + } + + bool StdUnorderedSetView::Contains(const Argument& inElement) const + { + return rtti->contains(obj, inElement); + } + + void StdUnorderedSetView::Emplace(const Argument& inTempObj) const + { + rtti->emplace(obj, inTempObj); + } + + void StdUnorderedSetView::Erase(const Argument& inElement) const + { + rtti->erase(obj, inElement); + } + + StdSetView::StdSetView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdSetView::GetElementType() const + { + return rtti->getElementType(); + } + + size_t StdSetView::GetSize() const + { + return rtti->getSize(obj); + } + + void StdSetView::Traverse(const ElementTraverser& inTraverser) const + { + rtti->traverse(obj, inTraverser); + } + + bool StdSetView::Contains(const Argument& inElement) const + { + return rtti->contains(obj, inElement); + } + + void StdSetView::Emplace(const Argument& inTempObj) const + { + rtti->emplace(obj, inTempObj); + } + + void StdSetView::Erase(const Argument& inElement) const + { + rtti->erase(obj, inElement); + } + + StdUnorderedMapView::StdUnorderedMapView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdUnorderedMapView::GetKeyType() const + { + return rtti->getKeyType(); + } + + const TypeInfo* StdUnorderedMapView::GetValueType() const + { + return rtti->getValueType(); + } + + size_t StdUnorderedMapView::GetSize() const + { + return rtti->getSize(obj); + } + + Any StdUnorderedMapView::At(const Argument& inKey) const + { + return rtti->at(obj, inKey); + } + + Any StdUnorderedMapView::GetOrAdd(const Argument& inKey) const + { + return rtti->getOrAdd(obj, inKey); + } + + void StdUnorderedMapView::Traverse(const PairTraverser& inTraverser) const + { + rtti->traverse(obj, inTraverser); + } + + void StdUnorderedMapView::ConstTraverse(const PairTraverser& inTraverser) const + { + rtti->constTraverse(obj, inTraverser); + } + + bool StdUnorderedMapView::Contains(const Argument& inKey) const + { + return rtti->contains(obj, inKey); + } + + void StdUnorderedMapView::Emplace(const Argument& inTempKey, const Argument& inTempValue) const + { + rtti->emplace(obj, inTempKey, inTempValue); + } + + void StdUnorderedMapView::Erase(const Argument& inKey) const + { + rtti->erase(obj, inKey); + } + + StdMapView::StdMapView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + const TypeInfo* StdMapView::GetKeyType() const + { + return rtti->getKeyType(); + } + + const TypeInfo* StdMapView::GetValueType() const + { + return rtti->getValueType(); + } + + size_t StdMapView::GetSize() const + { + return rtti->getSize(obj); + } + + Any StdMapView::At(const Argument& inKey) const + { + return rtti->at(obj, inKey); + } + + Any StdMapView::GetOrAdd(const Argument& inKey) const + { + return rtti->getOrAdd(obj, inKey); + } + + void StdMapView::Traverse(const PairTraverser& inTraverser) const + { + rtti->traverse(obj, inTraverser); + } + + void StdMapView::ConstTraverse(const PairTraverser& inTraverser) const + { + rtti->constTraverse(obj, inTraverser); + } + + bool StdMapView::Contains(const Argument& inKey) const + { + return rtti->contains(obj, inKey); + } + + void StdMapView::Emplace(const Argument& inTempKey, const Argument& inTempValue) const + { + rtti->emplace(obj, inTempKey, inTempValue); + } + + void StdMapView::Erase(const Argument& inKey) const + { + rtti->erase(obj, inKey); + } + + StdTupleView::StdTupleView(const Argument& inObj) + : obj(inObj) + { + Assert(inObj.CanAsTemplateView()); + rtti = static_cast(inObj.GetTemplateViewRtti()); + } + + size_t StdTupleView::GetSize() const + { + return rtti->getSize(); + } + + const TypeInfo* StdTupleView::GetElementType(size_t inIndex) const + { + return rtti->getElementType(inIndex); + } + + Any StdTupleView::GetElement(size_t inIndex) const + { + return rtti->getElement(obj, inIndex); + } + + void StdTupleView::Visit(const Visitor& inVisitor) const + { + rtti->visit(obj, inVisitor); + } +} // namespace Mirror diff --git a/Engine/Source/Mirror/Test/AnyTest.cpp b/Engine/Source/Mirror/Test/AnyTest.cpp index 03e913be..caac04df 100644 --- a/Engine/Source/Mirror/Test/AnyTest.cpp +++ b/Engine/Source/Mirror/Test/AnyTest.cpp @@ -69,6 +69,38 @@ AnyMoveCtorTest::AnyMoveCtorTest(AnyMoveCtorTest&& inOther) noexcept moveTime++; } +AnyCopyAssignTest::AnyCopyAssignTest() + : called(false) +{ +} + +AnyCopyAssignTest::AnyCopyAssignTest(AnyCopyAssignTest&& inOther) noexcept + : called(inOther.called) +{ +} + +AnyCopyAssignTest& AnyCopyAssignTest::operator=(const AnyCopyAssignTest& inOther) +{ + called = true; + return *this; +} + +AnyMoveAssignTest::AnyMoveAssignTest() + : called(false) +{ +} + +AnyMoveAssignTest::AnyMoveAssignTest(AnyMoveAssignTest&& inOther) noexcept + : called(inOther.called) +{ +} + +AnyMoveAssignTest& AnyMoveAssignTest::operator=(AnyMoveAssignTest&& inOther) noexcept +{ + called = true; + return *this; +} + bool AnyBasicTest::operator==(const AnyBasicTest& inRhs) const { return a == inRhs.a @@ -235,6 +267,26 @@ TEST(AnyTest, MoveAssignTest) ASSERT_EQ(a0.TypeId(), a1.TypeId()); } +TEST(AnyTest, ValueCopyAssignTest) +{ + Any a0 = AnyCopyAssignTest(); + ASSERT_EQ(a0.As().called, false); + + Any a1 = AnyCopyAssignTest(); + a0.CopyAssign(a1); + ASSERT_EQ(a0.As().called, true); +} + +TEST(AnyTest, ValueMoveAssignTest) +{ + Any a0 = AnyMoveAssignTest(); + ASSERT_EQ(a0.As().called, false); + + Any a1 = AnyMoveAssignTest(); + a0.MoveAssign(a1); + ASSERT_EQ(a0.As().called, true); +} + TEST(AnyTest, ValueAssignTest) { Any a0 = 1; @@ -1230,3 +1282,8 @@ TEST(AnyTest, ArrayTest) ASSERT_EQ(a6.ArrayLength(), sizeof(v0) / sizeof(int)); ASSERT_EQ(a6[1].As(), 2); } + +TEST(AnyTest, AnyViewTest) +{ + // TODO +} diff --git a/Engine/Source/Mirror/Test/AnyTest.h b/Engine/Source/Mirror/Test/AnyTest.h index cfd0d1d4..a91687be 100644 --- a/Engine/Source/Mirror/Test/AnyTest.h +++ b/Engine/Source/Mirror/Test/AnyTest.h @@ -34,6 +34,22 @@ struct AnyMoveCtorTest { uint8_t& moveTime; }; +struct AnyCopyAssignTest { + AnyCopyAssignTest(); + AnyCopyAssignTest(AnyCopyAssignTest&& inOther) noexcept; + AnyCopyAssignTest& operator=(const AnyCopyAssignTest& inOther); + + bool called; +}; + +struct AnyMoveAssignTest { + AnyMoveAssignTest(); + AnyMoveAssignTest(AnyMoveAssignTest&& inOther) noexcept; + AnyMoveAssignTest& operator=(AnyMoveAssignTest&& inOther) noexcept; + + bool called; +}; + struct AnyBasicTest { int a; float b; diff --git a/Engine/Source/Mirror/Test/RegistryTest.cpp b/Engine/Source/Mirror/Test/RegistryTest.cpp index a473dcc9..17afdce1 100644 --- a/Engine/Source/Mirror/Test/RegistryTest.cpp +++ b/Engine/Source/Mirror/Test/RegistryTest.cpp @@ -159,10 +159,10 @@ TEST(RegistryTest, ClassTest) const auto& b = clazz.GetMemberVariable("b"); auto object = constructor.New(1, 2); - Mirror::Any objectRef = *object.As(); + Mirror::Any objectRef = object.Deref(); ASSERT_EQ(a.GetDyn(objectRef).As(), 1); ASSERT_EQ(b.GetDyn(objectRef).As(), 2); - destructor.InvokeDyn(objectRef); + destructor.DeleteDyn(object); } { diff --git a/Engine/Source/Runtime/Include/Runtime/Asset.h b/Engine/Source/Runtime/Include/Runtime/Asset.h index 13aff30d..488f9c98 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset.h @@ -321,7 +321,7 @@ namespace Runtime { template void AsyncLoad(const Core::Uri& uri, const OnAssetLoaded& onAssetLoaded) { - threadPool.EmplaceTask([this, uri, onAssetLoaded]() -> void { + threadPool.EmplaceTask([=]() -> void { AssetRef result = nullptr; { std::unique_lock lock(mutex);