Skip to content

Commit addfa4c

Browse files
committed
new ctor dispatch defined. wip.
1 parent 0e90096 commit addfa4c

File tree

9 files changed

+164
-50
lines changed

9 files changed

+164
-50
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ define and register everything in an isolated translation unit, *`(MyReflection.
7777
#include <rtl/builder.h> // Reflection builder interface.
7878
7979
rtl::CxxMirror& cxx::mirror() {
80+
// Inherently thread safe.
8081
static auto cxx_mirror = rtl::CxxMirror({
8182
/* ...register all types here... */
8283
});

ReflectionTemplateLib/rtl/builder/RObjectBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ namespace rtl::detail
2929

3030
template <rtl::alloc _allocOn> requires (_allocOn == alloc::Stack)
3131
static RObject build(T&& pVal, std::optional<FunctorId> pClonerId, bool pIsConstCastSafe) noexcept;
32+
33+
template <rtl::alloc _allocOn> requires (_allocOn == alloc::Heap)
34+
static RObject build(T&& pVal, traits::cloner_t pClonerFn, bool pIsConstCastSafe) noexcept;
35+
36+
template <rtl::alloc _allocOn> requires (_allocOn == alloc::Stack)
37+
static RObject build(T&& pVal, traits::cloner_t pClonerFn, bool pIsConstCastSafe) noexcept;
3238
};
3339
}
3440

ReflectionTemplateLib/rtl/builder/RObjectBuilder.hpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace rtl::detail
4343
&getConverters<std::unique_ptr<_T>>());
4444
}
4545

46-
46+
4747
template<class T>
4848
template <rtl::alloc _allocOn> requires (_allocOn == alloc::Stack)
4949
ForceInline RObject RObjectBuilder<T>::build(T&& pVal, std::optional<FunctorId> pClonerId, bool pIsConstCastSafe) noexcept
@@ -81,4 +81,61 @@ namespace rtl::detail
8181
}
8282
}
8383
}
84+
}
85+
86+
87+
88+
namespace rtl::detail
89+
{
90+
template<class T>
91+
template<rtl::alloc _allocOn> requires (_allocOn == alloc::Heap)
92+
inline RObject RObjectBuilder<T>::build(T&& pVal, traits::cloner_t pClonerFn, bool pIsConstCastSafe) noexcept
93+
{
94+
using _T = traits::raw_t<T>;
95+
return RObject( std::any{
96+
std::in_place_type<RObjectUPtr<_T>>,
97+
RObjectUPtr<_T>(std::unique_ptr<_T>(static_cast<_T*>(pVal)))
98+
},
99+
RObjectId::create<std::unique_ptr<_T>, alloc::Heap>(pIsConstCastSafe, pClonerFn),
100+
&getConverters<std::unique_ptr<_T>>());
101+
}
102+
103+
104+
template<class T>
105+
template<rtl::alloc _allocOn> requires (_allocOn == alloc::Stack)
106+
inline RObject RObjectBuilder<T>::build(T&& pVal, traits::cloner_t pClonerFn, bool pIsConstCastSafe) noexcept
107+
{
108+
using _T = traits::raw_t<T>;
109+
constexpr bool isRawPointer = std::is_pointer_v<traits::remove_cref_t<T>>;
110+
111+
if constexpr (isRawPointer)
112+
{
113+
return RObject( std::any { static_cast<const _T*>(pVal) },
114+
RObjectId::create<T, alloc::Stack>(pIsConstCastSafe, pClonerFn),
115+
&getConverters<T>() );
116+
}
117+
else
118+
{
119+
if constexpr (traits::std_wrapper<_T>::type == Wrapper::Unique)
120+
{
121+
using U = traits::std_wrapper<_T>::value_type;
122+
return RObject( std::any {
123+
std::in_place_type<RObjectUPtr<U>>,
124+
RObjectUPtr<U>(std::move(pVal))
125+
},
126+
RObjectId::create<T, alloc::Stack>(pIsConstCastSafe, pClonerFn),
127+
&getConverters<T>() );
128+
}
129+
else
130+
{
131+
static_assert(std::is_copy_constructible_v<_T>, "T must be copy-constructible (std::any requires this).");
132+
return RObject( std::any {
133+
std::in_place_type<T>,
134+
std::forward<T>(pVal)
135+
},
136+
RObjectId::create<T, alloc::Stack>(pIsConstCastSafe, pClonerFn),
137+
&getConverters<T>() );
138+
}
139+
}
140+
}
84141
}

ReflectionTemplateLib/rtl/detail/inc/RObjectId.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ namespace rtl::detail
3131
Wrapper m_wrapperType;
3232
EntityKind m_containsAs;
3333

34+
traits::cloner_t m_clonerFn;
35+
3436
std::optional<FunctorId> m_clonerId;
3537

3638
GETTER(std::size_t, TypeId, m_typeId)
@@ -78,7 +80,36 @@ namespace rtl::detail
7880
_allocOn,
7981
_W::type,
8082
entityKind,
81-
pClonerId
83+
nullptr,
84+
pClonerId
85+
};
86+
}
87+
88+
89+
template<class T, rtl::alloc _allocOn>
90+
ForceInline static RObjectId create(bool pIsConstCastSafe, traits::cloner_t pClonerFn) noexcept
91+
{
92+
// extract wrapper info.
93+
using _W = traits::std_wrapper<traits::raw_t<T>>;
94+
// extract Un-Qualified raw type.
95+
using _T = traits::raw_t<std::conditional_t<(_W::type == Wrapper::None), T, typename _W::value_type>>;
96+
constexpr EntityKind entityKind = getEntityKind<T>();
97+
98+
const std::size_t wrapperId = _W::id();
99+
const std::size_t typeId = rtl::detail::TypeId<_T>::get();
100+
101+
constexpr bool isWrappingConst = (_W::type != Wrapper::None && traits::is_const_v<typename _W::value_type>);
102+
return RObjectId {
103+
104+
isWrappingConst,
105+
pIsConstCastSafe,
106+
typeId,
107+
wrapperId,
108+
_allocOn,
109+
_W::type,
110+
entityKind,
111+
pClonerFn,
112+
std::nullopt
82113
};
83114
}
84115
};

ReflectionTemplateLib/rtl/erasure/aware_constructor.h

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,67 +28,88 @@ namespace rtl::dispatch
2828
aware_constructor(): base_t(this_t::get_allocator())
2929
{ }
3030

31-
template<class ...args_t>
31+
template<class ...args_t>
3232
static Return get_allocator()
3333
{
34-
return [](const detail::FunctorId& pFunctorId, alloc pAllocType, const detail::FunctorId& pClonerId, args_t...params)-> Return
34+
return [](alloc p_alloc_on, args_t...params)-> Return
3535
{
36-
if constexpr (sizeof...(args_t) == 0 && !std::is_default_constructible_v<record_t>)
37-
{ //default constructor, private or deleted.
38-
return { error::TypeNotDefaultConstructible, RObject{} };
39-
}
40-
else
36+
if (p_alloc_on == alloc::Stack)
4137
{
42-
if (pAllocType == alloc::Stack) {
43-
44-
if constexpr (!std::is_copy_constructible_v<record_t>)
45-
{
46-
return { error::TypeNotCopyConstructible, RObject{} };
47-
}
48-
else
49-
{
50-
return {
51-
error::None,
52-
detail::RObjectBuilder<record_t>::template build<alloc::Stack>(
53-
record_t(std::forward<args_t>(params)...), pClonerId, true
54-
)
55-
};
56-
}
57-
}
58-
else if (pAllocType == alloc::Heap)
38+
if constexpr (std::is_copy_constructible_v<record_t>)
5939
{
6040
return {
6141
error::None,
62-
detail::RObjectBuilder<record_t*>::template build<alloc::Heap>(
63-
new record_t(std::forward<args_t>(params)...), pClonerId, true
42+
detail::RObjectBuilder<record_t>::template build<alloc::Stack>(
43+
record_t(std::forward<args_t>(params)...), &aware_constructor<record_t>::cloner, true
6444
)
6545
};
6646
}
6747
}
48+
else if (p_alloc_on == alloc::Heap)
49+
{
50+
return {
51+
error::None,
52+
detail::RObjectBuilder<record_t*>::template build<alloc::Heap>(
53+
new record_t(std::forward<args_t>(params)...), &aware_constructor<record_t>::cloner, true
54+
)
55+
};
56+
}
6857
return { error::EmptyRObject, RObject{} }; //dead code. compiler warning omitted.
6958
};
7059
}
7160

7261

73-
static Return cloner(const detail::FunctorId& pFunctorId, const RObject& pOther, alloc pAllocOn)
62+
static Return allocator(alloc p_alloc_on)
63+
{
64+
if(!std::is_default_constructible_v<record_t>) {
65+
//default constructor, private or deleted.
66+
return { error::TypeNotDefaultConstructible, RObject{} };
67+
}
68+
69+
if (p_alloc_on == alloc::Stack)
70+
{
71+
if constexpr (std::is_copy_constructible_v<record_t>)
72+
{
73+
return {
74+
error::None,
75+
detail::RObjectBuilder<record_t>::template build<alloc::Stack>(
76+
record_t(), &aware_constructor<record_t>::cloner, true
77+
)
78+
};
79+
}
80+
}
81+
else if (p_alloc_on == alloc::Heap)
82+
{
83+
return {
84+
error::None,
85+
detail::RObjectBuilder<record_t*>::template build<alloc::Heap>(
86+
new record_t(), &aware_constructor<record_t>::cloner, true
87+
)
88+
};
89+
}
90+
return { error::EmptyRObject, RObject{} }; //dead code. compiler warning omitted.
91+
}
92+
93+
94+
static Return cloner(alloc p_alloc_on, const RObject& p_other)
7495
{
7596
if constexpr (std::is_copy_constructible_v<record_t>)
7697
{
77-
const auto& srcObj = pOther.view<record_t>()->get();
78-
switch (pAllocOn)
98+
const auto& srcObj = p_other.view<record_t>()->get();
99+
switch (p_alloc_on)
79100
{
80101
case alloc::Stack:
81102
return {
82103
error::None,
83104
detail::RObjectBuilder<record_t>::template build<alloc::Stack>(
84-
record_t(srcObj), pFunctorId, true
105+
record_t(srcObj), &aware_constructor<record_t>::cloner, true
85106
)
86107
};
87108
case alloc::Heap:
88109
return {
89110
error::None,
90111
detail::RObjectBuilder<record_t*>::template build<alloc::Heap>(
91-
new record_t(srcObj), pFunctorId, true
112+
new record_t(srcObj), &aware_constructor<record_t>::cloner, true
92113
)
93114
};
94115
default:

ReflectionTemplateLib/rtl/inc/type_meta.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ namespace rtl
6060
template<class record_t, class ...signature_t>
6161
static type_meta add_ctor();
6262

63-
template<class record_t, class ...signature_t>
64-
static type_meta add_copy_ctor();
65-
6663
template<class ..._signature>
6764
using lambda_fn_t = dispatch::lambda_function<_signature...>;
6865

ReflectionTemplateLib/rtl/inc/type_meta.hpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,24 +88,20 @@ namespace rtl
8888
template<class record_t, class ...signature_t>
8989
inline type_meta type_meta::add_ctor()
9090
{
91-
//auto& fc = cache::function_ptr<Return, signature_t...>::instance();
92-
//auto& lc = cache::lambda_function<Return, signature_t...>::instance();
91+
if constexpr (sizeof...(signature_t) == 0)
92+
{
93+
auto& fc = cache::function_ptr<Return, signature_t...>::instance();
94+
auto& lc = cache::lambda_function<Return, signature_t...>::instance();
9395

94-
//auto fptr = &(dispatch::aware_constructor<record_t>::allocator<signature_t...>);
96+
auto fptr = &(dispatch::aware_constructor<record_t>::allocator);
9597

96-
//auto& functor = fc.push(fptr, p_record_uid, p_member_kind, p_index);
97-
//auto [lambda, elambda] = lc.push(functor);
98+
//auto& functor = fc.push(fptr, p_record_uid, p_member_kind, p_index);
99+
//auto [lambda, elambda] = lc.push(functor);
98100

99-
//functor.set_lambda(lambda);
100-
//functor.set_erasure(elambda);
101+
//functor.set_lambda(lambda);
102+
//functor.set_erasure(elambda);
103+
}
101104

102105
return type_meta();
103106
}
104-
105-
106-
template<class record_t, class ...signature_t>
107-
inline type_meta type_meta::add_copy_ctor()
108-
{
109-
return type_meta();
110-
}
111107
}

ReflectionTemplateLib/rtl/rtl_forward_decls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,8 @@ namespace rtl
113113

114114
template<class record_t, class return_t, class ...signature_t>
115115
struct aware_return_n_target;
116+
117+
template<class record_t, class ...signature_t>
118+
struct aware_constructor;
116119
}
117120
}

ReflectionTemplateLib/rtl/rtl_traits.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ namespace rtl
3030
using ConverterPair = std::pair< std::size_t, Converter >;
3131

3232
using Cloner = detail::FunctorContainer<const RObject&, alloc>;
33+
34+
using cloner_t = Return(*)(alloc, const RObject&);
3335
}
3436

3537
namespace traits

0 commit comments

Comments
 (0)