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 f1394d8b..946b4c37 100644 --- a/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp +++ b/CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp @@ -15,16 +15,16 @@ 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()) { - 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{ } }; } @@ -40,15 +40,15 @@ 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()) { - 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..6fc25be5 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,19 +90,20 @@ 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")); } } 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; + static rtl::Record rNode = cxx_mirror().getRecord("node").value(); + static rtl::Method sendMsg = rNode.getMethod("sendMessage").value(); + static rtl::RObject robj = rNode.create().rObject; for (auto _ : state) { @@ -122,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); }; @@ -135,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")); @@ -145,9 +146,9 @@ 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; + static rtl::Record rNode = cxx_mirror().getRecord("node").value(); + static rtl::Method getMsg = rNode.getMethod("getMessage").value(); + static rtl::RObject robj = rNode.create().rObject; for (auto _ : state) { 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/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 945d230f..6a446112 100644 --- a/ReflectionTemplateLib/access/inc/RObject.h +++ b/ReflectionTemplateLib/access/inc/RObject.h @@ -34,24 +34,30 @@ namespace rtl::detail namespace rtl { + struct Return; class Function; //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(); + 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; @@ -79,7 +85,7 @@ namespace rtl bool canViewAs() const; template - std::pair clone() const; + Return clone() const; template, int> = 0> std::optional> view() const; @@ -96,4 +102,9 @@ namespace rtl friend detail::RObjExtractor; friend detail::RObjectBuilder; }; + + struct [[nodiscard]] Return { + error err; + RObject rObject; + }; } \ No newline at end of file diff --git a/ReflectionTemplateLib/access/inc/RObject.hpp b/ReflectionTemplateLib/access/inc/RObject.hpp index 33bd2bcc..c478a320 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) - : m_getClone(std::forward(pCloner)) + inline RObject::RObject(const detail::RObjectId& pRObjId, std::any&& pObject, const Cloner& pCloner, + const std::vector& pConverters) + : 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.reset(); + pOther.m_objectId = {}; 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); } @@ -143,37 +161,35 @@ 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) }; + return (*m_getClone)(*this, alloc::Heap); } template<> - inline std::pair RObject::createCopy() const + inline Return RObject::createCopy() const { - error err = error::None; - return { err, m_getClone(err, *this, alloc::Stack) }; + return (*m_getClone)(*this, alloc::Stack); } 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) }; @@ -182,10 +198,10 @@ namespace rtl template - inline std::pair RObject::clone() const + 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/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/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/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 51836273..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() }; + 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 bd3fcedd..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) { @@ -40,20 +40,18 @@ 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) - 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/RObjectBuilder.h b/ReflectionTemplateLib/detail/inc/RObjectBuilder.h index c458c635..17e0f08c 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectBuilder.h +++ b/ReflectionTemplateLib/detail/inc/RObjectBuilder.h @@ -15,16 +15,20 @@ 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(); public: diff --git a/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp b/ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp index 499bb36c..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" @@ -22,39 +24,54 @@ 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() + 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) { @@ -64,29 +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); - return RObject(std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(objPtr))), buildCloner<_T>(), robjId); + 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); - return RObject(std::any(static_cast(pVal)), buildCloner<_T>(), robjId); + return RObject(RObjectId::create(pIsConstCastSafe), + std::any(static_cast(pVal)), + buildCloner<_T>(), + getConverters()); } else { - const RObjectId& robjId = RObjectId::create(pIsConstCastSafe); 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(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); + return RObject(RObjectId::create(pIsConstCastSafe), + std::any(std::forward(pVal)), + buildCloner<_T>(), + getConverters()); } } } diff --git a/ReflectionTemplateLib/detail/inc/RObjectId.h b/ReflectionTemplateLib/detail/inc/RObjectId.h index 66ee57e1..4dd628c8 100644 --- a/ReflectionTemplateLib/detail/inc/RObjectId.h +++ b/ReflectionTemplateLib/detail/inc/RObjectId.h @@ -21,89 +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: - - static std::vector m_conversions; - - 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; - - const std::vector& m_converters; - - RObjectId(RObjectId&&) = default; - RObjectId(const RObjectId&) = default; - RObjectId& operator=(RObjectId&&) = delete; - RObjectId& operator=(const RObjectId&) = delete; - + bool m_isWrappingConst; + bool m_isConstCastSafe; - 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) - , m_converters(m_conversions) - { } + std::size_t m_typeId; + std::size_t m_wrapperTypeId; + alloc m_allocatedOn; + Wrapper m_wrapperType; + EntityKind m_containsAs; - RObjectId(alloc pAllocOn, bool pIsConstCastSafe, Wrapper pWrapperType, bool pIsStoredConst, EntityKind pContainsAs, - std::size_t pTypeId, const std::vector& pConverters, 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) - , m_converters(pConverters) - { } - - - 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; - } - - - 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; - } - + GETTER(std::size_t, TypeId, m_typeId) + GETTER(EntityKind, ContainedAs, m_containsAs) template static constexpr EntityKind getEntityKind() @@ -132,14 +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 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); + return RObjectId{ isWrappingConst, pIsConstCastSafe, typeId, wrapperId, _allocOn, _W::type, entityKind }; } }; } \ 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 16577771..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 54e02896..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 628e5b9c..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) }; } }; } 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