Skip to content

Commit 0220696

Browse files
authored
Merge pull request #78 from ReflectCxx/develop
- Optimized RObject → now extremely efficient. - Made RObjectId a pure POD. - Introduced rtl::Return type. - Removed std::pair<rtl::error, rtl::RObject>. - Benchmarks show significant performance improvements. - General code refactoring and cleanup.
2 parents 8b5198f + 95e8160 commit 0220696

31 files changed

+230
-270
lines changed

CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace proxy_test {
3030
* @return The result of the function call as a std::any object.
3131
*/
3232
template<class ..._args>
33-
std::pair<rtl::error, rtl::RObject> forwardCall(const std::string& pFunctionName, _args&& ...params);
33+
rtl::Return forwardCall(const std::string& pFunctionName, _args&& ...params);
3434

3535
/**
3636
* @brief Forwards a call to a static method of the "Original" class.
@@ -41,6 +41,6 @@ namespace proxy_test {
4141
* @return The result of the function call as a std::any object.
4242
*/
4343
template<class ..._args>
44-
static std::pair<rtl::error, rtl::RObject> forwardStaticCall(const std::string& pFunctionName, _args&& ...params);
44+
static rtl::Return forwardStaticCall(const std::string& pFunctionName, _args&& ...params);
4545
};
4646
}

CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/inc/Proxy.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ namespace proxy_test
1515
* @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.
1616
*/
1717
template<class ..._args>
18-
inline std::pair<rtl::error, rtl::RObject> Proxy::forwardCall(const std::string& pFunctionName, _args&& ...params)
18+
inline rtl::Return Proxy::forwardCall(const std::string& pFunctionName, _args&& ...params)
1919
{
2020
const auto orgMethod = OriginalReflection::getClass()->getMethod(pFunctionName);
2121
if (!orgMethod.has_value()) {
22-
return { rtl::error::FunctionNotRegisterd, rtl::RObject() };
22+
return { rtl::error::FunctionNotRegisterd, rtl::RObject{ } };
2323
}
2424
if (orgMethod->hasSignature<_args...>()) {
2525
return orgMethod->bind(m_originalObj).call(std::forward<_args>(params)...);
2626
}
27-
return { rtl::error::SignatureMismatch, rtl::RObject() };
27+
return { rtl::error::SignatureMismatch, rtl::RObject{ } };
2828
}
2929

3030

@@ -40,15 +40,15 @@ namespace proxy_test
4040
* @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.
4141
*/
4242
template<class ..._args>
43-
inline std::pair<rtl::error, rtl::RObject> Proxy::forwardStaticCall(const std::string& pFunctionName, _args&& ...params)
43+
inline rtl::Return Proxy::forwardStaticCall(const std::string& pFunctionName, _args&& ...params)
4444
{
4545
const auto orgMethod = OriginalReflection::getClass()->getMethod(pFunctionName);
4646
if (!orgMethod.has_value()) {
47-
return { rtl::error::FunctionNotRegisterd, rtl::RObject() };
47+
return { rtl::error::FunctionNotRegisterd, rtl::RObject{ } };
4848
}
4949
if (orgMethod->hasSignature<_args...>()) {
5050
return orgMethod->bind().call(std::forward<_args>(params)...);
5151
}
52-
return { rtl::error::SignatureMismatch, rtl::RObject() };
52+
return { rtl::error::SignatureMismatch, rtl::RObject{ } };
5353
}
5454
}

CxxTestDesignPatternsUsingRTL/CxxTestProxyDesignPattern/src/Proxy.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace proxy_test
1515
Proxy::Proxy()
1616
: m_originalObj([&]() {
1717
auto [err, robj] = OriginalReflection::getClass()->create<rtl::alloc::Heap>();
18-
return (err == rtl::error::None ? std::move(robj) : rtl::RObject());
18+
return (err == rtl::error::None ? std::move(robj) : rtl::RObject{ });
1919
}())
2020
{
2121
assert(!m_originalObj.isEmpty() && "Reflected instance creation failed.");

RTLBenchmarkApp/src/BenchMark.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ namespace rtl_bench
7676

7777
void BenchMark::lambdaCall_noReturn(benchmark::State& state)
7878
{
79-
std::function sendMsg = [](const char* pMsg) {
79+
static std::function sendMsg = [](const char* pMsg) {
8080
sendMessage(pMsg);
8181
};
8282

@@ -90,19 +90,20 @@ namespace rtl_bench
9090

9191
void BenchMark::reflectedCall_noReturn(benchmark::State& state)
9292
{
93-
rtl::Function sendMsg = cxx_mirror().getFunction("sendMessage").value();
93+
static rtl::Function sendMsg = cxx_mirror().getFunction("sendMessage").value();
94+
static auto sendMsgCall = sendMsg.bind<const char*>();
9495
for (auto _ : state)
9596
{
96-
benchmark::DoNotOptimize(sendMsg.bind<const char*>().call("reflected"));
97+
benchmark::DoNotOptimize(sendMsgCall.call("reflected"));
9798
}
9899
}
99100

100101

101102
void BenchMark::reflectedMethodCall_noReturn(benchmark::State& state)
102103
{
103-
rtl::Record rNode = cxx_mirror().getRecord("node").value();
104-
rtl::Method sendMsg = rNode.getMethod("sendMessage").value();
105-
rtl::RObject robj = rNode.create<rtl::alloc::Stack>().second;
104+
static rtl::Record rNode = cxx_mirror().getRecord("node").value();
105+
static rtl::Method sendMsg = rNode.getMethod("sendMessage").value();
106+
static rtl::RObject robj = rNode.create<rtl::alloc::Stack>().rObject;
106107

107108
for (auto _ : state)
108109
{
@@ -122,7 +123,7 @@ namespace rtl_bench
122123

123124
void BenchMark::lambdaCall_withReturn(benchmark::State& state)
124125
{
125-
std::function getMsg = [](const char* pMsg) {
126+
static std::function getMsg = [](const char* pMsg) {
126127
return getMessage(pMsg);
127128
};
128129

@@ -135,7 +136,7 @@ namespace rtl_bench
135136

136137
void BenchMark::reflectedCall_withReturn(benchmark::State& state)
137138
{
138-
rtl::Function getMsg = cxx_mirror().getFunction("getMessage").value();
139+
static rtl::Function getMsg = cxx_mirror().getFunction("getMessage").value();
139140
for (auto _ : state)
140141
{
141142
benchmark::DoNotOptimize(getMsg.bind<const char*>().call("reflected"));
@@ -145,9 +146,9 @@ namespace rtl_bench
145146

146147
void BenchMark::reflectedMethodCall_withReturn(benchmark::State& state)
147148
{
148-
rtl::Record rNode = cxx_mirror().getRecord("node").value();
149-
rtl::Method getMsg = rNode.getMethod("getMessage").value();
150-
rtl::RObject robj = rNode.create<rtl::alloc::Stack>().second;
149+
static rtl::Record rNode = cxx_mirror().getRecord("node").value();
150+
static rtl::Method getMsg = rNode.getMethod("getMessage").value();
151+
static rtl::RObject robj = rNode.create<rtl::alloc::Stack>().rObject;
151152

152153
for (auto _ : state)
153154
{

RTLTestRunApp/src/FunctionalityTests/ConstMethodOverloadTests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ namespace rtl_tests
7676

7777
string lastName = person::LAST_NAME;
7878
{
79-
auto [err, ret] = updateLastName->bind(constCast(RObject())).call(lastName);
79+
auto [err, ret] = updateLastName->bind(constCast(RObject{ })).call(lastName);
8080

8181
EXPECT_TRUE(err == error::EmptyRObject);
8282
ASSERT_TRUE(ret.isEmpty());
8383
} {
84-
auto [err, ret] = updateLastName->bind(constCast(RObject())).call(lastName);
84+
auto [err, ret] = updateLastName->bind(constCast(RObject{ })).call(lastName);
8585

8686
EXPECT_TRUE(err == error::EmptyRObject);
8787
ASSERT_TRUE(ret.isEmpty());

ReflectionTemplateLib/access/inc/Function.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ namespace rtl {
9292
bool hasSignature() const;
9393

9494
template<class ..._args>
95-
std::pair<error, RObject> operator()(_args&&...params) const noexcept;
95+
Return operator()(_args&&...params) const noexcept;
9696

9797
template<class ..._signature>
9898
const detail::FunctionCaller<_signature...> bind() const;

ReflectionTemplateLib/access/inc/Function.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ namespace rtl
3737

3838
/* @method: operator()()
3939
@param: variadic arguments.
40-
@return: std::pair<error, RObject>, possible error & return value of from the reflected call.
40+
@return: Return, possible error & return value of from the reflected call.
4141
* if the arguments did not match with any overload, returns RObject with error::SignatureMismatch
4242
* providing optional syntax, Function::call() does the exact same thing.
4343
*/ template<class ..._args>
44-
inline std::pair<error, RObject> Function::operator()(_args&& ...params) const noexcept
44+
inline Return Function::operator()(_args&& ...params) const noexcept
4545
{
4646
return bind().call(std::forward<_args>(params)...);
4747
}

ReflectionTemplateLib/access/inc/Method.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace rtl {
4343

4444
//invokes the constructor associated with this 'Method'
4545
template<class ..._args>
46-
std::pair<error, RObject> invokeCtor(alloc&& pAllocType, _args&&...params) const;
46+
Return invokeCtor(alloc&& pAllocType, _args&&...params) const;
4747

4848
public:
4949

@@ -94,7 +94,7 @@ namespace rtl {
9494
* provides syntax like, 'method(pTarget)(params...)', keeping the target & params seperate.
9595
*/ constexpr auto operator()(const RObject& pTarget) const
9696
{
97-
return [&](auto&&...params)-> std::pair<error, RObject> {
97+
return [&](auto&&...params)-> Return {
9898
return bind(pTarget).call(std::forward<decltype(params)>(params)...);
9999
};
100100
}

ReflectionTemplateLib/access/inc/Method.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace rtl
3434
@return: RStatus
3535
* calls the constructor with given arguments.
3636
*/ template<class ..._args>
37-
inline std::pair<error, RObject> Method::invokeCtor(alloc&& pAllocType, _args&& ...params) const
37+
inline Return Method::invokeCtor(alloc&& pAllocType, _args&& ...params) const
3838
{
3939
return Function::bind().call<alloc, _args...>(std::forward<alloc>(pAllocType), std::forward<_args>(params)...);
4040
}

ReflectionTemplateLib/access/inc/RObject.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,30 @@ namespace rtl::detail
3434

3535
namespace rtl
3636
{
37+
struct Return;
3738
class Function;
3839

3940
//Reflecting the object within.
4041
class RObject
4142
{
42-
using Cloner = std::function<RObject(error&, const RObject&, rtl::alloc)>;
43+
using Cloner = std::function< Return(const RObject&, rtl::alloc) >;
4344

44-
mutable Cloner m_getClone;
45-
mutable std::any m_object;
4645
mutable detail::RObjectId m_objectId;
4746

47+
mutable std::any m_object;
48+
mutable const Cloner* m_getClone;
49+
mutable const std::vector<traits::ConverterPair>* m_converters;
50+
4851
RObject(const RObject&) = default;
49-
RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId);
52+
RObject(const detail::RObjectId& pRObjId, std::any&& pObject, const Cloner& pCloner,
53+
const std::vector<traits::ConverterPair>& pConverters);
5054

5155
static std::atomic<std::size_t>& getInstanceCounter();
5256

57+
std::size_t getConverterIndex(const std::size_t pToTypeId) const;
58+
5359
template<rtl::alloc _allocOn, detail::EntityKind _entityKind>
54-
std::pair<rtl::error, RObject> createCopy() const;
60+
Return createCopy() const;
5561

5662
template<class T>
5763
std::optional<rtl::view<T>> performConversion(const std::size_t pIndex) const;
@@ -79,7 +85,7 @@ namespace rtl
7985
bool canViewAs() const;
8086

8187
template<rtl::alloc _allocOn, rtl::copy _copyTarget = rtl::copy::Auto>
82-
std::pair<rtl::error, RObject> clone() const;
88+
Return clone() const;
8389

8490
template<class T, std::enable_if_t<traits::is_unique_ptr_v<T>, int> = 0>
8591
std::optional<rtl::view<T>> view() const;
@@ -96,4 +102,9 @@ namespace rtl
96102
friend detail::RObjExtractor;
97103
friend detail::RObjectBuilder;
98104
};
105+
106+
struct [[nodiscard]] Return {
107+
error err;
108+
RObject rObject;
109+
};
99110
}

0 commit comments

Comments
 (0)