Skip to content

Commit 730452d

Browse files
committed
code improved, logic simplified.
1 parent 042335d commit 730452d

16 files changed

+159
-156
lines changed

ReflectionTemplateLib/rtl/detail/inc/FunctionCaller.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ namespace rtl::detail
4444
template<member member_kind, class ..._signature>
4545
struct HopFunction
4646
{
47-
rtl::type_meta m_argsTfnMeta;
47+
std::size_t m_fnIndex;
4848

4949
std::vector<rtl::type_meta> m_overloadsFnMeta = {};
5050

ReflectionTemplateLib/rtl/detail/inc/FunctionCaller.hpp

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,17 @@ namespace rtl::detail
6767
inline constexpr const static_method<return_t(args_t...)> HopFunction<member_kind, args_t...>::returnT() const
6868
{
6969
static_method<return_t(args_t...)> mth;
70-
if (!m_argsTfnMeta.is_empty())
70+
if (m_fnIndex != rtl::index_none)
7171
{
72-
if (m_argsTfnMeta.get_member_kind() != member::Static) {
72+
auto& ty_meta = m_overloadsFnMeta[m_fnIndex];
73+
if (ty_meta.get_member_kind() != member::Static) {
7374
mth.set_init_error(error::InvalidNonStaticMethodCaller);
7475
}
75-
else if (m_argsTfnMeta.get_member_kind() == member::Static &&
76-
traits::uid<return_t>::value == m_argsTfnMeta.get_return_id())
76+
else if (ty_meta.get_member_kind() == member::Static &&
77+
traits::uid<return_t>::value == ty_meta.get_return_id())
7778
{
7879
using function_t = dispatch::function_ptr<return_t, args_t...>;
79-
auto fptr = static_cast<const function_t&>(m_argsTfnMeta.get_functor()).f_ptr();
80+
auto fptr = static_cast<const function_t&>(ty_meta.get_functor()).f_ptr();
8081
return static_method<return_t(args_t...)>(fptr);
8182
}
8283
}
@@ -89,24 +90,61 @@ namespace rtl::detail
8990
inline constexpr const function<return_t(args_t...)> HopFunction<member_kind, args_t...>::returnT() const
9091
{
9192
function<return_t(args_t...)> fn;
92-
if (!m_argsTfnMeta.is_empty())
93+
if (m_fnIndex != rtl::index_none)
9394
{
94-
if (m_argsTfnMeta.get_member_kind() == member::Static)
95+
auto& ty_meta = m_overloadsFnMeta[m_fnIndex];
96+
if (ty_meta.get_member_kind() == member::Static)
9597
{
9698
fn.set_init_error(error::InvalidStaticMethodCaller);
9799
}
98-
else if (m_argsTfnMeta.get_member_kind() == member::None &&
99-
traits::uid<return_t>::value == m_argsTfnMeta.get_return_id())
100+
else if (ty_meta.get_member_kind() == member::None &&
101+
traits::uid<return_t>::value == ty_meta.get_return_id())
100102
{
101103
using function_t = dispatch::function_ptr<return_t, args_t...>;
102-
auto fptr = static_cast<const function_t&>(m_argsTfnMeta.get_functor()).f_ptr();
104+
auto fptr = static_cast<const function_t&>(ty_meta.get_functor()).f_ptr();
103105
return function<return_t(args_t...)>(fptr);
104106
}
105107
}
106108
return fn;
107109
}
108110

109111

112+
template<detail::member member_kind>
113+
template<class ...args_t>
114+
inline constexpr const HopFunction<member_kind, args_t...> Hopper<member_kind>::argsT() const
115+
{
116+
std::vector<rtl::type_meta> fnTyMetas(call_by::ncref);
117+
118+
auto normalId = traits::uid<traits::normal_sign_id_t<args_t...>>::value;
119+
for (auto& ty_meta : m_functorsMeta)
120+
{
121+
if (normalId == ty_meta.get_normal_args_id())
122+
{
123+
if (normalId == ty_meta.get_strict_args_id()) {
124+
fnTyMetas[call_by::value] = ty_meta;
125+
}
126+
else if (!ty_meta.is_any_arg_ncref()) {
127+
fnTyMetas[call_by::cref] = ty_meta;
128+
}
129+
else fnTyMetas.push_back(ty_meta);
130+
}
131+
}
132+
133+
std::size_t index = rtl::index_none;
134+
auto strictId = traits::uid<traits::strict_sign_id_t<args_t...>>::value;
135+
for (int i = 0; i < fnTyMetas.size(); i++)
136+
{
137+
auto& ty_meta = fnTyMetas[i];
138+
if (!ty_meta.is_empty() && ty_meta.get_strict_args_id() == strictId) {
139+
index = i;
140+
break;
141+
}
142+
}
143+
144+
return { index, fnTyMetas };
145+
}
146+
147+
110148
template<member member_kind, class ...args_t>
111149
inline void HopFunction<member_kind, args_t...>::initHopper(function<rtl::Return(args_t...)>& pHopper) const
112150
{
@@ -156,45 +194,4 @@ namespace rtl::detail
156194
pHopper.get_vhop().clear();
157195
}
158196
}
159-
160-
161-
template<detail::member member_kind>
162-
template<class ...args_t>
163-
inline constexpr const HopFunction<member_kind, args_t...> Hopper<member_kind>::argsT() const
164-
{
165-
auto strictArgsId = traits::uid<traits::strict_sign_id_t<args_t...>>::value;
166-
auto normalArgsId = traits::uid<traits::normal_sign_id_t<args_t...>>::value;
167-
168-
rtl::type_meta argsTfnMeta;
169-
//initializing pos '0' with empty 'type_meta'.
170-
std::vector<rtl::type_meta> overloadsFnMeta = { rtl::type_meta() };
171-
172-
for (auto& ty_meta : m_functorsMeta)
173-
{
174-
if (argsTfnMeta.is_empty() && strictArgsId == ty_meta.get_strict_args_id()) {
175-
argsTfnMeta = ty_meta;
176-
}
177-
if (normalArgsId == ty_meta.get_normal_args_id())
178-
{
179-
if (normalArgsId == ty_meta.get_strict_args_id()) {
180-
// same normal & strict ids, means no refs exists in target function's signature
181-
// target's function signature is call by value, always at pos '0'.
182-
// if doesn't exists, this pos is occupied by an empty 'type_meta'.
183-
overloadsFnMeta[0] = ty_meta;
184-
}
185-
else if (!ty_meta.is_any_arg_ncref()) {
186-
// its a const-ref-overload with no non-const-ref in signature, added from pos '1' onwards.
187-
overloadsFnMeta.push_back(ty_meta);
188-
}
189-
}
190-
}
191-
192-
for (auto& ty_meta : m_functorsMeta) {
193-
if (normalArgsId == ty_meta.get_normal_args_id() && ty_meta.is_any_arg_ncref()) {
194-
// any remaining overload, const/non-const ref added from pos '1' onwards.
195-
overloadsFnMeta.push_back(ty_meta);
196-
}
197-
}
198-
return { argsTfnMeta, overloadsFnMeta };
199-
}
200197
}

ReflectionTemplateLib/rtl/detail/inc/MethodInvoker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ namespace rtl::detail
9999
template<class record_t, class ...signature_t>
100100
struct HopMethod
101101
{
102-
rtl::type_meta m_argsTfnMeta;
102+
std::size_t m_fnIndex;
103103

104104
std::vector<rtl::type_meta> m_overloadsFnMeta = {};
105105

ReflectionTemplateLib/rtl/detail/inc/MethodInvoker.hpp

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,16 @@ namespace rtl::detail
175175
inline constexpr const method<record_t, return_t(args_t...)> HopMethod<record_t, args_t...>::returnT() const
176176
{
177177
method<record_t, return_t(args_t...)> mth;
178-
if (!m_argsTfnMeta.is_empty())
178+
if (m_fnIndex != rtl::index_none)
179179
{
180-
if (m_argsTfnMeta.get_member_kind() == member::Static) {
180+
auto& ty_meta = m_overloadsFnMeta[m_fnIndex];
181+
if (ty_meta.get_member_kind() == member::Static) {
181182
mth.set_init_error(error::InvalidStaticMethodCaller);
182183
}
183-
else if(traits::uid<return_t>::value == m_argsTfnMeta.get_return_id()) {
184+
else if(traits::uid<return_t>::value == ty_meta.get_return_id()) {
184185

185186
using method_t = dispatch::method_ptr<record_t, return_t, args_t...>;
186-
auto fptr = static_cast<const method_t&>(m_argsTfnMeta.get_functor()).f_ptr();
187+
auto fptr = static_cast<const method_t&>(ty_meta.get_functor()).f_ptr();
187188
return method<record_t, return_t(args_t...)>(fptr);
188189
}
189190
}
@@ -196,48 +197,40 @@ namespace rtl::detail
196197
inline constexpr HopMethod<record_t, args_t...> Hopper<member_kind, record_t>::argsT() const
197198
{
198199
auto recordId = traits::uid<record_t>::value;
199-
auto strictArgsId = traits::uid<traits::strict_sign_id_t<args_t...>>::value;
200-
auto normalArgsId = traits::uid<traits::normal_sign_id_t<args_t...>>::value;
201-
202-
type_meta argsTfnMeta;
203-
//initializing pos '0' with empty 'type_meta'.
204-
std::vector<type_meta> overloadsFnMeta = { type_meta() };
200+
std::vector<rtl::type_meta> fnTyMetas(call_by::ncref);
205201

202+
auto normalId = traits::uid<traits::normal_sign_id_t<args_t...>>::value;
206203
for (auto& ty_meta : m_functorsMeta)
207204
{
208205
if constexpr (!std::is_same_v<record_t, RObject>)
209206
{
210207
if (recordId != ty_meta.get_record_id()) {
211-
return { argsTfnMeta, overloadsFnMeta };
208+
return { rtl::index_none, fnTyMetas };
212209
}
213210
}
214-
215-
if (argsTfnMeta.is_empty() && strictArgsId == ty_meta.get_strict_args_id()) {
216-
argsTfnMeta = ty_meta;
217-
}
218-
219-
if (normalArgsId == ty_meta.get_normal_args_id())
211+
if (normalId == ty_meta.get_normal_args_id())
220212
{
221-
if (normalArgsId == ty_meta.get_strict_args_id()) {
222-
// same normal & strict ids, means no refs exists in target function's signature
223-
// target's function signature is call by value, always at pos '0'.
224-
// if doesn't exists, this pos is occupied by an empty 'type_meta'.
225-
overloadsFnMeta[0] = ty_meta;
213+
if (normalId == ty_meta.get_strict_args_id()) {
214+
fnTyMetas[call_by::value] = ty_meta;
226215
}
227216
else if (!ty_meta.is_any_arg_ncref()) {
228-
// its a const-ref-overload with no non-const-ref in signature, added from pos '1' onwards.
229-
overloadsFnMeta.push_back(ty_meta);
217+
fnTyMetas[call_by::cref] = ty_meta;
230218
}
219+
else fnTyMetas.push_back(ty_meta);
231220
}
232221
}
233222

234-
for (auto& ty_meta : m_functorsMeta) {
235-
if (recordId == ty_meta.get_record_id() &&
236-
normalArgsId == ty_meta.get_normal_args_id() && ty_meta.is_any_arg_ncref()) {
237-
overloadsFnMeta.push_back(ty_meta);
223+
std::size_t index = rtl::index_none;
224+
auto strictId = traits::uid<traits::strict_sign_id_t<args_t...>>::value;
225+
for (int i = 0; i < fnTyMetas.size(); i++)
226+
{
227+
auto& ty_meta = fnTyMetas[i];
228+
if (!ty_meta.is_empty() && ty_meta.get_strict_args_id() == strictId) {
229+
index = i;
230+
break;
238231
}
239232
}
240-
return { argsTfnMeta, overloadsFnMeta };
233+
return { index, fnTyMetas };
241234
}
242235

243236

@@ -288,7 +281,6 @@ namespace rtl::detail
288281
auto fn = lambda.template operator() < dispatch::fn_void::no > ();
289282
pHopper.get_rhop().push_back(fn.f_ptr());
290283
}
291-
292284
pHopper.get_overloads().push_back(&ty_meta.get_functor());
293285
pHopper.set_init_error(error::None);
294286
}

ReflectionTemplateLib/rtl/inc/RObject.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
namespace rtl
2727
{
2828
ForceInline RObject::RObject(std::any&& pObject, const detail::RObjectId& pRObjId,
29-
const std::vector<traits::ConverterPair>* pConverters) noexcept
29+
const std::vector<traits::ConverterPair>* pConverters) noexcept
3030
: m_object(std::in_place, std::move(pObject))
3131
, m_objectId(pRObjId)
3232
, m_converters(pConverters)

ReflectionTemplateLib/rtl/inc/Record.h

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include <unordered_map>
1717

1818
#include "Method.h"
19-
#include "rtl_constants.h"
19+
#include "rtl_constructor.h"
2020

2121
namespace rtl::detail
2222
{
@@ -65,6 +65,9 @@ namespace rtl {
6565
GETTER_CREF(MethodMap, MethodMap, m_methods)
6666
GETTER_CREF(std::string, RecordName, m_recordName)
6767

68+
template<class ...args_t>
69+
constructor<args_t...> ctor() const;
70+
6871
/* @method: getMethod
6972
@param: const std::string& (name of the method)
7073
@return: std::optional<Method>
@@ -100,4 +103,46 @@ namespace rtl {
100103
//only class which can create objects of this class & manipulates 'm_methods'.
101104
friend class detail::CxxReflection;
102105
};
106+
}
107+
108+
109+
namespace rtl
110+
{
111+
template<class ...args_t>
112+
inline constructor<args_t...> Record::ctor() const
113+
{
114+
constructor<args_t...> fnCtor;
115+
const auto& method = m_methods.at(detail::ctor_name(m_recordName));
116+
const auto& functorsMeta = method.getFunctorsMeta();
117+
118+
std::vector<rtl::type_meta> fnTyMetas(detail::call_by::ncref);
119+
120+
auto normalId = traits::uid<traits::normal_sign_id_t<args_t...>>::value;
121+
for (auto& ty_meta : functorsMeta)
122+
{
123+
if (normalId == ty_meta.get_normal_args_id())
124+
{
125+
if (normalId == ty_meta.get_strict_args_id()) {
126+
fnTyMetas[detail::call_by::value] = ty_meta;
127+
}
128+
else if (!ty_meta.is_any_arg_ncref()) {
129+
fnTyMetas[detail::call_by::cref] = ty_meta;
130+
}
131+
else fnTyMetas.push_back(ty_meta);
132+
}
133+
}
134+
135+
std::size_t index = rtl::index_none;
136+
auto strictId = traits::uid<traits::strict_sign_id_t<args_t...>>::value;
137+
for (int i = 0; i < fnTyMetas.size(); i++)
138+
{
139+
auto& ty_meta = fnTyMetas[i];
140+
if (!ty_meta.is_empty() && ty_meta.get_strict_args_id() == strictId) {
141+
index = i;
142+
break;
143+
}
144+
}
145+
146+
return fnCtor;
147+
}
103148
}

ReflectionTemplateLib/rtl/inc/type_meta.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ namespace rtl
4848
GETTER_CREF(dispatch::functor, _functor, m_functor->get())
4949

5050
template<class return_t, class ...signature_t>
51-
static type_meta add_function(return_t(*p_fptr)(signature_t...), traits::uid_t p_record_uid, detail::member p_member_kind, std::size_t p_index);
51+
static type_meta add_function(return_t(*p_fptr)(signature_t...), traits::uid_t p_record_uid,
52+
detail::member p_member_kind, std::size_t p_index);
5253

5354
template<class record_t, class return_t, class ...signature_t>
5455
static type_meta add_method(return_t(record_t::* p_fptr)(signature_t...), std::size_t p_index);

ReflectionTemplateLib/rtl/rtl_constants.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ namespace rtl {
4747
enum class copy
4848
{
4949
/*
50-
* An rtl::RObject may internally hold values wrapped in std::optional,
50+
* An rtl::RObject may internally hold value wrapped in std::optional,
5151
* std::reference_wrapper, or smart pointers. The copy policy gives users
5252
* control over whether cloning should duplicate the wrapper itself or
5353
* perform a deep copy of the underlying object.
5454
*
5555
* Auto (default):
5656
* - RTL first attempts a wrapper-level copy if the wrapper is copyable.
57-
* - If the wrapper is an internal detail (e.g., heap objects stored in
58-
* std::unique_ptr), RTL transparently performs a deep copy of the
59-
* underlying object instead of copying the wrapper.
57+
* - If the wrapper is an internal detail (e.g., heap objects created via
58+
* RTL, stored in std::unique_ptr), RTL transparently performs a deep
59+
* copy of the underlying object instead of copying the wrapper.
6060
* - This ensures correct semantics even when the user is unaware of
6161
* wrapper details (typical in reflection use cases).
6262
* - When explicitly requested, users can still attempt Value or Wrapper

ReflectionTemplateLib/rtl/rtl_constructor.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ namespace rtl
3434

3535
public:
3636

37-
enum call_by {
38-
value = 0,
39-
cref = 1, //const ref.
40-
ncref = 2 //non-const ref.
41-
};
42-
4337
GETTER(rtl::error, _init_error, m_init_err)
4438

4539
constexpr operator bool() const noexcept {
@@ -48,8 +42,8 @@ namespace rtl
4842
}
4943

5044
constexpr bool must_bind_refs() const noexcept {
51-
return (m_functors[call_by::value] == nullptr &&
52-
(m_functors.size() > call_by::ncref || m_functors[call_by::cref]->is_any_arg_ncref()));
45+
return (m_functors[detail::call_by::value] == nullptr &&
46+
(m_functors.size() > detail::call_by::ncref || m_functors[detail::call_by::cref]->is_any_arg_ncref()));
5347
}
5448

5549
template<class ...args_t>
@@ -64,7 +58,7 @@ namespace rtl
6458
return { error::ExplicitRefBindingRequired, RObject{} };
6559
}
6660

67-
auto index = (m_functors[call_by::value] != nullptr ? call_by::value : call_by::cref);
61+
auto index = (m_functors[detail::call_by::value] != nullptr ? detail::call_by::value : detail::call_by::cref);
6862
return m_hop[index](p_alloc_on, std::forward<args_t>(params)...);
6963
}
7064

@@ -99,6 +93,8 @@ namespace rtl
9993
return perfect_fwd<args_t...>{ *this };
10094
}
10195

96+
friend Record;
97+
10298
static_assert((!std::is_reference_v<signature_t> && ...),
10399
"rtl::function<...>: any type cannot be specified as reference here");
104100
};

0 commit comments

Comments
 (0)