Skip to content

Commit 6e80bf1

Browse files
committed
return-erased static_method test, fixes, doc ups.
1 parent 68d4451 commit 6e80bf1

File tree

6 files changed

+95
-35
lines changed

6 files changed

+95
-35
lines changed

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ Overhead? Practically none. **RTL**’s reflective calls — when return and arg
2525

2626
Yes — `rtl::function`’s dispatch is faster than `std::function`.
2727

28-
> Microbenchmarks show reflective invocations through `rtl::function` have lower call overhead — a single, native pointer jump with no extra indirection. Once the functions start doing real work, both perform identically.
28+
> *Microbenchmarks show reflective invocations through `rtl::function` have lower call overhead — a single, native pointer jump with no extra indirection. Once the functions start doing real work, both perform identically.*
2929
3030
### 💡 In One Line
3131

32-
***"RTL is a lightweight, static library that enables a robust, type-safe run-time reflection system for C++ — as flexible as in managed languages, yet as close as possible to native performance."***
32+
*"RTL is a lightweight, static library that enables a robust, type-safe run-time reflection system for C++ — as flexible as in managed languages, yet as close as possible to native performance."*
3333

3434
## What’s more?
3535

@@ -57,12 +57,13 @@ Yes — `rtl::function`’s dispatch is faster than `std::function`.
5757
Create an instance of `CxxMirror`, passing all type information directly to its constructor — and you’re done!
5858
```c++
5959
auto cxx_mirror = rtl::CxxMirror({
60-
/* ...register all types here... */
61-
rtl::type().function("complexToStr").build(complexToStr),
60+
// Register free function -
61+
rtl::type().function("complexToStr").build(complexToStr),
62+
// Register class 'Person'-
6263
rtl::type().record<Person>("Person").build(),
63-
rtl::type().member<Person>().constructor<std::string, int>().build(),
64-
rtl::type().member<Person>().method("setAge").build(Person::setAge),
65-
rtl::type().member<Person>().method("getName").build(Person::getName)
64+
rtl::type().member<Person>().constructor<std::string, int>().build(), // User defined ctor.
65+
rtl::type().member<Person>().method("setAge").build(Person::setAge), // a setter method.
66+
rtl::type().member<Person>().method("getName").build(Person::getName) // and a getter.
6667
});
6768
```
6869
The `cxx_mirror` object is your gateway to runtime reflection — it lets you query, introspect, and even instantiate types without any compile-time knowledge. It can live anywhere — in any translation unit, quietly sitting in a corner of your codebase. All you need is to expose the `cxx_mirror` wherever reflection is required.
@@ -75,7 +76,7 @@ define and register everything in an isolated translation unit.
7576
```c++
7677
rtl::CxxMirror& cxx::mirror() {
7778
static auto cxx_mirror = rtl::CxxMirror({
78-
/* ...all type registrations... */
79+
/* ...register all types here... */
7980
});
8081
return cxx_mirror;
8182
}

RTLTestRunApp/src/FunctionalityTests/ReflectionOpErrorCodeTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* rtl::error::NonConstOverloadMissing
99
* rtl::error::ConstCallViolation
1010
*
11-
* Covered in BasicTypeErasedDispatch.cpp
11+
* Covered in ReturnTypeErasedDispatch.cpp
1212
* rtl::error::ExplicitRefBindingRequired
1313
*
1414
* and,

RTLTestRunApp/src/FunctionalityTests/TypeErasedReflectiveCalls/BasicTypeErasedDispatch_Function.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ using namespace test_mirror;
1111

1212
namespace rtl_tests
1313
{
14-
TEST(BasicTypeErasedRtl_function, invalid_erased_return_rtl_function)
14+
TEST(ReturnTypeErased_rtl_function, invalid_erased_return_rtl_function)
1515
{
1616
{
1717
rtl::function<rtl::Return()> erased_ret_fn;
@@ -40,7 +40,7 @@ namespace rtl_tests
4040
}
4141

4242

43-
TEST(BasicTypeErasedRtl_function, implicit_resolutions_to_call_by_value_overloads)
43+
TEST(ReturnTypeErased_rtl_function, implicit_resolutions_to_call_by_value_overloads)
4444
{
4545
auto reverseStrOpt = cxx::mirror().getFunction(str_reverseString);
4646
ASSERT_TRUE(reverseStrOpt);
@@ -197,7 +197,7 @@ namespace rtl_tests
197197
}
198198

199199

200-
TEST(BasicTypeErasedRtl_function, implicit_resolution_to_ambiguous_lvalue_and_cref_overload)
200+
TEST(ReturnTypeErased_rtl_function, implicit_resolution_to_ambiguous_lvalue_and_cref_overload)
201201
{
202202
auto revStrOverloadValCRefOpt = cxx::mirror().getFunction(str_revStrOverloadValCRef);
203203
ASSERT_TRUE(revStrOverloadValCRefOpt);
@@ -241,7 +241,7 @@ namespace rtl_tests
241241
}
242242

243243

244-
TEST(BasicTypeErasedRtl_function, explicit_resolution_to_ambiguous_lvalue_and_cref_overload)
244+
TEST(ReturnTypeErased_rtl_function, explicit_resolution_to_ambiguous_lvalue_and_cref_overload)
245245
{
246246
auto revStrOverloadValCRefOpt = cxx::mirror().getFunction(str_revStrOverloadValCRef);
247247
ASSERT_TRUE(revStrOverloadValCRefOpt);
@@ -278,7 +278,7 @@ namespace rtl_tests
278278
}
279279

280280

281-
TEST(BasicTypeErasedRtl_function, implicit_resolution_to_ambiguous_lvalue_and_ref_overload)
281+
TEST(ReturnTypeErased_rtl_function, implicit_resolution_to_ambiguous_lvalue_and_ref_overload)
282282
{
283283
auto revStrOverloadValRefOpt = cxx::mirror().getFunction(str_revStrOverloadValRef);
284284
ASSERT_TRUE(revStrOverloadValRefOpt);
@@ -318,7 +318,7 @@ namespace rtl_tests
318318
}
319319

320320

321-
TEST(BasicTypeErasedRtl_function, explicit_resolution_to_ambiguous_lvalue_and_ref_overload)
321+
TEST(ReturnTypeErased_rtl_function, explicit_resolution_to_ambiguous_lvalue_and_ref_overload)
322322
{
323323
auto revStrOverloadValRefOpt = cxx::mirror().getFunction(str_revStrOverloadValRef);
324324
ASSERT_TRUE(revStrOverloadValRefOpt);
@@ -353,7 +353,7 @@ namespace rtl_tests
353353
}
354354

355355

356-
TEST(BasicTypeErasedRtl_function, calling_non_overloaded_non_const_ref_argument)
356+
TEST(ReturnTypeErased_rtl_function, calling_non_overloaded_non_const_ref_argument)
357357
{
358358
auto revStrNonConstRefArgOpt = cxx::mirror().getFunction(str_revStrNonConstRefArg);
359359
ASSERT_TRUE(revStrNonConstRefArgOpt);
@@ -396,7 +396,7 @@ namespace rtl_tests
396396
}
397397

398398

399-
TEST(BasicTypeErasedRtl_function, calling_non_overloaded_const_ref_argument)
399+
TEST(ReturnTypeErased_rtl_function, calling_non_overloaded_const_ref_argument)
400400
{
401401
auto revStrConstRefArgOpt = cxx::mirror().getFunction(str_revStrConstRefArg);
402402
ASSERT_TRUE(revStrConstRefArgOpt);
@@ -445,7 +445,7 @@ namespace rtl_tests
445445
}
446446

447447

448-
TEST(BasicTypeErasedRtl_function, calling_non_overloaded_rvalue_ref_argument)
448+
TEST(ReturnTypeErased_rtl_function, calling_non_overloaded_rvalue_ref_argument)
449449
{
450450
auto revStrRValueRefArgOpt = cxx::mirror().getFunction(str_revStrRValueRefArg);
451451
ASSERT_TRUE(revStrRValueRefArgOpt);
@@ -476,7 +476,7 @@ namespace rtl_tests
476476
}
477477

478478

479-
TEST(BasicTypeErasedRtl_function, implicit_resolution_to_ambiguous_ref_and_cref_overload)
479+
TEST(ReturnTypeErased_rtl_function, implicit_resolution_to_ambiguous_ref_and_cref_overload)
480480
{
481481
auto revStrOverloadValRefNCrefOpt = cxx::mirror().getFunction(str_revStrOverloadValRefAndCRef);
482482
ASSERT_TRUE(revStrOverloadValRefNCrefOpt);
@@ -507,7 +507,7 @@ namespace rtl_tests
507507
}
508508

509509

510-
TEST(BasicTypeErasedRtl_function, explicit_resolution_to_ambiguous_ref_and_cref_overload)
510+
TEST(ReturnTypeErased_rtl_function, explicit_resolution_to_ambiguous_ref_and_cref_overload)
511511
{
512512
auto revStrOverloadValRefNCrefOpt = cxx::mirror().getFunction(str_revStrOverloadValRefAndCRef);
513513
ASSERT_TRUE(revStrOverloadValRefNCrefOpt);

RTLTestRunApp/src/FunctionalityTests/TypeErasedReflectiveCalls/BasicTypeErasedDispatch_Method.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ using namespace test_mirror;
1212

1313
namespace rtl_tests
1414
{
15-
TEST(BasicTypeErasedRtl_method, invalid_erased_return_rtl_function)
15+
TEST(ReturnTypeErased_rtl_method, invalid_erased_return_rtl_function)
1616
{
1717
{
1818
rtl::method<int, rtl::Return()> erased_ret_mt;
@@ -41,7 +41,7 @@ namespace rtl_tests
4141
}
4242

4343

44-
TEST(BasicTypeErasedRtl_method, implicit_resolutions_to_call_by_value_overloads)
44+
TEST(ReturnTypeErased_rtl_method, implicit_resolutions_to_call_by_value_overloads)
4545
{
4646
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
4747
ASSERT_TRUE(optStringUtil);
@@ -213,7 +213,7 @@ namespace rtl_tests
213213
}
214214

215215

216-
TEST(BasicTypeErasedRtl_method, implicit_resolution_to_ambiguous_lvalue_and_cref_overload)
216+
TEST(ReturnTypeErased_rtl_method, implicit_resolution_to_ambiguous_lvalue_and_cref_overload)
217217
{
218218
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
219219
ASSERT_TRUE(optStringUtil);
@@ -263,7 +263,7 @@ namespace rtl_tests
263263
}
264264

265265

266-
TEST(BasicTypeErasedRtl_method, explicit_resolution_to_ambiguous_lvalue_and_cref_overload)
266+
TEST(ReturnTypeErased_rtl_method, explicit_resolution_to_ambiguous_lvalue_and_cref_overload)
267267
{
268268
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
269269
ASSERT_TRUE(optStringUtil);
@@ -306,7 +306,7 @@ namespace rtl_tests
306306
}
307307

308308

309-
TEST(BasicTypeErasedRtl_method, implicit_resolution_to_ambiguous_lvalue_and_ref_overload)
309+
TEST(ReturnTypeErased_rtl_method, implicit_resolution_to_ambiguous_lvalue_and_ref_overload)
310310
{
311311
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
312312
ASSERT_TRUE(optStringUtil);
@@ -353,7 +353,7 @@ namespace rtl_tests
353353
}
354354

355355

356-
TEST(BasicTypeErasedRtl_method, explicit_resolution_to_ambiguous_lvalue_and_ref_overload)
356+
TEST(ReturnTypeErased_rtl_method, explicit_resolution_to_ambiguous_lvalue_and_ref_overload)
357357
{
358358
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
359359
ASSERT_TRUE(optStringUtil);
@@ -395,7 +395,7 @@ namespace rtl_tests
395395
}
396396

397397

398-
TEST(BasicTypeErasedRtl_method, calling_non_overloaded_non_const_ref_argument)
398+
TEST(ReturnTypeErased_rtl_method, calling_non_overloaded_non_const_ref_argument)
399399
{
400400
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
401401
ASSERT_TRUE(optStringUtil);
@@ -443,7 +443,7 @@ namespace rtl_tests
443443
}
444444

445445

446-
TEST(BasicTypeErasedRtl_method, calling_non_overloaded_const_ref_argument)
446+
TEST(ReturnTypeErased_rtl_method, calling_non_overloaded_const_ref_argument)
447447
{
448448
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
449449
ASSERT_TRUE(optStringUtil);
@@ -498,7 +498,7 @@ namespace rtl_tests
498498
}
499499

500500

501-
TEST(BasicTypeErasedRtl_method, calling_non_overloaded_rvalue_ref_argument)
501+
TEST(ReturnTypeErased_rtl_method, calling_non_overloaded_rvalue_ref_argument)
502502
{
503503
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
504504
ASSERT_TRUE(optStringUtil);
@@ -535,7 +535,7 @@ namespace rtl_tests
535535
}
536536

537537

538-
TEST(BasicTypeErasedRtl_method, implicit_resolution_to_ambiguous_ref_and_cref_overload)
538+
TEST(ReturnTypeErased_rtl_method, implicit_resolution_to_ambiguous_ref_and_cref_overload)
539539
{
540540
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
541541
ASSERT_TRUE(optStringUtil);
@@ -572,7 +572,7 @@ namespace rtl_tests
572572
}
573573

574574

575-
TEST(BasicTypeErasedRtl_method, explicit_resolution_to_ambiguous_ref_and_cref_overload)
575+
TEST(ReturnTypeErased_rtl_method, explicit_resolution_to_ambiguous_ref_and_cref_overload)
576576
{
577577
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_);
578578
ASSERT_TRUE(optStringUtil);

RTLTestRunApp/src/FunctionalityTests/TypeErasedReflectiveCalls/BasicTypeErasedDispatch_StaticMethod.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,58 @@ using namespace test_mirror;
1010

1111
namespace rtl_tests
1212
{
13-
TEST(BasicTypeErasedRtl_static_method, implicit_resolutions_to_call_by_value_overloads)
13+
TEST(ReturnTypeErased_rtl_static_method, using_wrong_class_n_callable_apis_for_static_method)
14+
{
15+
{
16+
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringS::struct_); // has only static-methods.
17+
ASSERT_TRUE(optStringUtil);
18+
19+
std::optional<rtl::Method> reverseString = optStringUtil->getMethod(str_reverseString);
20+
ASSERT_TRUE(reverseString);
21+
{
22+
rtl::method<StringS, rtl::Return(std::string)> reverse_string = reverseString.value()
23+
.targetT<StringS>()
24+
.argsT<std::string>()
25+
.returnT<>();
26+
EXPECT_FALSE(reverse_string);
27+
EXPECT_EQ(reverse_string.get_init_error(), rtl::error::InvalidStaticMethodCaller);
28+
} {
29+
rtl::function<rtl::Return(std::string)> reverse_string = static_cast<rtl::Function>(reverseString.value())
30+
.argsT<std::string>()
31+
.returnT<>();
32+
EXPECT_FALSE(reverse_string);
33+
EXPECT_EQ(reverse_string.get_init_error(), rtl::error::InvalidStaticMethodCaller);
34+
}
35+
} {
36+
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringC::struct_); // doesn't have any static-methods.
37+
ASSERT_TRUE(optStringUtil);
38+
39+
std::optional<rtl::Method> reverseString = optStringUtil->getMethod(str_reverseString);
40+
ASSERT_TRUE(reverseString);
41+
42+
rtl::static_method<rtl::Return(std::string)> reverse_string = reverseString.value()
43+
.argsT<std::string>()
44+
.returnT<>();
45+
EXPECT_FALSE(reverse_string);
46+
EXPECT_EQ(reverse_string.get_init_error(), rtl::error::InvalidNonStaticMethodCaller);
47+
} {
48+
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringM::struct_); // doesn't have any static-methods.
49+
ASSERT_TRUE(optStringUtil);
50+
51+
std::optional<rtl::Method> reverseString = optStringUtil->getMethod(str_reverseString);
52+
ASSERT_TRUE(reverseString);
53+
{
54+
rtl::static_method<rtl::Return(std::string)> reverse_string = reverseString.value()
55+
.argsT<std::string>()
56+
.returnT<>();
57+
EXPECT_FALSE(reverse_string);
58+
EXPECT_EQ(reverse_string.get_init_error(), rtl::error::InvalidNonStaticMethodCaller);
59+
}
60+
}
61+
}
62+
63+
64+
TEST(ReturnTypeErased_rtl_static_method, implicit_resolutions_to_call_by_value_overloads)
1465
{
1566
std::optional<rtl::Record> optStringUtil = cxx::mirror().getRecord(StringS::struct_);
1667
ASSERT_TRUE(optStringUtil);

ReflectionTemplateLib/rtl/detail/inc/FunctionCaller.hpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,17 @@ namespace rtl::detail
118118
continue;
119119
}
120120

121-
if (fnMeta.get_member_kind() != member::None && fnMeta.get_member_kind() != member::Static) {
122-
pHopFn.set_init_error(error::InvalidNonStaticMethodCaller);
123-
return;
121+
if constexpr (member_kind == member::Static) {
122+
if (fnMeta.get_member_kind() != member::Static) {
123+
pHopFn.set_init_error(error::InvalidNonStaticMethodCaller);
124+
return;
125+
}
126+
}
127+
else if constexpr (member_kind == member::None) {
128+
if (fnMeta.get_member_kind() == member::Static) {
129+
pHopFn.set_init_error(error::InvalidStaticMethodCaller);
130+
return;
131+
}
124132
}
125133

126134
auto& erasedRetFn = fnMeta.get_erasure_base()

0 commit comments

Comments
 (0)