From 605642ed9d1e2dff54fc3b6f4f980ed1937797d2 Mon Sep 17 00:00:00 2001 From: neeraj31285 Date: Fri, 5 Sep 2025 14:50:31 +0530 Subject: [PATCH 1/6] RObject Optimizations: refactor. --- ReflectionTemplateLib/access/inc/RObject.h | 7 ++++- ReflectionTemplateLib/access/inc/RObject.hpp | 26 ++++++++++++++++--- .../detail/inc/RObjectBuilder.h | 3 +++ .../detail/inc/RObjectBuilder.hpp | 22 +++++++++++++--- ReflectionTemplateLib/detail/inc/RObjectId.h | 24 ++--------------- .../detail/src/CMakeLists.txt | 1 - .../detail/src/RObjectId.cpp | 17 ------------ 7 files changed, 51 insertions(+), 49 deletions(-) delete mode 100644 ReflectionTemplateLib/detail/src/RObjectId.cpp diff --git a/ReflectionTemplateLib/access/inc/RObject.h b/ReflectionTemplateLib/access/inc/RObject.h index 945d230f..ae2d401b 100644 --- a/ReflectionTemplateLib/access/inc/RObject.h +++ b/ReflectionTemplateLib/access/inc/RObject.h @@ -45,11 +45,16 @@ namespace rtl mutable std::any m_object; mutable detail::RObjectId m_objectId; + mutable const std::vector* m_converters; + RObject(const RObject&) = default; - RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId); + RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId, + const std::vector& pConverters); static std::atomic& getInstanceCounter(); + std::size_t getConverterIndex(const std::size_t pToTypeId) const; + template std::pair createCopy() const; diff --git a/ReflectionTemplateLib/access/inc/RObject.hpp b/ReflectionTemplateLib/access/inc/RObject.hpp index 33bd2bcc..f0441ad0 100644 --- a/ReflectionTemplateLib/access/inc/RObject.hpp +++ b/ReflectionTemplateLib/access/inc/RObject.hpp @@ -24,21 +24,25 @@ namespace rtl { - inline RObject::RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId) + inline RObject::RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId, + const std::vector& pConverters) : m_getClone(std::forward(pCloner)) , m_object(std::forward(pObject)) , m_objectId(pRObjectId) + , m_converters(&pConverters) { } inline RObject::RObject(RObject&& pOther) noexcept : m_object(std::move(pOther.m_object)) , m_getClone(std::move(pOther.m_getClone)) , m_objectId(pOther.m_objectId) + , m_converters(pOther.m_converters) { // Explicitly clear moved-from source pOther.m_object.reset(); pOther.m_objectId.reset(); pOther.m_getClone = nullptr; + pOther.m_converters = nullptr; } inline std::atomic& RObject::getInstanceCounter() @@ -47,6 +51,20 @@ namespace rtl return instanceCounter; } + + inline std::size_t RObject::getConverterIndex(const std::size_t pToTypeId) const + { + if (m_objectId.m_containsAs != detail::EntityKind::None) { + for (std::size_t index = 0; index < m_converters->size(); index++) { + if ((*m_converters)[index].first == pToTypeId) { + return index; + } + } + } + return index_none; + } + + template inline bool RObject::canViewAs() const { @@ -57,7 +75,7 @@ namespace rtl } } const auto& typeId = detail::TypeId::get(); - return (m_objectId.m_typeId == typeId || m_objectId.getConverterIndex(typeId) != index_none); + return (m_objectId.m_typeId == typeId || getConverterIndex(typeId) != index_none); } } @@ -66,7 +84,7 @@ namespace rtl inline std::optional> RObject::performConversion(const std::size_t pIndex) const { detail::EntityKind newKind = detail::EntityKind::None; - const traits::Converter& convert = m_objectId.m_converters[pIndex].second; + const traits::Converter& convert = (*m_converters)[pIndex].second; const std::any& viewObj = convert(m_object, m_objectId.m_containsAs, newKind); const T* viewRef = detail::RObjExtractor::getPointer(viewObj, newKind); @@ -128,7 +146,7 @@ namespace rtl } else { - const std::size_t index = m_objectId.getConverterIndex(asTypeId); + const std::size_t index = getConverterIndex(asTypeId); if (index != index_none) { return performConversion(index); } diff --git a/ReflectionTemplateLib/detail/inc/RObjectBuilder.h b/ReflectionTemplateLib/detail/inc/RObjectBuilder.h index c458c635..7b130597 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectBuilder.h +++ b/ReflectionTemplateLib/detail/inc/RObjectBuilder.h @@ -26,6 +26,9 @@ namespace rtl::detail template static Cloner buildCloner(); + template + static const std::vector& getConverters(); + public: RObjectBuilder() = delete; diff --git a/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp b/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp index 499bb36c..1a9b4921 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp +++ b/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp @@ -54,6 +54,17 @@ namespace rtl::detail { } } + template + inline const std::vector& RObjectBuilder::getConverters() + { + // extract wrapper info. + using _W = traits::std_wrapper>; + // extract Un-Qualified raw type. + using _T = traits::raw_t>; + + return rtl::detail::ReflectCast<_T>::getConversions(); + } + template inline RObject RObjectBuilder::build(T&& pVal, const bool pIsConstCastSafe) @@ -66,27 +77,30 @@ namespace rtl::detail { static_assert(isRawPointer, "Invalid 'alloc' specified for non-pointer-type 'T'"); _T* objPtr = static_cast<_T*>(pVal); const RObjectId& robjId = RObjectId::create, _allocOn>(pIsConstCastSafe); - return RObject(std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(objPtr))), buildCloner<_T>(), robjId); + const std::vector& conversions = getConverters>(); + return RObject(std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(objPtr))), buildCloner<_T>(), robjId, conversions); } else if constexpr (_allocOn == alloc::Stack) { if constexpr (isRawPointer) { const RObjectId& robjId = RObjectId::create(pIsConstCastSafe); - return RObject(std::any(static_cast(pVal)), buildCloner<_T>(), robjId); + const std::vector& conversions = getConverters(); + return RObject(std::any(static_cast(pVal)), buildCloner<_T>(), robjId, conversions); } else { const RObjectId& robjId = RObjectId::create(pIsConstCastSafe); + const std::vector& conversions = getConverters(); if constexpr (traits::std_wrapper<_T>::type == Wrapper::Unique) { using U = traits::std_wrapper<_T>::value_type; - return RObject(std::any(RObjectUPtr(std::move(pVal))), buildCloner<_T>(), robjId); + return RObject(std::any(RObjectUPtr(std::move(pVal))), buildCloner<_T>(), robjId, conversions); } else { static_assert(std::is_copy_constructible_v<_T>, "T must be copy-constructible (std::any requires this)."); - return RObject(std::any(std::forward(pVal)), buildCloner<_T>(), robjId); + return RObject(std::any(std::forward(pVal)), buildCloner<_T>(), robjId, conversions); } } } diff --git a/ReflectionTemplateLib/detail/inc/RObjectId.h b/ReflectionTemplateLib/detail/inc/RObjectId.h index 66ee57e1..e58c6251 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectId.h +++ b/ReflectionTemplateLib/detail/inc/RObjectId.h @@ -35,8 +35,6 @@ namespace rtl::detail private: - static std::vector m_conversions; - mutable bool m_isWrappingConst; mutable bool m_isConstCastSafe; @@ -47,8 +45,6 @@ namespace rtl::detail mutable std::size_t m_typeId; mutable std::size_t m_wrapperTypeId; - const std::vector& m_converters; - RObjectId(RObjectId&&) = default; RObjectId(const RObjectId&) = default; RObjectId& operator=(RObjectId&&) = delete; @@ -63,12 +59,11 @@ namespace rtl::detail , m_containsAs(EntityKind::None) , m_typeId(TypeId<>::None) , m_wrapperTypeId(TypeId<>::None) - , m_converters(m_conversions) { } RObjectId(alloc pAllocOn, bool pIsConstCastSafe, Wrapper pWrapperType, bool pIsStoredConst, EntityKind pContainsAs, - std::size_t pTypeId, const std::vector& pConverters, std::size_t pWrapperTypeId) + std::size_t pTypeId, std::size_t pWrapperTypeId) : m_isWrappingConst(pIsStoredConst) , m_isConstCastSafe(pIsConstCastSafe) , m_allocatedOn(pAllocOn) @@ -76,7 +71,6 @@ namespace rtl::detail , m_containsAs(pContainsAs) , m_typeId(pTypeId) , m_wrapperTypeId(pWrapperTypeId) - , m_converters(pConverters) { } @@ -92,19 +86,6 @@ namespace rtl::detail } - inline std::size_t getConverterIndex(const std::size_t pToTypeId) const - { - if (m_containsAs != EntityKind::None) { - for (std::size_t index = 0; index < m_converters.size(); index++) { - if (m_converters[index].first == pToTypeId) { - return index; - } - } - } - return index_none; - } - - template static constexpr EntityKind getEntityKind() { @@ -136,10 +117,9 @@ namespace rtl::detail const std::size_t wrapperId = _W::id(); const std::size_t typeId = rtl::detail::TypeId<_T>::get(); - const auto& conversions = rtl::detail::ReflectCast<_T>::getConversions(); const bool isWrappingConst = (_W::type != Wrapper::None && traits::is_const_v); return RObjectId(_allocOn, pIsConstCastSafe, _W::type, - isWrappingConst, containedAs, typeId, conversions, wrapperId); + isWrappingConst, containedAs, typeId, wrapperId); } }; } \ No newline at end of file diff --git a/ReflectionTemplateLib/detail/src/CMakeLists.txt b/ReflectionTemplateLib/detail/src/CMakeLists.txt index 27998ccb..d7be430f 100644 --- a/ReflectionTemplateLib/detail/src/CMakeLists.txt +++ b/ReflectionTemplateLib/detail/src/CMakeLists.txt @@ -2,7 +2,6 @@ set(LOCAL_SOURCES "${CMAKE_CURRENT_LIST_DIR}/CxxReflection.cpp" "${CMAKE_CURRENT_LIST_DIR}/FunctorId.cpp" - "${CMAKE_CURRENT_LIST_DIR}/RObjectId.cpp" "${CMAKE_CURRENT_LIST_DIR}/ReflectCast.cpp" "${CMAKE_CURRENT_LIST_DIR}/RObjectConverters_string.cpp" ) diff --git a/ReflectionTemplateLib/detail/src/RObjectId.cpp b/ReflectionTemplateLib/detail/src/RObjectId.cpp deleted file mode 100644 index f7a6624e..00000000 --- a/ReflectionTemplateLib/detail/src/RObjectId.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/************************************************************************* - * * - * Reflection Template Library (RTL) - Modern C++ Reflection Framework * - * https://github.com/ReflectCxx/ReflectionTemplateLibrary-CPP * - * * - * Copyright (c) 2025 Neeraj Singh * - * SPDX-License-Identifier: MIT * - * * - *************************************************************************/ - - -#include "RObject.h" - -namespace rtl::detail -{ - std::vector detail::RObjectId::m_conversions = { }; -} \ No newline at end of file From 0a0c3fa687359094ffc5d4862c77c6f19f45a3f7 Mon Sep 17 00:00:00 2001 From: neeraj31285 Date: Fri, 5 Sep 2025 16:58:57 +0530 Subject: [PATCH 2/6] RObjectId- pure pod now. --- .../CxxTestProxyDesignPattern/inc/Proxy.hpp | 8 +- .../CxxTestProxyDesignPattern/src/Proxy.cpp | 2 +- RTLBenchmarkApp/src/BenchMark.cpp | 39 +++++----- RTLBenchmarkApp/src/main.cpp | 10 +-- .../ConstMethodOverloadTests.cpp | 4 +- ReflectionTemplateLib/access/inc/RObject.h | 1 - ReflectionTemplateLib/access/inc/RObject.hpp | 10 +-- ReflectionTemplateLib/common/Constants.h | 8 +- .../detail/inc/FunctionCaller.hpp | 2 +- .../detail/inc/MethodInvoker.hpp | 16 ++-- .../detail/inc/RObjectBuilder.hpp | 30 ++++---- ReflectionTemplateLib/detail/inc/RObjectId.h | 73 +++---------------- .../detail/inc/SetupConstructor.hpp | 6 +- .../detail/inc/SetupFunction.hpp | 2 +- .../detail/inc/SetupMethod.hpp | 6 +- 15 files changed, 82 insertions(+), 135 deletions(-) diff --git a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp index f1394d8b..831f1426 100644 --- a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp +++ b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp @@ -19,12 +19,12 @@ namespace proxy_test { const auto orgMethod = OriginalReflection::getClass()->getMethod(pFunctionName); if (!orgMethod.has_value()) { - return { rtl::error::FunctionNotRegisterd, rtl::RObject() }; + return { rtl::error::FunctionNotRegisterd, rtl::RObject{ } }; } if (orgMethod->hasSignature<_args...>()) { return orgMethod->bind(m_originalObj).call(std::forward<_args>(params)...); } - return { rtl::error::SignatureMismatch, rtl::RObject() }; + return { rtl::error::SignatureMismatch, rtl::RObject{ } }; } @@ -44,11 +44,11 @@ namespace proxy_test { const auto orgMethod = OriginalReflection::getClass()->getMethod(pFunctionName); if (!orgMethod.has_value()) { - return { rtl::error::FunctionNotRegisterd, rtl::RObject() }; + return { rtl::error::FunctionNotRegisterd, rtl::RObject{ } }; } if (orgMethod->hasSignature<_args...>()) { return orgMethod->bind().call(std::forward<_args>(params)...); } - return { rtl::error::SignatureMismatch, rtl::RObject() }; + return { rtl::error::SignatureMismatch, rtl::RObject{ } }; } } diff --git a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/src/Proxy.cpp b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/src/Proxy.cpp index 38e8836a..0e026ea0 100644 --- a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/src/Proxy.cpp +++ b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/src/Proxy.cpp @@ -15,7 +15,7 @@ namespace proxy_test Proxy::Proxy() : m_originalObj([&]() { auto [err, robj] = OriginalReflection::getClass()->create(); - return (err == rtl::error::None ? std::move(robj) : rtl::RObject()); + return (err == rtl::error::None ? std::move(robj) : rtl::RObject{ }); }()) { assert(!m_originalObj.isEmpty() && "Reflected instance creation failed."); diff --git a/RTLBenchmarkApp/src/BenchMark.cpp b/RTLBenchmarkApp/src/BenchMark.cpp index 2134af38..13b1b55f 100644 --- a/RTLBenchmarkApp/src/BenchMark.cpp +++ b/RTLBenchmarkApp/src/BenchMark.cpp @@ -76,7 +76,7 @@ namespace rtl_bench void BenchMark::lambdaCall_noReturn(benchmark::State& state) { - std::function sendMsg = [](const char* pMsg) { + static std::function sendMsg = [](const char* pMsg) { sendMessage(pMsg); }; @@ -90,24 +90,25 @@ namespace rtl_bench void BenchMark::reflectedCall_noReturn(benchmark::State& state) { - rtl::Function sendMsg = cxx_mirror().getFunction("sendMessage").value(); + static rtl::Function sendMsg = cxx_mirror().getFunction("sendMessage").value(); + static auto sendMsgCall = sendMsg.bind(); for (auto _ : state) { - benchmark::DoNotOptimize(sendMsg.bind().call("reflected")); + benchmark::DoNotOptimize(sendMsgCall.call("reflected"));//*/.call("reflected")); } } void BenchMark::reflectedMethodCall_noReturn(benchmark::State& state) { - rtl::Record rNode = cxx_mirror().getRecord("node").value(); - rtl::Method sendMsg = rNode.getMethod("sendMessage").value(); - rtl::RObject robj = rNode.create().second; - - for (auto _ : state) - { - benchmark::DoNotOptimize(sendMsg.bind(robj).call("reflected")); - } + //rtl::Record rNode = cxx_mirror().getRecord("node").value(); + //rtl::Method sendMsg = rNode.getMethod("sendMessage").value(); + //rtl::RObject robj = rNode.create().second; + + //for (auto _ : state) + //{ + // benchmark::DoNotOptimize(sendMsg.bind(robj).call("reflected")); + //} } @@ -145,13 +146,13 @@ namespace rtl_bench void BenchMark::reflectedMethodCall_withReturn(benchmark::State& state) { - rtl::Record rNode = cxx_mirror().getRecord("node").value(); - rtl::Method getMsg = rNode.getMethod("getMessage").value(); - rtl::RObject robj = rNode.create().second; - - for (auto _ : state) - { - benchmark::DoNotOptimize(getMsg.bind(robj).call("reflected")); - } + //rtl::Record rNode = cxx_mirror().getRecord("node").value(); + //rtl::Method getMsg = rNode.getMethod("getMessage").value(); + //rtl::RObject robj = rNode.create().second; + + //for (auto _ : state) + //{ + // benchmark::DoNotOptimize(getMsg.bind(robj).call("reflected")); + //} } } \ No newline at end of file diff --git a/RTLBenchmarkApp/src/main.cpp b/RTLBenchmarkApp/src/main.cpp index f0a27601..2c7276e2 100644 --- a/RTLBenchmarkApp/src/main.cpp +++ b/RTLBenchmarkApp/src/main.cpp @@ -11,9 +11,9 @@ BENCHMARK(rtl_bench::BenchMark::directCall_noReturn); BENCHMARK(rtl_bench::BenchMark::lambdaCall_noReturn); BENCHMARK(rtl_bench::BenchMark::reflectedCall_noReturn); -BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_noReturn); -BENCHMARK(rtl_bench::BenchMark::directCall_withReturn); -BENCHMARK(rtl_bench::BenchMark::lambdaCall_withReturn); -BENCHMARK(rtl_bench::BenchMark::reflectedCall_withReturn); -BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_withReturn); +//BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_noReturn); +//BENCHMARK(rtl_bench::BenchMark::directCall_withReturn); +//BENCHMARK(rtl_bench::BenchMark::lambdaCall_withReturn); +//BENCHMARK(rtl_bench::BenchMark::reflectedCall_withReturn); +//BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_withReturn); BENCHMARK_MAIN(); diff --git a/RTLTestRunApp/src/FunctionalityTests/ConstMethodOverloadTests.cpp b/RTLTestRunApp/src/FunctionalityTests/ConstMethodOverloadTests.cpp index 21638d92..87ba39ce 100644 --- a/RTLTestRunApp/src/FunctionalityTests/ConstMethodOverloadTests.cpp +++ b/RTLTestRunApp/src/FunctionalityTests/ConstMethodOverloadTests.cpp @@ -76,12 +76,12 @@ namespace rtl_tests string lastName = person::LAST_NAME; { - auto [err, ret] = updateLastName->bind(constCast(RObject())).call(lastName); + auto [err, ret] = updateLastName->bind(constCast(RObject{ })).call(lastName); EXPECT_TRUE(err == error::EmptyRObject); ASSERT_TRUE(ret.isEmpty()); } { - auto [err, ret] = updateLastName->bind(constCast(RObject())).call(lastName); + auto [err, ret] = updateLastName->bind(constCast(RObject{ })).call(lastName); EXPECT_TRUE(err == error::EmptyRObject); ASSERT_TRUE(ret.isEmpty()); diff --git a/ReflectionTemplateLib/access/inc/RObject.h b/ReflectionTemplateLib/access/inc/RObject.h index ae2d401b..40821a32 100644 --- a/ReflectionTemplateLib/access/inc/RObject.h +++ b/ReflectionTemplateLib/access/inc/RObject.h @@ -44,7 +44,6 @@ namespace rtl mutable Cloner m_getClone; mutable std::any m_object; mutable detail::RObjectId m_objectId; - mutable const std::vector* m_converters; RObject(const RObject&) = default; diff --git a/ReflectionTemplateLib/access/inc/RObject.hpp b/ReflectionTemplateLib/access/inc/RObject.hpp index f0441ad0..c05ce869 100644 --- a/ReflectionTemplateLib/access/inc/RObject.hpp +++ b/ReflectionTemplateLib/access/inc/RObject.hpp @@ -40,7 +40,7 @@ namespace rtl { // Explicitly clear moved-from source pOther.m_object.reset(); - pOther.m_objectId.reset(); + pOther.m_objectId = { }; pOther.m_getClone = nullptr; pOther.m_converters = nullptr; } @@ -179,7 +179,7 @@ namespace rtl template<> inline std::pair RObject::createCopy() const { - return { error::StlWrapperHeapAllocForbidden, RObject() }; + return { error::StlWrapperHeapAllocForbidden, RObject{ } }; } @@ -187,11 +187,11 @@ namespace rtl inline std::pair RObject::createCopy() const { if (m_objectId.m_wrapperType == detail::Wrapper::None) { - return { error::NotWrapperType, RObject() }; + return { error::NotWrapperType, RObject{ } }; } else if (m_objectId.m_wrapperType == detail::Wrapper::Unique) { - return { error::TypeNotCopyConstructible, RObject() }; + return { error::TypeNotCopyConstructible, RObject{ } }; } else { return { error::None, RObject(*this) }; @@ -203,7 +203,7 @@ namespace rtl inline std::pair RObject::clone() const { if (isEmpty()) { - return { error::EmptyRObject, RObject() }; + return { error::EmptyRObject, RObject{ } }; } if constexpr (_copyTarget == copy::Value) { return createCopy<_allocOn, detail::EntityKind::Value>(); diff --git a/ReflectionTemplateLib/common/Constants.h b/ReflectionTemplateLib/common/Constants.h index f469069c..24d47ddd 100644 --- a/ReflectionTemplateLib/common/Constants.h +++ b/ReflectionTemplateLib/common/Constants.h @@ -22,7 +22,7 @@ namespace rtl { // cleanup is always automatic. enum class alloc { - None, /* + None = 0,/* * Assigned to empty or moved-from RObjects. * - Represents an invalid / non-owning state. * - Any attempt to call or clone results in rtl::error::EmptyRObject. @@ -104,7 +104,7 @@ namespace rtl::detail { enum class EntityKind { - None, + None = 0, Ref, Value, Wrapper @@ -112,7 +112,7 @@ namespace rtl::detail enum class Wrapper { - None, + None = 0, Any, Weak, Unique, @@ -126,7 +126,7 @@ namespace rtl::detail // MethodQ: Method qualifier + static marker. enum class methodQ { - None, // Static method (no const/non-const qualifier) + None = 0, // Static method (no const/non-const qualifier) Const, // Const-qualified instance method NonConst // Non-const instance method }; diff --git a/ReflectionTemplateLib/detail/inc/FunctionCaller.hpp b/ReflectionTemplateLib/detail/inc/FunctionCaller.hpp index 51836273..bc86426d 100644 --- a/ReflectionTemplateLib/detail/inc/FunctionCaller.hpp +++ b/ReflectionTemplateLib/detail/inc/FunctionCaller.hpp @@ -39,6 +39,6 @@ namespace rtl::detail return { err, Container::template forwardCall<_args...>(err, index, std::forward<_args>(params)...) }; } - return { error::SignatureMismatch, RObject() }; + return { error::SignatureMismatch, RObject{ } }; } } \ No newline at end of file diff --git a/ReflectionTemplateLib/detail/inc/MethodInvoker.hpp b/ReflectionTemplateLib/detail/inc/MethodInvoker.hpp index bd3fcedd..063835f7 100644 --- a/ReflectionTemplateLib/detail/inc/MethodInvoker.hpp +++ b/ReflectionTemplateLib/detail/inc/MethodInvoker.hpp @@ -40,11 +40,11 @@ namespace rtl::detail } if (m_target.isEmpty()) { //if the target is empty. - return { error::EmptyRObject, RObject() }; + return { error::EmptyRObject, RObject{ } }; } if (m_target.getTypeId() != m_method.getRecordTypeId()) { //if the m_target's type-id & type-id of the 'class/struct' owner of the associated functor(m_method's) do not match. - return { error::TargetMismatch, RObject() }; + return { error::TargetMismatch, RObject{ } }; } if constexpr (sizeof...(_signature) == 0) { // executes when bind doesn't have any explicit signature types specified. (e.g. perfect-forwaring) @@ -84,7 +84,7 @@ namespace rtl::detail { if (!pTarget.isConstCastSafe()) { pError = error::ConstOverloadMissing; - return RObject(); + return RObject{ }; } return containerNonConst::template forwardCall<_args...>(pError, pTarget, nonConstMethodIndex, std::forward<_args>(params)...); } @@ -92,7 +92,7 @@ namespace rtl::detail pError = error::SignatureMismatch; } } - return RObject(); + return RObject{ }; } } @@ -120,11 +120,11 @@ namespace rtl::detail } if (m_target.isEmpty()) { //if the target is empty. - return { error::EmptyRObject, RObject() }; + return { error::EmptyRObject, RObject{ } }; } if (m_target.getTypeId() != m_method.getRecordTypeId()) { //if the m_target's type-id & type-id of the 'class/struct' owner of the associated functor(m_method's) do not match. - return { error::TargetMismatch, RObject() }; + return { error::TargetMismatch, RObject{ } }; } if constexpr (sizeof...(_signature) == 0) { error err = error::None; @@ -160,11 +160,11 @@ namespace rtl::detail if (index != rtl::index_none) { // So, const-overload is present and non-const overload is not registered or doesn't exists. pError = error::NonConstOverloadMissing; - return RObject(); + return RObject{ }; } // else the signature might be wrong. pError = error::SignatureMismatch; - return RObject(); + return RObject{ }; } } } \ No newline at end of file diff --git a/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp b/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp index 1a9b4921..ca6e3a19 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp +++ b/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp @@ -22,6 +22,15 @@ namespace rtl::detail { return RObject::getInstanceCounter(); } + template + inline const std::vector& RObjectBuilder::getConverters() + { + // extract wrapper info. + using _W = traits::std_wrapper>; + // extract Un-Qualified raw type. + using _T = traits::raw_t>; + return rtl::detail::ReflectCast<_T>::getConversions(); + } template inline RObjectBuilder::Cloner RObjectBuilder::buildCloner() @@ -41,7 +50,7 @@ namespace rtl::detail { else if (pAllocOn == alloc::Heap) { return RObjectBuilder::template build<_T*, alloc::Heap>(new _T(srcObj), true); } - return RObject(); //dead code. compiler warning ommited. + return RObject{ }; //dead code. compiler warning ommited. }; } else @@ -49,22 +58,11 @@ namespace rtl::detail { return [](error& pError, const RObject& pOther, alloc pAllocOn)-> RObject { pError = error::TypeNotCopyConstructible; - return RObject(); + return RObject{ }; }; } } - template - inline const std::vector& RObjectBuilder::getConverters() - { - // extract wrapper info. - using _W = traits::std_wrapper>; - // extract Un-Qualified raw type. - using _T = traits::raw_t>; - - return rtl::detail::ReflectCast<_T>::getConversions(); - } - template inline RObject RObjectBuilder::build(T&& pVal, const bool pIsConstCastSafe) @@ -76,7 +74,7 @@ namespace rtl::detail { { static_assert(isRawPointer, "Invalid 'alloc' specified for non-pointer-type 'T'"); _T* objPtr = static_cast<_T*>(pVal); - const RObjectId& robjId = RObjectId::create, _allocOn>(pIsConstCastSafe); + const RObjectId robjId = RObjectId::create, _allocOn>(pIsConstCastSafe); const std::vector& conversions = getConverters>(); return RObject(std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(objPtr))), buildCloner<_T>(), robjId, conversions); } @@ -84,13 +82,13 @@ namespace rtl::detail { { if constexpr (isRawPointer) { - const RObjectId& robjId = RObjectId::create(pIsConstCastSafe); + const RObjectId robjId = RObjectId::create(pIsConstCastSafe); const std::vector& conversions = getConverters(); return RObject(std::any(static_cast(pVal)), buildCloner<_T>(), robjId, conversions); } else { - const RObjectId& robjId = RObjectId::create(pIsConstCastSafe); + const RObjectId robjId = RObjectId::create(pIsConstCastSafe); const std::vector& conversions = getConverters(); if constexpr (traits::std_wrapper<_T>::type == Wrapper::Unique) { diff --git a/ReflectionTemplateLib/detail/inc/RObjectId.h b/ReflectionTemplateLib/detail/inc/RObjectId.h index e58c6251..4dd628c8 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectId.h +++ b/ReflectionTemplateLib/detail/inc/RObjectId.h @@ -21,70 +21,20 @@ namespace rtl { namespace rtl::detail { - class RObjExtractor; - class RObjectBuilder; - struct RObjectId { - friend RObjExtractor; - friend RObjectBuilder; - friend RObject; - - GETTER(std::size_t, TypeId, m_typeId) - GETTER(EntityKind, ContainedAs, m_containsAs) - - private: - - mutable bool m_isWrappingConst; - mutable bool m_isConstCastSafe; - - mutable alloc m_allocatedOn; - mutable Wrapper m_wrapperType; - mutable EntityKind m_containsAs; - - mutable std::size_t m_typeId; - mutable std::size_t m_wrapperTypeId; - - RObjectId(RObjectId&&) = default; - RObjectId(const RObjectId&) = default; - RObjectId& operator=(RObjectId&&) = delete; - RObjectId& operator=(const RObjectId&) = delete; + bool m_isWrappingConst; + bool m_isConstCastSafe; + std::size_t m_typeId; + std::size_t m_wrapperTypeId; - RObjectId() - : m_isWrappingConst(false) - , m_isConstCastSafe(false) - , m_allocatedOn(alloc::None) - , m_wrapperType(Wrapper::None) - , m_containsAs(EntityKind::None) - , m_typeId(TypeId<>::None) - , m_wrapperTypeId(TypeId<>::None) - { } - - - RObjectId(alloc pAllocOn, bool pIsConstCastSafe, Wrapper pWrapperType, bool pIsStoredConst, EntityKind pContainsAs, - std::size_t pTypeId, std::size_t pWrapperTypeId) - : m_isWrappingConst(pIsStoredConst) - , m_isConstCastSafe(pIsConstCastSafe) - , m_allocatedOn(pAllocOn) - , m_wrapperType(pWrapperType) - , m_containsAs(pContainsAs) - , m_typeId(pTypeId) - , m_wrapperTypeId(pWrapperTypeId) - { } - - - void reset() const - { - m_isWrappingConst = false; - m_isConstCastSafe = false; - m_allocatedOn = alloc::None; - m_wrapperType = Wrapper::None; - m_containsAs = EntityKind::None; - m_typeId = TypeId<>::None; - m_wrapperTypeId = TypeId<>::None; - } + alloc m_allocatedOn; + Wrapper m_wrapperType; + EntityKind m_containsAs; + GETTER(std::size_t, TypeId, m_typeId) + GETTER(EntityKind, ContainedAs, m_containsAs) template static constexpr EntityKind getEntityKind() @@ -113,13 +63,12 @@ namespace rtl::detail using _W = traits::std_wrapper>; // extract Un-Qualified raw type. using _T = traits::raw_t>; - constexpr EntityKind containedAs = getEntityKind(); + constexpr EntityKind entityKind = getEntityKind(); const std::size_t wrapperId = _W::id(); const std::size_t typeId = rtl::detail::TypeId<_T>::get(); const bool isWrappingConst = (_W::type != Wrapper::None && traits::is_const_v); - return RObjectId(_allocOn, pIsConstCastSafe, _W::type, - isWrappingConst, containedAs, typeId, wrapperId); + return RObjectId{ isWrappingConst, pIsConstCastSafe, typeId, wrapperId, _allocOn, _W::type, entityKind }; } }; } \ No newline at end of file diff --git a/ReflectionTemplateLib/detail/inc/SetupConstructor.hpp b/ReflectionTemplateLib/detail/inc/SetupConstructor.hpp index 16577771..93b57244 100644 --- a/ReflectionTemplateLib/detail/inc/SetupConstructor.hpp +++ b/ReflectionTemplateLib/detail/inc/SetupConstructor.hpp @@ -27,7 +27,7 @@ namespace rtl::detail if constexpr (sizeof...(_signature) == 0 && !std::is_default_constructible_v<_recordType>) { //default constructor, private or deleted. pError = error::TypeNotDefaultConstructible; - return RObject(); + return RObject{ }; } else { @@ -35,7 +35,7 @@ namespace rtl::detail if constexpr (!std::is_copy_constructible_v<_recordType>) { pError = error::TypeNotCopyConstructible; - return RObject(); + return RObject{ }; } else { pError = error::None; @@ -46,7 +46,7 @@ namespace rtl::detail return RObjectBuilder::build<_recordType*, alloc::Heap>(new _recordType(std::forward<_signature>(params)...), true); } } - return RObject(); //dead code. compiler warning ommited. + return RObject{ }; //dead code. compiler warning ommited. }; } diff --git a/ReflectionTemplateLib/detail/inc/SetupFunction.hpp b/ReflectionTemplateLib/detail/inc/SetupFunction.hpp index 54e02896..9e4c6e6c 100644 --- a/ReflectionTemplateLib/detail/inc/SetupFunction.hpp +++ b/ReflectionTemplateLib/detail/inc/SetupFunction.hpp @@ -34,7 +34,7 @@ namespace rtl if constexpr (std::is_same_v<_returnType, void>) { //if the function do not returns anything, this block will be retained by compiler. (*pFunctor)(std::forward<_signature>(params)...); - return RObject(); + return RObject{ }; } else if constexpr (std::is_reference_v<_returnType>) { /* if the function returns reference, this block will be retained by compiler. diff --git a/ReflectionTemplateLib/detail/inc/SetupMethod.hpp b/ReflectionTemplateLib/detail/inc/SetupMethod.hpp index 628e5b9c..803f9333 100644 --- a/ReflectionTemplateLib/detail/inc/SetupMethod.hpp +++ b/ReflectionTemplateLib/detail/inc/SetupMethod.hpp @@ -32,7 +32,7 @@ namespace rtl if (!pTargetObj.isConstCastSafe()) { pError = error::IllegalConstCast; - return RObject(); + return RObject{ }; } //call on 'pFunctor' will definitely be successful, since the object type, signature type has already been validated. @@ -43,7 +43,7 @@ namespace rtl if constexpr (std::is_same_v<_returnType, void>) { //if the function do not returns anything, this block will be retained by compiler. (target.*pFunctor)(std::forward<_signature>(params)...); - return RObject(); + return RObject{ }; } else if constexpr (std::is_reference_v<_returnType>) { /* if the function returns reference, this block will be retained by compiler. @@ -77,7 +77,7 @@ namespace rtl if constexpr (std::is_same_v<_returnType, void>) { //if the function do not returns anything, this block will be retained by compiler. (target.*pFunctor)(std::forward<_signature>(params)...); - return RObject(); + return RObject{ }; } else if constexpr (std::is_reference_v<_returnType>) { /* if the function returns reference, this block will be retained by compiler. From 36087b464fa6377ec103ef81d903c56147092fd5 Mon Sep 17 00:00:00 2001 From: neeraj31285 Date: Fri, 5 Sep 2025 22:13:58 +0530 Subject: [PATCH 3/6] introduced rtl::Return, removed std::pair. --- .../CxxTestProxyDesignPattern/inc/Proxy.h | 4 +- .../CxxTestProxyDesignPattern/inc/Proxy.hpp | 4 +- RTLBenchmarkApp/src/BenchMark.cpp | 34 ++++++------- RTLBenchmarkApp/src/main.cpp | 10 ++-- ReflectionTemplateLib/access/inc/Function.h | 2 +- ReflectionTemplateLib/access/inc/Function.hpp | 4 +- ReflectionTemplateLib/access/inc/Method.h | 4 +- ReflectionTemplateLib/access/inc/Method.hpp | 2 +- ReflectionTemplateLib/access/inc/RObject.h | 10 +++- ReflectionTemplateLib/access/inc/RObject.hpp | 24 +++++---- ReflectionTemplateLib/access/inc/Record.h | 4 +- .../detail/inc/CallReflector.h | 12 ++--- .../detail/inc/FunctionCaller.h | 3 +- .../detail/inc/FunctionCaller.hpp | 7 +-- .../detail/inc/FunctorContainer.h | 2 +- .../detail/inc/MethodContainer.h | 4 +- .../detail/inc/MethodInvoker.h | 8 +-- .../detail/inc/MethodInvoker.hpp | 50 +++++++------------ .../detail/inc/SetupConstructor.h | 2 +- .../detail/inc/SetupConstructor.hpp | 19 +++---- .../detail/inc/SetupFunction.h | 2 +- .../detail/inc/SetupFunction.hpp | 14 +++--- .../detail/inc/SetupMethod.h | 2 +- .../detail/inc/SetupMethod.hpp | 31 ++++++------ 24 files changed, 129 insertions(+), 129 deletions(-) diff --git a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.h b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.h index d0721345..416894b7 100644 --- a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.h +++ b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.h @@ -30,7 +30,7 @@ namespace proxy_test { * @return The result of the function call as a std::any object. */ template - std::pair forwardCall(const std::string& pFunctionName, _args&& ...params); + rtl::Return forwardCall(const std::string& pFunctionName, _args&& ...params); /** * @brief Forwards a call to a static method of the "Original" class. @@ -41,6 +41,6 @@ namespace proxy_test { * @return The result of the function call as a std::any object. */ template - static std::pair forwardStaticCall(const std::string& pFunctionName, _args&& ...params); + static rtl::Return forwardStaticCall(const std::string& pFunctionName, _args&& ...params); }; } diff --git a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp index 831f1426..946b4c37 100644 --- a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp +++ b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp @@ -15,7 +15,7 @@ namespace proxy_test * @return The result of the function call as a std::any object. If the method does not exist or the signature does not match, returns an empty std::any object. */ template - inline std::pair Proxy::forwardCall(const std::string& pFunctionName, _args&& ...params) + inline rtl::Return Proxy::forwardCall(const std::string& pFunctionName, _args&& ...params) { const auto orgMethod = OriginalReflection::getClass()->getMethod(pFunctionName); if (!orgMethod.has_value()) { @@ -40,7 +40,7 @@ namespace proxy_test * @return The result of the function call as a std::any object. If the method does not exist or the signature does not match, returns an empty std::any object. */ template - inline std::pair Proxy::forwardStaticCall(const std::string& pFunctionName, _args&& ...params) + inline rtl::Return Proxy::forwardStaticCall(const std::string& pFunctionName, _args&& ...params) { const auto orgMethod = OriginalReflection::getClass()->getMethod(pFunctionName); if (!orgMethod.has_value()) { diff --git a/RTLBenchmarkApp/src/BenchMark.cpp b/RTLBenchmarkApp/src/BenchMark.cpp index 13b1b55f..0ab81fe0 100644 --- a/RTLBenchmarkApp/src/BenchMark.cpp +++ b/RTLBenchmarkApp/src/BenchMark.cpp @@ -94,21 +94,21 @@ namespace rtl_bench static auto sendMsgCall = sendMsg.bind(); for (auto _ : state) { - benchmark::DoNotOptimize(sendMsgCall.call("reflected"));//*/.call("reflected")); + benchmark::DoNotOptimize(sendMsgCall.call("reflected")); } } void BenchMark::reflectedMethodCall_noReturn(benchmark::State& state) { - //rtl::Record rNode = cxx_mirror().getRecord("node").value(); - //rtl::Method sendMsg = rNode.getMethod("sendMessage").value(); - //rtl::RObject robj = rNode.create().second; - - //for (auto _ : state) - //{ - // benchmark::DoNotOptimize(sendMsg.bind(robj).call("reflected")); - //} + static rtl::Record rNode = cxx_mirror().getRecord("node").value(); + static rtl::Method sendMsg = rNode.getMethod("sendMessage").value(); + static rtl::RObject robj = rNode.create().robj; + + for (auto _ : state) + { + benchmark::DoNotOptimize(sendMsg.bind(robj).call("reflected")); + } } @@ -146,13 +146,13 @@ namespace rtl_bench void BenchMark::reflectedMethodCall_withReturn(benchmark::State& state) { - //rtl::Record rNode = cxx_mirror().getRecord("node").value(); - //rtl::Method getMsg = rNode.getMethod("getMessage").value(); - //rtl::RObject robj = rNode.create().second; - - //for (auto _ : state) - //{ - // benchmark::DoNotOptimize(getMsg.bind(robj).call("reflected")); - //} + static rtl::Record rNode = cxx_mirror().getRecord("node").value(); + static rtl::Method getMsg = rNode.getMethod("getMessage").value(); + static rtl::RObject robj = rNode.create().robj; + + for (auto _ : state) + { + benchmark::DoNotOptimize(getMsg.bind(robj).call("reflected")); + } } } \ No newline at end of file diff --git a/RTLBenchmarkApp/src/main.cpp b/RTLBenchmarkApp/src/main.cpp index 2c7276e2..f0a27601 100644 --- a/RTLBenchmarkApp/src/main.cpp +++ b/RTLBenchmarkApp/src/main.cpp @@ -11,9 +11,9 @@ BENCHMARK(rtl_bench::BenchMark::directCall_noReturn); BENCHMARK(rtl_bench::BenchMark::lambdaCall_noReturn); BENCHMARK(rtl_bench::BenchMark::reflectedCall_noReturn); -//BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_noReturn); -//BENCHMARK(rtl_bench::BenchMark::directCall_withReturn); -//BENCHMARK(rtl_bench::BenchMark::lambdaCall_withReturn); -//BENCHMARK(rtl_bench::BenchMark::reflectedCall_withReturn); -//BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_withReturn); +BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_noReturn); +BENCHMARK(rtl_bench::BenchMark::directCall_withReturn); +BENCHMARK(rtl_bench::BenchMark::lambdaCall_withReturn); +BENCHMARK(rtl_bench::BenchMark::reflectedCall_withReturn); +BENCHMARK(rtl_bench::BenchMark::reflectedMethodCall_withReturn); BENCHMARK_MAIN(); diff --git a/ReflectionTemplateLib/access/inc/Function.h b/ReflectionTemplateLib/access/inc/Function.h index 43641186..f8ffdec2 100644 --- a/ReflectionTemplateLib/access/inc/Function.h +++ b/ReflectionTemplateLib/access/inc/Function.h @@ -92,7 +92,7 @@ namespace rtl { bool hasSignature() const; template - std::pair operator()(_args&&...params) const noexcept; + Return operator()(_args&&...params) const noexcept; template const detail::FunctionCaller<_signature...> bind() const; diff --git a/ReflectionTemplateLib/access/inc/Function.hpp b/ReflectionTemplateLib/access/inc/Function.hpp index bc2bf2c6..033db291 100644 --- a/ReflectionTemplateLib/access/inc/Function.hpp +++ b/ReflectionTemplateLib/access/inc/Function.hpp @@ -37,11 +37,11 @@ namespace rtl /* @method: operator()() @param: variadic arguments. - @return: std::pair, possible error & return value of from the reflected call. + @return: Return, possible error & return value of from the reflected call. * if the arguments did not match with any overload, returns RObject with error::SignatureMismatch * providing optional syntax, Function::call() does the exact same thing. */ template - inline std::pair Function::operator()(_args&& ...params) const noexcept + inline Return Function::operator()(_args&& ...params) const noexcept { return bind().call(std::forward<_args>(params)...); } diff --git a/ReflectionTemplateLib/access/inc/Method.h b/ReflectionTemplateLib/access/inc/Method.h index f1fe5911..d6ec6045 100644 --- a/ReflectionTemplateLib/access/inc/Method.h +++ b/ReflectionTemplateLib/access/inc/Method.h @@ -43,7 +43,7 @@ namespace rtl { //invokes the constructor associated with this 'Method' template - std::pair invokeCtor(alloc&& pAllocType, _args&&...params) const; + Return invokeCtor(alloc&& pAllocType, _args&&...params) const; public: @@ -94,7 +94,7 @@ namespace rtl { * provides syntax like, 'method(pTarget)(params...)', keeping the target & params seperate. */ constexpr auto operator()(const RObject& pTarget) const { - return [&](auto&&...params)-> std::pair { + return [&](auto&&...params)-> Return { return bind(pTarget).call(std::forward(params)...); }; } diff --git a/ReflectionTemplateLib/access/inc/Method.hpp b/ReflectionTemplateLib/access/inc/Method.hpp index 34fc1186..cc08864b 100644 --- a/ReflectionTemplateLib/access/inc/Method.hpp +++ b/ReflectionTemplateLib/access/inc/Method.hpp @@ -34,7 +34,7 @@ namespace rtl @return: RStatus * calls the constructor with given arguments. */ template - inline std::pair Method::invokeCtor(alloc&& pAllocType, _args&& ...params) const + inline Return Method::invokeCtor(alloc&& pAllocType, _args&& ...params) const { return Function::bind().call(std::forward(pAllocType), std::forward<_args>(params)...); } diff --git a/ReflectionTemplateLib/access/inc/RObject.h b/ReflectionTemplateLib/access/inc/RObject.h index 40821a32..c9cb0869 100644 --- a/ReflectionTemplateLib/access/inc/RObject.h +++ b/ReflectionTemplateLib/access/inc/RObject.h @@ -34,6 +34,7 @@ namespace rtl::detail namespace rtl { + struct Return; class Function; //Reflecting the object within. @@ -55,7 +56,7 @@ namespace rtl std::size_t getConverterIndex(const std::size_t pToTypeId) const; template - std::pair createCopy() const; + Return createCopy() const; template std::optional> performConversion(const std::size_t pIndex) const; @@ -83,7 +84,7 @@ namespace rtl bool canViewAs() const; template - std::pair clone() const; + Return clone() const; template, int> = 0> std::optional> view() const; @@ -100,4 +101,9 @@ namespace rtl friend detail::RObjExtractor; friend detail::RObjectBuilder; }; + + struct [[nodiscard]] Return { + error err; + RObject robj; + }; } \ No newline at end of file diff --git a/ReflectionTemplateLib/access/inc/RObject.hpp b/ReflectionTemplateLib/access/inc/RObject.hpp index c05ce869..b930ebd5 100644 --- a/ReflectionTemplateLib/access/inc/RObject.hpp +++ b/ReflectionTemplateLib/access/inc/RObject.hpp @@ -41,7 +41,7 @@ namespace rtl // Explicitly clear moved-from source pOther.m_object.reset(); pOther.m_objectId = { }; - pOther.m_getClone = nullptr; + //pOther.m_getClone = nullptr; pOther.m_converters = nullptr; } @@ -161,37 +161,39 @@ namespace rtl namespace rtl { template<> - inline std::pair RObject::createCopy() const + inline Return RObject::createCopy() const { error err = error::None; - return { err, m_getClone(err, *this, alloc::Heap) }; + RObject robj/*;//*/ = m_getClone(err, *this, alloc::Heap); + return { err, std::move(robj) }; } template<> - inline std::pair RObject::createCopy() const + inline Return RObject::createCopy() const { error err = error::None; - return { err, m_getClone(err, *this, alloc::Stack) }; + RObject robj/*;//*/ = m_getClone(err, *this, alloc::Stack); + return { err, std::move(robj) }; } template<> - inline std::pair RObject::createCopy() const + inline Return RObject::createCopy() const { - return { error::StlWrapperHeapAllocForbidden, RObject{ } }; + return { error::StlWrapperHeapAllocForbidden, RObject{} }; } template<> - inline std::pair RObject::createCopy() const + inline Return RObject::createCopy() const { if (m_objectId.m_wrapperType == detail::Wrapper::None) { - return { error::NotWrapperType, RObject{ } }; + return { error::NotWrapperType, RObject{} }; } else if (m_objectId.m_wrapperType == detail::Wrapper::Unique) { - return { error::TypeNotCopyConstructible, RObject{ } }; + return { error::TypeNotCopyConstructible, RObject{} }; } else { return { error::None, RObject(*this) }; @@ -200,7 +202,7 @@ namespace rtl template - inline std::pair RObject::clone() const + inline Return RObject::clone() const { if (isEmpty()) { return { error::EmptyRObject, RObject{ } }; diff --git a/ReflectionTemplateLib/access/inc/Record.h b/ReflectionTemplateLib/access/inc/Record.h index 2ce3d394..4956f29f 100644 --- a/ReflectionTemplateLib/access/inc/Record.h +++ b/ReflectionTemplateLib/access/inc/Record.h @@ -81,7 +81,7 @@ namespace rtl { /* @method: create @param: ...params (any number/type of arguments) - @return: std::pair + @return: Return * calls the constructor of the calss/struct represented by this 'Record' object. * returns the dynamically allocated object of the calss/struct along with the status. * only default or any other overloaded constructor is called, except copy (for that check, Record::clone()). @@ -89,7 +89,7 @@ namespace rtl { * if no constructor found, error::ConstructorNotRegisteredInRtl is returned with empty 'RObject'. * on success error::None and newly constructed object wrapped under 'RObject' (type erased, treated as non-const) is returned. */ template - std::pair create(_ctorArgs&& ...params) const + Return create(_ctorArgs&& ...params) const { static_assert(_alloc != rtl::alloc::None, "Instance cannot be created with 'rtl::alloc::None' option."); return m_methods.at(detail::ctor_name(m_recordName)).invokeCtor(_alloc, std::forward<_ctorArgs>(params)...); diff --git a/ReflectionTemplateLib/detail/inc/CallReflector.h b/ReflectionTemplateLib/detail/inc/CallReflector.h index e2d84db9..1295f459 100644 --- a/ReflectionTemplateLib/detail/inc/CallReflector.h +++ b/ReflectionTemplateLib/detail/inc/CallReflector.h @@ -31,10 +31,10 @@ namespace rtl { * gets the lambda vector from '_derivedType' and calls the lambda at given index with '_args'. * this 'forwardCall' is for calling lambda containing non-member-function and static-member-function functors. */ template - static RObject forwardCall(error& pError, std::size_t pFunctorIndex, _params&&..._args) + static Return forwardCall(std::size_t pFunctorIndex, _params&&..._args) { //'getFunctors()' must be implemented by _derivedType (FunctorContainer). - return _derivedType::getFunctors().at(pFunctorIndex)(pError, std::forward<_params>(_args)...); + return _derivedType::getFunctors().at(pFunctorIndex)(std::forward<_params>(_args)...); } @@ -43,10 +43,10 @@ namespace rtl { * gets the lambda vector from '_derivedType' and calls the lambda at given index with '_args'. * this 'forwardCall' is for calling lambda containing constructors. */ template - static RObject forwardCall(error& pError, rtl::alloc&& pAllocType, std::size_t pFunctorIndex, _params&&..._args) + static Return forwardCall(rtl::alloc&& pAllocType, std::size_t pFunctorIndex, _params&&..._args) { //'getFunctors()' must be implemented by _derivedType (FunctorContainer). - return _derivedType::getFunctors().at(pFunctorIndex)(pError, std::forward(pAllocType), std::forward<_params>(_args)...); + return _derivedType::getFunctors().at(pFunctorIndex)(std::forward(pAllocType), std::forward<_params>(_args)...); } @@ -55,10 +55,10 @@ namespace rtl { * gets the lambda vector from '_derivedType' and calls the lambda at given index with '_args'. * this 'forwardCall' is for calling lambda containing member-function functors. */ template - static RObject forwardCall(error& pError, const rtl::RObject& pTarget, std::size_t pFunctorIndex, _params&&..._args) + static Return forwardCall(const rtl::RObject& pTarget, std::size_t pFunctorIndex, _params&&..._args) { //'getMethodFunctors()' is implemented by _derivedType (MethodContainer) - return _derivedType::getMethodFunctors().at(pFunctorIndex)(pError, pTarget, std::forward<_params>(_args)...); + return _derivedType::getMethodFunctors().at(pFunctorIndex)(pTarget, std::forward<_params>(_args)...); } }; } diff --git a/ReflectionTemplateLib/detail/inc/FunctionCaller.h b/ReflectionTemplateLib/detail/inc/FunctionCaller.h index 833c8de5..f4d746c5 100644 --- a/ReflectionTemplateLib/detail/inc/FunctionCaller.h +++ b/ReflectionTemplateLib/detail/inc/FunctionCaller.h @@ -15,6 +15,7 @@ namespace rtl { class RObject; class Function; + class Return; } namespace rtl::detail @@ -30,7 +31,7 @@ namespace rtl::detail public: template - std::pair call(_args&&...) const noexcept; + rtl::Return call(_args&&...) const; friend Function; }; diff --git a/ReflectionTemplateLib/detail/inc/FunctionCaller.hpp b/ReflectionTemplateLib/detail/inc/FunctionCaller.hpp index bc86426d..4fdfbde7 100644 --- a/ReflectionTemplateLib/detail/inc/FunctionCaller.hpp +++ b/ReflectionTemplateLib/detail/inc/FunctionCaller.hpp @@ -26,7 +26,7 @@ namespace rtl::detail template template - inline std::pair FunctionCaller<_signature...>::call(_args&&...params) const noexcept + inline Return FunctionCaller<_signature...>::call(_args&&...params) const { using Container = std::conditional_t...>, @@ -34,11 +34,8 @@ namespace rtl::detail std::size_t index = m_function.hasSignatureId(Container::getContainerId()); if (index != rtl::index_none) { - - error err = error::None; - return { err, Container::template forwardCall<_args...>(err, index, std::forward<_args>(params)...) }; + return Container::template forwardCall<_args...>(index, std::forward<_args>(params)...); } - return { error::SignatureMismatch, RObject{ } }; } } \ No newline at end of file diff --git a/ReflectionTemplateLib/detail/inc/FunctorContainer.h b/ReflectionTemplateLib/detail/inc/FunctorContainer.h index ca1c3dcf..618d9ed8 100644 --- a/ReflectionTemplateLib/detail/inc/FunctorContainer.h +++ b/ReflectionTemplateLib/detail/inc/FunctorContainer.h @@ -36,7 +36,7 @@ namespace rtl { public SetupConstructor>, public CallReflector> { - using FunctionLambda = std::function < RObject (error&, _signature...) >; + using FunctionLambda = std::function < Return(_signature...) >; public: //every FunctorContainer<...> will have a unique-id. diff --git a/ReflectionTemplateLib/detail/inc/MethodContainer.h b/ReflectionTemplateLib/detail/inc/MethodContainer.h index 91e91c79..0b0fb6df 100644 --- a/ReflectionTemplateLib/detail/inc/MethodContainer.h +++ b/ReflectionTemplateLib/detail/inc/MethodContainer.h @@ -40,7 +40,7 @@ namespace rtl { class MethodContainer : public SetupMethod>, public CallReflector> { - using MethodLambda = std::function < RObject (error&, const rtl::RObject&, _signature...) >; + using MethodLambda = std::function < Return (const rtl::RObject&, _signature...) >; public: @@ -111,7 +111,7 @@ namespace rtl { class MethodContainer : public SetupMethod>, public CallReflector> { - using MethodLambda = std::function < RObject (error&, const rtl::RObject&, _signature...) >; + using MethodLambda = std::function < Return (const rtl::RObject&, _signature...) >; public: diff --git a/ReflectionTemplateLib/detail/inc/MethodInvoker.h b/ReflectionTemplateLib/detail/inc/MethodInvoker.h index 083af89f..3ed505aa 100644 --- a/ReflectionTemplateLib/detail/inc/MethodInvoker.h +++ b/ReflectionTemplateLib/detail/inc/MethodInvoker.h @@ -34,13 +34,13 @@ namespace rtl::detail { struct Invoker { template - static RObject invoke(error& pError, const Method& pMethod, const RObject& pTarget, _args&&...); + static Return invoke(const Method& pMethod, const RObject& pTarget, _args&&...); }; public: template - std::pair call(_args&&...) const noexcept; + Return call(_args&&...) const noexcept; friend Method; }; @@ -61,13 +61,13 @@ namespace rtl::detail { struct Invoker { template - static RObject invoke(error& pError, const Method& pMethod, const RObject& pTarget, _args&&...); + static Return invoke(const Method& pMethod, const RObject& pTarget, _args&&...); }; public: template - std::pair call(_args&&...) const noexcept; + Return call(_args&&...) const noexcept; friend Method; }; diff --git a/ReflectionTemplateLib/detail/inc/MethodInvoker.hpp b/ReflectionTemplateLib/detail/inc/MethodInvoker.hpp index 063835f7..6e0f946b 100644 --- a/ReflectionTemplateLib/detail/inc/MethodInvoker.hpp +++ b/ReflectionTemplateLib/detail/inc/MethodInvoker.hpp @@ -32,7 +32,7 @@ namespace rtl::detail * invokes non-static-member-function functor associated with 'm_method' on object 'm_target'. */ template template - inline std::pair DefaultInvoker<_signature...>::call(_args&& ...params) const noexcept + inline Return DefaultInvoker<_signature...>::call(_args&& ...params) const noexcept { //Only static-member-functions have Qualifier- 'methodQ::None' if (m_method.getQualifier() == methodQ::None) { @@ -48,12 +48,10 @@ namespace rtl::detail } if constexpr (sizeof...(_signature) == 0) { // executes when bind doesn't have any explicit signature types specified. (e.g. perfect-forwaring) - error err = error::None; - return { err, Invoker...>::invoke(err, m_method, m_target, std::forward<_args>(params)...) }; + return Invoker...>::invoke(m_method, m_target, std::forward<_args>(params)...); } else { - error err = error::None; - return { err, Invoker<_signature...>::invoke(err, m_method, m_target, std::forward<_args>(params)...) }; + return Invoker<_signature...>::invoke(m_method, m_target, std::forward<_args>(params)...); } } @@ -62,9 +60,8 @@ namespace rtl::detail template template template - inline RObject - DefaultInvoker<_signature...>::Invoker<_invokSignature...>::invoke(error& pError, - const Method& pMethod, + inline Return + DefaultInvoker<_signature...>::Invoker<_invokSignature...>::invoke(const Method& pMethod, const RObject& pTarget, _args&&... params) { @@ -73,7 +70,7 @@ namespace rtl::detail if (constMethodIndex != rtl::index_none) { - return containerConst::template forwardCall<_args...>(pError, pTarget, constMethodIndex, std::forward<_args>(params)...); + return containerConst::template forwardCall<_args...>(pTarget, constMethodIndex, std::forward<_args>(params)...); } else { @@ -83,16 +80,12 @@ namespace rtl::detail if (nonConstMethodIndex != rtl::index_none) { if (!pTarget.isConstCastSafe()) { - pError = error::ConstOverloadMissing; - return RObject{ }; + return { error::ConstOverloadMissing, RObject{} }; } - return containerNonConst::template forwardCall<_args...>(pError, pTarget, nonConstMethodIndex, std::forward<_args>(params)...); - } - else { - pError = error::SignatureMismatch; + return containerNonConst::template forwardCall<_args...>(pTarget, nonConstMethodIndex, std::forward<_args>(params)...); } } - return RObject{ }; + return { error::SignatureMismatch, RObject{} }; } } @@ -113,26 +106,24 @@ namespace rtl::detail * invokes non-static-member-function functor associated with 'm_method' on object 'm_target'. */ template template - inline std::pair NonConstInvoker<_signature...>::call(_args&& ...params) const noexcept + inline Return NonConstInvoker<_signature...>::call(_args&& ...params) const noexcept { if (m_method.getQualifier() == methodQ::None) { return static_cast(m_method).bind().call(std::forward<_args>(params)...); } if (m_target.isEmpty()) { //if the target is empty. - return { error::EmptyRObject, RObject{ } }; + return { error::EmptyRObject, RObject{} }; } if (m_target.getTypeId() != m_method.getRecordTypeId()) { //if the m_target's type-id & type-id of the 'class/struct' owner of the associated functor(m_method's) do not match. - return { error::TargetMismatch, RObject{ } }; + return { error::TargetMismatch, RObject{} }; } if constexpr (sizeof...(_signature) == 0) { - error err = error::None; - return { err, Invoker...>::invoke(err, m_method, m_target, std::forward<_args>(params)...) }; + return Invoker...>::invoke(m_method, m_target, std::forward<_args>(params)...); } else { - error err = error::None; - return { err, Invoker<_signature...>::invoke(err, m_method, m_target, std::forward<_args>(params)...) }; + return Invoker<_signature...>::invoke(m_method, m_target, std::forward<_args>(params)...); } } @@ -141,16 +132,15 @@ namespace rtl::detail template template template - inline RObject - NonConstInvoker<_signature...>::Invoker<_invokSignature...>::invoke(error& pError, - const Method& pMethod, + inline Return + NonConstInvoker<_signature...>::Invoker<_invokSignature...>::invoke(const Method& pMethod, const RObject& pTarget, _args&&... params) { using container0 = detail::MethodContainer; const std::size_t index = pMethod.hasSignatureId(container0::getContainerId()); if (index != rtl::index_none) { - return container0::template forwardCall<_args...>(pError, pTarget, index, std::forward<_args>(params)...); + return container0::template forwardCall<_args...>(pTarget, index, std::forward<_args>(params)...); } else { @@ -159,12 +149,10 @@ namespace rtl::detail std::size_t index = pMethod.hasSignatureId(container2::getContainerId()); if (index != rtl::index_none) { // So, const-overload is present and non-const overload is not registered or doesn't exists. - pError = error::NonConstOverloadMissing; - return RObject{ }; + return { error::NonConstOverloadMissing, RObject{} }; } // else the signature might be wrong. - pError = error::SignatureMismatch; - return RObject{ }; + return { error::SignatureMismatch , RObject{} }; } } } \ No newline at end of file diff --git a/ReflectionTemplateLib/detail/inc/SetupConstructor.h b/ReflectionTemplateLib/detail/inc/SetupConstructor.h index 85b223a4..bc65908e 100644 --- a/ReflectionTemplateLib/detail/inc/SetupConstructor.h +++ b/ReflectionTemplateLib/detail/inc/SetupConstructor.h @@ -26,7 +26,7 @@ namespace rtl { class SetupConstructor { template - using CtorLambda = std::function < RObject(error&, alloc, _signature...) >; + using CtorLambda = std::function < Return(alloc, _signature...) >; template static CtorLambda<_signature...> getConstructorCaller(); diff --git a/ReflectionTemplateLib/detail/inc/SetupConstructor.hpp b/ReflectionTemplateLib/detail/inc/SetupConstructor.hpp index 93b57244..a5d78f4b 100644 --- a/ReflectionTemplateLib/detail/inc/SetupConstructor.hpp +++ b/ReflectionTemplateLib/detail/inc/SetupConstructor.hpp @@ -22,31 +22,32 @@ namespace rtl::detail inline SetupConstructor<_derivedType>::CtorLambda<_signature...> SetupConstructor<_derivedType>::getConstructorCaller() { - return [](error& pError, alloc pAllocType, _signature&&...params)-> RObject + return [](alloc pAllocType, _signature&&...params)-> Return { if constexpr (sizeof...(_signature) == 0 && !std::is_default_constructible_v<_recordType>) { //default constructor, private or deleted. - pError = error::TypeNotDefaultConstructible; - return RObject{ }; + return { error::TypeNotDefaultConstructible, RObject{} }; } else { if (pAllocType == alloc::Stack) { if constexpr (!std::is_copy_constructible_v<_recordType>) { - pError = error::TypeNotCopyConstructible; - return RObject{ }; + return { error::TypeNotCopyConstructible, RObject{} }; } else { - pError = error::None; - return RObjectBuilder::build<_recordType, alloc::Stack>(_recordType(std::forward<_signature>(params)...), true); + return { error::None, + RObjectBuilder::build<_recordType, alloc::Stack>(_recordType(std::forward<_signature>(params)...), + true) }; } } else if (pAllocType == alloc::Heap) { - return RObjectBuilder::build<_recordType*, alloc::Heap>(new _recordType(std::forward<_signature>(params)...), true); + return {error::None, + RObjectBuilder::build<_recordType*, alloc::Heap>(new _recordType(std::forward<_signature>(params)...), + true) }; } } - return RObject{ }; //dead code. compiler warning ommited. + return { error::EmptyRObject, RObject{} }; //dead code. compiler warning omitted. }; } diff --git a/ReflectionTemplateLib/detail/inc/SetupFunction.h b/ReflectionTemplateLib/detail/inc/SetupFunction.h index 39f9c335..131a1f62 100644 --- a/ReflectionTemplateLib/detail/inc/SetupFunction.h +++ b/ReflectionTemplateLib/detail/inc/SetupFunction.h @@ -33,7 +33,7 @@ namespace rtl { class SetupFunction { template - using FunctionLambda = std::function < RObject(error&, _signature...) >; + using FunctionLambda = std::function < Return(_signature...) >; template static FunctionLambda<_signature...> getCaller(_returnType(*pFunctor)(_signature...)); diff --git a/ReflectionTemplateLib/detail/inc/SetupFunction.hpp b/ReflectionTemplateLib/detail/inc/SetupFunction.hpp index 9e4c6e6c..ade7baec 100644 --- a/ReflectionTemplateLib/detail/inc/SetupFunction.hpp +++ b/ReflectionTemplateLib/detail/inc/SetupFunction.hpp @@ -25,27 +25,29 @@ namespace rtl { /* a variable arguments lambda, which finally calls the 'pFunctor' with 'params...'. this is stored in _derivedType's (FunctorContainer) vector holding lambda's. - */ return [=](error& pError, _signature&&...params)-> RObject + */ return [=](_signature&&...params)-> Return { - //call will definitely be successful, since the signature type has alrady been validated. - pError = error::None; constexpr bool isConstCastSafe = (!traits::is_const_v<_returnType>); if constexpr (std::is_same_v<_returnType, void>) { //if the function do not returns anything, this block will be retained by compiler. (*pFunctor)(std::forward<_signature>(params)...); - return RObject{ }; + return { error::None, RObject{} }; } else if constexpr (std::is_reference_v<_returnType>) { /* if the function returns reference, this block will be retained by compiler. Note: reference to temporary or dangling is not checked here. */ using _rawRetType = traits::raw_t<_returnType>; const _rawRetType& retObj = (*pFunctor)(std::forward<_signature>(params)...); - return RObjectBuilder::build(&retObj, isConstCastSafe); + return { error::None, + RObjectBuilder::build(&retObj, + isConstCastSafe) }; } else { //if the function returns anything (not refrence), this block will be retained by compiler. - return RObjectBuilder::build<_returnType, rtl::alloc::Stack>((*pFunctor)(std::forward<_signature>(params)...), isConstCastSafe); + return { error::None, + RObjectBuilder::build<_returnType, rtl::alloc::Stack>((*pFunctor)(std::forward<_signature>(params)...), + isConstCastSafe) }; } }; } diff --git a/ReflectionTemplateLib/detail/inc/SetupMethod.h b/ReflectionTemplateLib/detail/inc/SetupMethod.h index 2b3df564..8456aa6e 100644 --- a/ReflectionTemplateLib/detail/inc/SetupMethod.h +++ b/ReflectionTemplateLib/detail/inc/SetupMethod.h @@ -34,7 +34,7 @@ namespace rtl { class SetupMethod { template - using MethodLambda = std::function < RObject(error&, const rtl::RObject&, _signature...) >; + using MethodLambda = std::function < Return(const rtl::RObject&, _signature...) >; template static MethodLambda<_signature...> getMethodCaller(_returnType(_recordType::* pFunctor)(_signature...)); diff --git a/ReflectionTemplateLib/detail/inc/SetupMethod.hpp b/ReflectionTemplateLib/detail/inc/SetupMethod.hpp index 803f9333..b0ca559e 100644 --- a/ReflectionTemplateLib/detail/inc/SetupMethod.hpp +++ b/ReflectionTemplateLib/detail/inc/SetupMethod.hpp @@ -27,33 +27,34 @@ namespace rtl { /* a variable arguments lambda, which finally calls the 'pFunctor' with 'params...'. this is stored in _derivedType's (MethodContainer) vector holding lambda's. - */ return [=](error& pError, const RObject& pTargetObj, _signature&&...params)-> RObject + */ return [=](const RObject& pTargetObj, _signature&&...params)-> Return { if (!pTargetObj.isConstCastSafe()) { - pError = error::IllegalConstCast; - return RObject{ }; + return { error::IllegalConstCast, RObject{} }; } - //call on 'pFunctor' will definitely be successful, since the object type, signature type has already been validated. - pError = error::None; constexpr bool isConstCastSafe = (!traits::is_const_v<_returnType>); //'target' needs const_cast, since the functor is non-const-member-function. _recordType& target = const_cast<_recordType&>(pTargetObj.view<_recordType>()->get()); if constexpr (std::is_same_v<_returnType, void>) { //if the function do not returns anything, this block will be retained by compiler. (target.*pFunctor)(std::forward<_signature>(params)...); - return RObject{ }; + return { error::None, RObject{} }; } else if constexpr (std::is_reference_v<_returnType>) { /* if the function returns reference, this block will be retained by compiler. Note: reference to temporary or dangling is not checked here. */ using _rawRetType = traits::raw_t<_returnType>; const _rawRetType& retObj = (target.*pFunctor)(std::forward<_signature>(params)...); - return RObjectBuilder::build(&retObj, isConstCastSafe); + return { error::None, + RObjectBuilder::build(&retObj, + isConstCastSafe) }; } else { - return RObjectBuilder::build<_returnType, alloc::Stack>((target.*pFunctor)(std::forward<_signature>(params)...), isConstCastSafe); + return { error::None, + RObjectBuilder::build<_returnType, alloc::Stack>((target.*pFunctor)(std::forward<_signature>(params)...), + isConstCastSafe) }; } }; } @@ -66,10 +67,8 @@ namespace rtl { /* a variable arguments lambda, which finally calls the 'pFunctor' with 'params...'. this is stored in _derivedType's (MethodContainer) vector holding lambda's. - */ return [=](error& pError, const RObject& pTargetObj, _signature&&...params)-> RObject + */ return [=](const RObject& pTargetObj, _signature&&...params)-> Return { - //call will definitely be successful, since the object type, signature type has already been validated. - pError = error::None; constexpr bool isConstCastSafe = (!traits::is_const_v<_returnType>); //'target' is const and 'pFunctor' is const-member-function. const _recordType& target = pTargetObj.view<_recordType>()->get(); @@ -77,17 +76,21 @@ namespace rtl if constexpr (std::is_same_v<_returnType, void>) { //if the function do not returns anything, this block will be retained by compiler. (target.*pFunctor)(std::forward<_signature>(params)...); - return RObject{ }; + return { error::None, RObject{} }; } else if constexpr (std::is_reference_v<_returnType>) { /* if the function returns reference, this block will be retained by compiler. Note: reference to temporary or dangling is not checked here. */ using _rawRetType = traits::raw_t<_returnType>; const _rawRetType& retObj = (target.*pFunctor)(std::forward<_signature>(params)...); - return RObjectBuilder::build(&retObj, isConstCastSafe); + return { error::None, + RObjectBuilder::build(&retObj, + isConstCastSafe) }; } else { - return RObjectBuilder::build<_returnType, alloc::Stack>((target.*pFunctor)(std::forward<_signature>(params)...), isConstCastSafe); + return { error::None, + RObjectBuilder::build<_returnType, alloc::Stack>((target.*pFunctor)(std::forward<_signature>(params)...), + isConstCastSafe) }; } }; } From 7a00a86d97dff39dfcdd7f0ca22206b77de3d43e Mon Sep 17 00:00:00 2001 From: neeraj31285 Date: Sat, 6 Sep 2025 00:18:09 +0530 Subject: [PATCH 4/6] optimized cloner construction --- ReflectionTemplateLib/access/inc/RObject.h | 11 ++-- ReflectionTemplateLib/access/inc/RObject.hpp | 22 +++---- .../detail/inc/RObjectBuilder.h | 5 +- .../detail/inc/RObjectBuilder.hpp | 63 +++++++++++-------- 4 files changed, 56 insertions(+), 45 deletions(-) diff --git a/ReflectionTemplateLib/access/inc/RObject.h b/ReflectionTemplateLib/access/inc/RObject.h index c9cb0869..6a446112 100644 --- a/ReflectionTemplateLib/access/inc/RObject.h +++ b/ReflectionTemplateLib/access/inc/RObject.h @@ -40,15 +40,16 @@ namespace rtl //Reflecting the object within. class RObject { - using Cloner = std::function; + using Cloner = std::function< Return(const RObject&, rtl::alloc) >; - mutable Cloner m_getClone; - mutable std::any m_object; mutable detail::RObjectId m_objectId; + + mutable std::any m_object; + mutable const Cloner* m_getClone; mutable const std::vector* m_converters; RObject(const RObject&) = default; - RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId, + RObject(const detail::RObjectId& pRObjId, std::any&& pObject, const Cloner& pCloner, const std::vector& pConverters); static std::atomic& getInstanceCounter(); @@ -104,6 +105,6 @@ namespace rtl struct [[nodiscard]] Return { error err; - RObject robj; + RObject rObject; }; } \ No newline at end of file diff --git a/ReflectionTemplateLib/access/inc/RObject.hpp b/ReflectionTemplateLib/access/inc/RObject.hpp index b930ebd5..c478a320 100644 --- a/ReflectionTemplateLib/access/inc/RObject.hpp +++ b/ReflectionTemplateLib/access/inc/RObject.hpp @@ -24,24 +24,24 @@ namespace rtl { - inline RObject::RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId, + inline RObject::RObject(const detail::RObjectId& pRObjId, std::any&& pObject, const Cloner& pCloner, const std::vector& pConverters) - : m_getClone(std::forward(pCloner)) + : m_objectId(pRObjId) , m_object(std::forward(pObject)) - , m_objectId(pRObjectId) + , m_getClone(&pCloner) , m_converters(&pConverters) { } inline RObject::RObject(RObject&& pOther) noexcept : m_object(std::move(pOther.m_object)) - , m_getClone(std::move(pOther.m_getClone)) + , m_getClone(pOther.m_getClone) , m_objectId(pOther.m_objectId) , m_converters(pOther.m_converters) { // Explicitly clear moved-from source pOther.m_object.reset(); - pOther.m_objectId = { }; - //pOther.m_getClone = nullptr; + pOther.m_objectId = {}; + pOther.m_getClone = nullptr; pOther.m_converters = nullptr; } @@ -163,18 +163,14 @@ namespace rtl template<> inline Return RObject::createCopy() const { - error err = error::None; - RObject robj/*;//*/ = m_getClone(err, *this, alloc::Heap); - return { err, std::move(robj) }; + return (*m_getClone)(*this, alloc::Heap); } template<> inline Return RObject::createCopy() const { - error err = error::None; - RObject robj/*;//*/ = m_getClone(err, *this, alloc::Stack); - return { err, std::move(robj) }; + return (*m_getClone)(*this, alloc::Stack); } @@ -205,7 +201,7 @@ namespace rtl inline Return RObject::clone() const { if (isEmpty()) { - return { error::EmptyRObject, RObject{ } }; + return { error::EmptyRObject, RObject{} }; } if constexpr (_copyTarget == copy::Value) { return createCopy<_allocOn, detail::EntityKind::Value>(); diff --git a/ReflectionTemplateLib/detail/inc/RObjectBuilder.h b/ReflectionTemplateLib/detail/inc/RObjectBuilder.h index 7b130597..17e0f08c 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectBuilder.h +++ b/ReflectionTemplateLib/detail/inc/RObjectBuilder.h @@ -15,16 +15,17 @@ namespace rtl { class RObject; + struct Return; } namespace rtl::detail { class RObjectBuilder { - using Cloner = std::function; + using Cloner = std::function< Return(const RObject&, rtl::alloc) >; template - static Cloner buildCloner(); + static const Cloner& buildCloner(); template static const std::vector& getConverters(); diff --git a/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp b/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp index ca6e3a19..68fa56e0 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp +++ b/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp @@ -11,6 +11,8 @@ #pragma once +#include + #include "RObject.hpp" #include "RObjectUPtr.h" #include "RObjectBuilder.h" @@ -33,37 +35,43 @@ namespace rtl::detail { } template - inline RObjectBuilder::Cloner RObjectBuilder::buildCloner() + inline const RObjectBuilder::Cloner& RObjectBuilder::buildCloner() { using W = traits::std_wrapper; using _T = std::conditional_t; if constexpr (std::is_copy_constructible_v<_T>) { - return [](error& pError, const RObject& pOther, alloc pAllocOn)-> RObject + static const Cloner cloner = [](const RObject& pOther, alloc pAllocOn) -> Return { const auto& srcObj = pOther.view<_T>()->get(); - pError = error::None; - if (pAllocOn == alloc::Stack) { - return RObjectBuilder::template build<_T, alloc::Stack>(_T(srcObj), true); - } - else if (pAllocOn == alloc::Heap) { - return RObjectBuilder::template build<_T*, alloc::Heap>(new _T(srcObj), true); + switch (pAllocOn) + { + case alloc::Stack: + return { error::None, + RObjectBuilder::template build<_T, alloc::Stack>(_T(srcObj), true) }; + + case alloc::Heap: + return { error::None, + RObjectBuilder::template build<_T*, alloc::Heap>(new _T(srcObj), true) }; + + default: + return { error::EmptyRObject, RObject{} }; } - return RObject{ }; //dead code. compiler warning ommited. }; + return cloner; } - else + else { - return [](error& pError, const RObject& pOther, alloc pAllocOn)-> RObject - { - pError = error::TypeNotCopyConstructible; - return RObject{ }; + static const Cloner cloner = [](const RObject&, alloc) -> Return { + return { error::TypeNotCopyConstructible, RObject{} }; }; + return cloner; } } + template inline RObject RObjectBuilder::build(T&& pVal, const bool pIsConstCastSafe) { @@ -73,32 +81,37 @@ namespace rtl::detail { if constexpr (_allocOn == alloc::Heap) { static_assert(isRawPointer, "Invalid 'alloc' specified for non-pointer-type 'T'"); - _T* objPtr = static_cast<_T*>(pVal); - const RObjectId robjId = RObjectId::create, _allocOn>(pIsConstCastSafe); - const std::vector& conversions = getConverters>(); - return RObject(std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(objPtr))), buildCloner<_T>(), robjId, conversions); + return RObject(RObjectId::create, _allocOn>(pIsConstCastSafe), + std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(static_cast<_T*>(pVal)))), + buildCloner<_T>(), + getConverters>()); } else if constexpr (_allocOn == alloc::Stack) { if constexpr (isRawPointer) { - const RObjectId robjId = RObjectId::create(pIsConstCastSafe); - const std::vector& conversions = getConverters(); - return RObject(std::any(static_cast(pVal)), buildCloner<_T>(), robjId, conversions); + return RObject(RObjectId::create(pIsConstCastSafe), + std::any(static_cast(pVal)), + buildCloner<_T>(), + getConverters()); } else { - const RObjectId robjId = RObjectId::create(pIsConstCastSafe); - const std::vector& conversions = getConverters(); if constexpr (traits::std_wrapper<_T>::type == Wrapper::Unique) { using U = traits::std_wrapper<_T>::value_type; - return RObject(std::any(RObjectUPtr(std::move(pVal))), buildCloner<_T>(), robjId, conversions); + return RObject(RObjectId::create(pIsConstCastSafe), + std::any(RObjectUPtr(std::move(pVal))), + buildCloner<_T>(), + getConverters()); } else { static_assert(std::is_copy_constructible_v<_T>, "T must be copy-constructible (std::any requires this)."); - return RObject(std::any(std::forward(pVal)), buildCloner<_T>(), robjId, conversions); + return RObject(RObjectId::create(pIsConstCastSafe), + std::any(std::forward(pVal)), + buildCloner<_T>(), + getConverters()); } } } From 2ead43b40532241ea1e7509e137486842e22a595 Mon Sep 17 00:00:00 2001 From: neeraj31285 Date: Sat, 6 Sep 2025 00:26:59 +0530 Subject: [PATCH 5/6] fix renaming error --- RTLBenchmarkApp/src/BenchMark.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RTLBenchmarkApp/src/BenchMark.cpp b/RTLBenchmarkApp/src/BenchMark.cpp index 0ab81fe0..6ad69e19 100644 --- a/RTLBenchmarkApp/src/BenchMark.cpp +++ b/RTLBenchmarkApp/src/BenchMark.cpp @@ -103,7 +103,7 @@ namespace rtl_bench { static rtl::Record rNode = cxx_mirror().getRecord("node").value(); static rtl::Method sendMsg = rNode.getMethod("sendMessage").value(); - static rtl::RObject robj = rNode.create().robj; + static rtl::RObject robj = rNode.create().rObject; for (auto _ : state) { @@ -148,7 +148,7 @@ namespace rtl_bench { static rtl::Record rNode = cxx_mirror().getRecord("node").value(); static rtl::Method getMsg = rNode.getMethod("getMessage").value(); - static rtl::RObject robj = rNode.create().robj; + static rtl::RObject robj = rNode.create().rObject; for (auto _ : state) { From 95e8160c1cff016ba95beb6371cc83156b442164 Mon Sep 17 00:00:00 2001 From: neeraj31285 Date: Sat, 6 Sep 2025 00:37:29 +0530 Subject: [PATCH 6/6] minor refactor --- RTLBenchmarkApp/src/BenchMark.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RTLBenchmarkApp/src/BenchMark.cpp b/RTLBenchmarkApp/src/BenchMark.cpp index 6ad69e19..6fc25be5 100644 --- a/RTLBenchmarkApp/src/BenchMark.cpp +++ b/RTLBenchmarkApp/src/BenchMark.cpp @@ -123,7 +123,7 @@ namespace rtl_bench void BenchMark::lambdaCall_withReturn(benchmark::State& state) { - std::function getMsg = [](const char* pMsg) { + static std::function getMsg = [](const char* pMsg) { return getMessage(pMsg); }; @@ -136,7 +136,7 @@ namespace rtl_bench void BenchMark::reflectedCall_withReturn(benchmark::State& state) { - rtl::Function getMsg = cxx_mirror().getFunction("getMessage").value(); + static rtl::Function getMsg = cxx_mirror().getFunction("getMessage").value(); for (auto _ : state) { benchmark::DoNotOptimize(getMsg.bind().call("reflected"));