Skip to content

Commit 16c9b3f

Browse files
committed
enabled operator() based syntax parallel to bind().call()
1 parent d60c9f3 commit 16c9b3f

File tree

12 files changed

+111
-67
lines changed

12 files changed

+111
-67
lines changed

RTLBenchmarkApp/src/BenchMark.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66

77
#include "BenchMark.h"
88

9-
extern std::size_t g_work_load_scale;
9+
extern std::size_t g_work_load;
1010
extern std::optional<std::string> g_work_done;
1111

1212
namespace
1313
{
14-
NOINLINE static std::string work_load(bm::argStr_t& pMsg)
14+
NOINLINE static std::string perform_work(bm::argStr_t& pMsg)
1515
{
1616
auto workStr = std::string();
17-
for(int i = 0; i < g_work_load_scale; ++i)
17+
for(int i = 0; i < g_work_load; ++i)
1818
{
1919
workStr += pMsg;
2020
}
@@ -30,23 +30,23 @@ namespace bm
3030
volatile auto* p = &pMsg;
3131
static_cast<void>(p);
3232

33-
g_work_done = work_load(pMsg);
33+
g_work_done = perform_work(pMsg);
3434
}
3535

3636
NOINLINE void Node::sendMessage(argStr_t pMsg)
3737
{
3838
volatile auto* p = &pMsg;
3939
static_cast<void>(p);
4040

41-
g_work_done = work_load(pMsg);
41+
g_work_done = perform_work(pMsg);
4242
}
4343

4444
NOINLINE retStr_t getMessage(argStr_t pMsg)
4545
{
4646
volatile auto* p = &pMsg;
4747
static_cast<void>(p);
4848

49-
g_work_done = work_load(pMsg);
49+
g_work_done = perform_work(pMsg);
5050
return bm::retStr_t(g_work_done->c_str());
5151
}
5252

@@ -55,7 +55,7 @@ namespace bm
5555
volatile auto* p = &pMsg;
5656
static_cast<void>(p);
5757

58-
g_work_done = work_load(pMsg);
58+
g_work_done = perform_work(pMsg);
5959
return bm::retStr_t(g_work_done->c_str());
6060
}
6161
}

RTLBenchmarkApp/src/ReflectedCall.cpp

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44

55
namespace
66
{
7-
static const rtl::CxxMirror& cxx_mirror()
8-
{
9-
static auto m = rtl::CxxMirror({
7+
static rtl::RObject nodeObj;
8+
static rtl::Method NodeGetMessage;
9+
static rtl::Method NodeSendMessage;
10+
static rtl::Function GetMessage;
11+
static rtl::Function SendMessage;
12+
13+
static auto _= []() {
14+
15+
rtl::CxxMirror m = rtl::CxxMirror({
1016

1117
rtl::type().function("getMessage").build(bm::getMessage),
1218

@@ -18,24 +24,22 @@ namespace
1824

1925
rtl::type().member<bm::Node>().method("getMessage").build(&bm::Node::getMessage)
2026
});
21-
return m;
22-
}
23-
24-
static rtl::Record Node = cxx_mirror().getRecord("Node").value();
25-
26-
static rtl::RObject robj = Node.create<rtl::alloc::Stack>().rObject;
2727

28-
static rtl::Method NodeGetMessage = Node.getMethod("getMessage").value();
29-
30-
static rtl::Method NodeSendMessage = Node.getMethod("sendMessage").value();
28+
GetMessage = m.getFunction("getMessage").value();
29+
30+
SendMessage = m.getFunction("sendMessage").value();
3131

32-
static rtl::Function GetMessage = cxx_mirror().getFunction("getMessage").value();
32+
rtl::Record Node = m.getRecord("Node").value();
3333

34-
static rtl::Function SendMessage = cxx_mirror().getFunction("sendMessage").value();
34+
nodeObj = std::move(Node.create<rtl::alloc::Stack>().rObject);
35+
36+
NodeGetMessage = Node.getMethod("getMessage").value();
37+
NodeSendMessage = Node.getMethod("sendMessage").value();
38+
return true;
39+
}();
3540
}
3641

3742

38-
3943
namespace
4044
{
4145
static auto _test0 = []()
@@ -50,7 +54,7 @@ namespace
5054

5155
static auto _test1 = []()
5256
{
53-
auto err = NodeSendMessage(robj)(bm::g_longStr).err;
57+
auto err = NodeSendMessage(nodeObj)(bm::g_longStr).err;
5458

5559
if (err != rtl::error::None) {
5660
std::cout << "[1] error: " << rtl::to_string(err) << "\n";
@@ -70,7 +74,7 @@ namespace
7074

7175
static auto _test3 = []()
7276
{
73-
auto err = NodeGetMessage(robj)(bm::g_longStr).err;
77+
auto err = NodeGetMessage(nodeObj)(bm::g_longStr).err;
7478

7579
if (err != rtl::error::None) {
7680
std::cout << "[3] error: " << rtl::to_string(err) << "\n";
@@ -86,7 +90,7 @@ void ReflectedCall::noReturn(benchmark::State& state)
8690
static auto _=_test0();
8791
for (auto _: state) {
8892

89-
auto error = SendMessage.bind().call(bm::g_longStr).err;
93+
auto error = SendMessage(bm::g_longStr).err;
9094
benchmark::DoNotOptimize(error);
9195
}
9296
}
@@ -97,7 +101,7 @@ void ReflectedCall::withReturn(benchmark::State& state)
97101
static auto _=_test2();
98102
for (auto _: state)
99103
{
100-
auto error = GetMessage.bind().call(bm::g_longStr).err;
104+
auto error = GetMessage(bm::g_longStr).err;
101105
benchmark::DoNotOptimize(error);
102106
}
103107
}
@@ -108,7 +112,7 @@ void ReflectedMethodCall::noReturn(benchmark::State& state)
108112
static auto _=_test1();
109113
for (auto _: state)
110114
{
111-
auto error = NodeSendMessage.bind(robj).call(bm::g_longStr).err;
115+
auto error = NodeSendMessage(nodeObj)(bm::g_longStr).err;
112116
benchmark::DoNotOptimize(error);
113117
}
114118
}
@@ -119,7 +123,7 @@ void ReflectedMethodCall::withReturn(benchmark::State& state)
119123
static auto _=_test3();
120124
for (auto _: state)
121125
{
122-
auto error = NodeGetMessage.bind(robj).call(bm::g_longStr).err;
126+
auto error = NodeGetMessage(nodeObj)(bm::g_longStr).err;
123127
benchmark::DoNotOptimize(error);
124128
}
125129
}

RTLBenchmarkApp/src/StandardCall.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ void DirectCall::withReturn(benchmark::State& state)
7878

7979
void StdFuncCall::noReturn(benchmark::State& state)
8080
{
81+
static auto _=_new_line();
8182
for (auto _: state)
8283
{
8384
SendMessage(bm::g_longStr);
@@ -99,6 +100,7 @@ void StdFuncMethodCall::noReturn(benchmark::State& state)
99100

100101
void StdFuncCall::withReturn(benchmark::State& state)
101102
{
103+
static auto _=_new_line();
102104
for (auto _: state)
103105
{
104106
benchmark::DoNotOptimize(GetMessage(bm::g_longStr));

RTLBenchmarkApp/src/main.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
11

22
#include <string>
3+
#include <iostream>
34
#include <benchmark/benchmark.h>
45

56
#include "StandardCall.h"
67
#include "ReflectedCall.h"
78

89
BENCHMARK(DirectCall::noReturn);
10+
911
BENCHMARK(StdFuncCall::noReturn);
1012
BENCHMARK(ReflectedCall::noReturn);
1113

1214
BENCHMARK(StdFuncMethodCall::noReturn);
1315
BENCHMARK(ReflectedMethodCall::noReturn);
1416

1517
BENCHMARK(DirectCall::withReturn);
18+
1619
BENCHMARK(StdFuncCall::withReturn);
1720
BENCHMARK(ReflectedCall::withReturn);
1821

1922
BENCHMARK(StdFuncMethodCall::withReturn);
2023
BENCHMARK(ReflectedMethodCall::withReturn);
2124

22-
std::size_t g_work_load_scale = 1;
25+
std::size_t g_work_load = 1;
2326

2427
std::optional<std::string> g_work_done;
2528

26-
#include <benchmark/benchmark.h>
27-
#include <iostream>
28-
2929
int main(int argc, char** argv)
3030
{
3131
if (argc > 1)
3232
{
33-
g_work_load_scale = std::stoi(argv[1]);
33+
g_work_load = std::stoi(argv[1]);
3434
for (int i = 1; i < argc - 1; ++i) {
3535
argv[i] = argv[i + 1];
3636
}
3737
--argc;
3838

3939
std::cout << "\n======== RTL Benchmark Configuration ========\n"
4040
<< "Workload: concatenate string of length 500\n"
41-
<< "Scale : " << g_work_load_scale << " iterations\n"
41+
<< "Scale : " << g_work_load << " iterations\n"
4242
<< "=============================================\n\n";
4343
}
4444

ReflectionTemplateLib/access/inc/Function.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ namespace rtl {
8080
GETTER(std::size_t, RecordTypeId, m_recordTypeId);
8181
GETTER(std::vector<detail::FunctorId>, Functors, m_functorIds);
8282

83+
Function() = default;
8384
Function(Function&&) = default;
8485
Function(const Function&) = default;
8586
Function& operator=(Function&&) = default;
@@ -95,7 +96,7 @@ namespace rtl {
9596
Return operator()(_args&&...params) const noexcept;
9697

9798
template<class ..._signature>
98-
const detail::FunctionCaller<_signature...> bind() const;
99+
const detail::FunctionCaller<_signature...> bind() const noexcept;
99100

100101
friend detail::CxxReflection;
101102
friend detail::ReflectionBuilder;

ReflectionTemplateLib/access/inc/Function.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
namespace rtl
1818
{
1919
template<class ..._signature>
20-
inline const detail::FunctionCaller<_signature...> Function::bind() const
20+
inline const detail::FunctionCaller<_signature...> Function::bind() const noexcept
2121
{
2222
return detail::FunctionCaller<_signature...>{ this };
2323
}
@@ -43,7 +43,7 @@ namespace rtl
4343
*/ template<class ..._args>
4444
inline Return Function::operator()(_args&& ...params) const noexcept
4545
{
46-
return bind().call(std::forward<_args>(params)...);
46+
return detail::FunctionCaller<>{ this }.call(std::forward<_args>(params)...);
4747
}
4848

4949

ReflectionTemplateLib/access/inc/Method.h

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ namespace rtl {
2929
* the returned lambda is then called with the arguments corresponding to the functor associated with it.
3030
*/ class Method : public Function
3131
{
32-
private:
33-
3432
//private ctor, called by 'Record' class.
3533
Method(const Function& pFunction)
3634
: Function(pFunction)
@@ -47,8 +45,16 @@ namespace rtl {
4745

4846
public:
4947

48+
Method() = default;
49+
Method(Method&&) = default;
50+
Method(const Method&) = default;
51+
Method& operator=(Method&&) = default;
52+
Method& operator=(const Method&) = default;
53+
5054
using Function::bind;
5155

56+
GETTER_BOOL(Const, (getQualifier() == detail::methodQ::Const));
57+
5258
//indicates if a particular set of arguments accepted by the functor associated with it.
5359
template<class ..._args>
5460
bool hasSignature() const;
@@ -59,30 +65,14 @@ namespace rtl {
5965
template<class ..._signature>
6066
const detail::NonConstInvoker<_signature...> bind(constCast<RObject>&& pTarget) const;
6167

62-
//friends :)
63-
friend Record;
64-
friend detail::CxxReflection;
65-
66-
template<class ..._signature>
67-
friend struct detail::DefaultInvoker;
68-
69-
template<class ..._signature>
70-
friend struct detail::NonConstInvoker;
71-
72-
public:
73-
74-
GETTER_BOOL(Const, (getQualifier() == detail::methodQ::Const));
75-
7668
/* @method: operator()()
7769
@return: lambda
7870
* accepts no arguments for 'target', since associated functor is static-member-functions.
7971
* returns a lambda, which forwards the call to finally call the associated static-member-function functor.
8072
* provides syntax like,'method()(params...)', first'()' is empty & second'()' takes the actual params.
8173
*/ constexpr auto operator()() const
8274
{
83-
return [this](auto&&...params) {
84-
return Function::operator()(std::forward<decltype(params)> (params)...);
85-
};
75+
return detail::FunctionCaller<>{ this };
8676
}
8777

8878

@@ -92,11 +82,24 @@ namespace rtl {
9282
* accepts 'pTarget', which contains the actual object on which the member-function functor associated with 'this' is invoked.
9383
* returns a lambda, which forwards the call to 'call', finally invoking the associated non-static-member-function functor.
9484
* provides syntax like, 'method(pTarget)(params...)', keeping the target & params seperate.
95-
*/ constexpr auto operator()(const RObject& pTarget) const
85+
*/ constexpr detail::DefaultInvoker<> operator()(const RObject& pTarget) const
86+
{
87+
return detail::DefaultInvoker<>{ this, &pTarget };
88+
}
89+
90+
constexpr detail::NonConstInvoker<> operator()(constCast<RObject>&& pTarget) const
9691
{
97-
return [&](auto&&...params)-> Return {
98-
return bind(pTarget).call(std::forward<decltype(params)>(params)...);
99-
};
92+
return detail::NonConstInvoker<>{ this, &pTarget.m_target };
10093
}
94+
95+
//friends :)
96+
friend Record;
97+
friend detail::CxxReflection;
98+
99+
template<class ..._signature>
100+
friend struct detail::DefaultInvoker;
101+
102+
template<class ..._signature>
103+
friend struct detail::NonConstInvoker;
101104
};
102105
}

ReflectionTemplateLib/access/inc/RObject.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ namespace rtl
6262

6363
RObject() = default;
6464
~RObject() = default;
65-
RObject(RObject&&) noexcept;
66-
RObject& operator=(RObject&&) = delete;
6765
RObject& operator=(const RObject&) = delete;
6866

67+
RObject(RObject&&) noexcept;
68+
RObject& operator=(RObject&&) noexcept;
69+
6970
GETTER_BOOL(Empty, (m_object == std::nullopt))
7071
GETTER_BOOL(OnHeap, (m_objectId.m_allocatedOn == alloc::Heap))
7172
GETTER_BOOL(AllocatedByRtl, (m_objectId.m_allocatedOn == alloc::Heap))

ReflectionTemplateLib/access/inc/RObject.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,23 @@ namespace rtl
4343
pOther.m_converters = nullptr;
4444
}
4545

46+
inline RObject& RObject::operator=(RObject&& pOther) noexcept
47+
{
48+
if (this == &pOther) {
49+
return *this;
50+
}
51+
52+
m_object = std::move(pOther.m_object);
53+
m_objectId = pOther.m_objectId;
54+
m_converters = pOther.m_converters;
55+
56+
// Explicitly clear moved-from source
57+
pOther.m_object = std::nullopt;
58+
pOther.m_objectId = {};
59+
pOther.m_converters = nullptr;
60+
return *this;
61+
}
62+
4663
inline std::atomic<std::size_t>& RObject::getInstanceCounter()
4764
{
4865
static std::atomic<std::size_t> instanceCounter = {0};

0 commit comments

Comments
 (0)