Skip to content

Commit 7a00a86

Browse files
committed
optimized cloner construction
1 parent 36087b4 commit 7a00a86

File tree

4 files changed

+56
-45
lines changed

4 files changed

+56
-45
lines changed

ReflectionTemplateLib/access/inc/RObject.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ namespace rtl
4040
//Reflecting the object within.
4141
class RObject
4242
{
43-
using Cloner = std::function<RObject(error&, const RObject&, rtl::alloc)>;
43+
using Cloner = std::function< Return(const RObject&, rtl::alloc) >;
4444

45-
mutable Cloner m_getClone;
46-
mutable std::any m_object;
4745
mutable detail::RObjectId m_objectId;
46+
47+
mutable std::any m_object;
48+
mutable const Cloner* m_getClone;
4849
mutable const std::vector<traits::ConverterPair>* m_converters;
4950

5051
RObject(const RObject&) = default;
51-
RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId,
52+
RObject(const detail::RObjectId& pRObjId, std::any&& pObject, const Cloner& pCloner,
5253
const std::vector<traits::ConverterPair>& pConverters);
5354

5455
static std::atomic<std::size_t>& getInstanceCounter();
@@ -104,6 +105,6 @@ namespace rtl
104105

105106
struct [[nodiscard]] Return {
106107
error err;
107-
RObject robj;
108+
RObject rObject;
108109
};
109110
}

ReflectionTemplateLib/access/inc/RObject.hpp

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,24 @@
2424

2525
namespace rtl
2626
{
27-
inline RObject::RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId,
27+
inline RObject::RObject(const detail::RObjectId& pRObjId, std::any&& pObject, const Cloner& pCloner,
2828
const std::vector<traits::ConverterPair>& pConverters)
29-
: m_getClone(std::forward<Cloner>(pCloner))
29+
: m_objectId(pRObjId)
3030
, m_object(std::forward<std::any>(pObject))
31-
, m_objectId(pRObjectId)
31+
, m_getClone(&pCloner)
3232
, m_converters(&pConverters)
3333
{ }
3434

3535
inline RObject::RObject(RObject&& pOther) noexcept
3636
: m_object(std::move(pOther.m_object))
37-
, m_getClone(std::move(pOther.m_getClone))
37+
, m_getClone(pOther.m_getClone)
3838
, m_objectId(pOther.m_objectId)
3939
, m_converters(pOther.m_converters)
4040
{
4141
// Explicitly clear moved-from source
4242
pOther.m_object.reset();
43-
pOther.m_objectId = { };
44-
//pOther.m_getClone = nullptr;
43+
pOther.m_objectId = {};
44+
pOther.m_getClone = nullptr;
4545
pOther.m_converters = nullptr;
4646
}
4747

@@ -163,18 +163,14 @@ namespace rtl
163163
template<>
164164
inline Return RObject::createCopy<alloc::Heap, detail::EntityKind::Value>() const
165165
{
166-
error err = error::None;
167-
RObject robj/*;//*/ = m_getClone(err, *this, alloc::Heap);
168-
return { err, std::move(robj) };
166+
return (*m_getClone)(*this, alloc::Heap);
169167
}
170168

171169

172170
template<>
173171
inline Return RObject::createCopy<alloc::Stack, detail::EntityKind::Value>() const
174172
{
175-
error err = error::None;
176-
RObject robj/*;//*/ = m_getClone(err, *this, alloc::Stack);
177-
return { err, std::move(robj) };
173+
return (*m_getClone)(*this, alloc::Stack);
178174
}
179175

180176

@@ -205,7 +201,7 @@ namespace rtl
205201
inline Return RObject::clone() const
206202
{
207203
if (isEmpty()) {
208-
return { error::EmptyRObject, RObject{ } };
204+
return { error::EmptyRObject, RObject{} };
209205
}
210206
if constexpr (_copyTarget == copy::Value) {
211207
return createCopy<_allocOn, detail::EntityKind::Value>();

ReflectionTemplateLib/detail/inc/RObjectBuilder.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@
1515

1616
namespace rtl {
1717
class RObject;
18+
struct Return;
1819
}
1920

2021
namespace rtl::detail
2122
{
2223
class RObjectBuilder
2324
{
24-
using Cloner = std::function<RObject(error&, const RObject&, rtl::alloc)>;
25+
using Cloner = std::function< Return(const RObject&, rtl::alloc) >;
2526

2627
template <class T>
27-
static Cloner buildCloner();
28+
static const Cloner& buildCloner();
2829

2930
template <class T>
3031
static const std::vector<traits::ConverterPair>& getConverters();

ReflectionTemplateLib/detail/inc/RObjectBuilder.hpp

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#pragma once
1313

14+
#include <utility>
15+
1416
#include "RObject.hpp"
1517
#include "RObjectUPtr.h"
1618
#include "RObjectBuilder.h"
@@ -33,37 +35,43 @@ namespace rtl::detail {
3335
}
3436

3537
template<class T>
36-
inline RObjectBuilder::Cloner RObjectBuilder::buildCloner()
38+
inline const RObjectBuilder::Cloner& RObjectBuilder::buildCloner()
3739
{
3840
using W = traits::std_wrapper<T>;
3941
using _T = std::conditional_t<W::type == Wrapper::None, T, typename W::value_type>;
4042

4143
if constexpr (std::is_copy_constructible_v<_T>)
4244
{
43-
return [](error& pError, const RObject& pOther, alloc pAllocOn)-> RObject
45+
static const Cloner cloner = [](const RObject& pOther, alloc pAllocOn) -> Return
4446
{
4547
const auto& srcObj = pOther.view<_T>()->get();
46-
pError = error::None;
47-
if (pAllocOn == alloc::Stack) {
48-
return RObjectBuilder::template build<_T, alloc::Stack>(_T(srcObj), true);
49-
}
50-
else if (pAllocOn == alloc::Heap) {
51-
return RObjectBuilder::template build<_T*, alloc::Heap>(new _T(srcObj), true);
48+
switch (pAllocOn)
49+
{
50+
case alloc::Stack:
51+
return { error::None,
52+
RObjectBuilder::template build<_T, alloc::Stack>(_T(srcObj), true) };
53+
54+
case alloc::Heap:
55+
return { error::None,
56+
RObjectBuilder::template build<_T*, alloc::Heap>(new _T(srcObj), true) };
57+
58+
default:
59+
return { error::EmptyRObject, RObject{} };
5260
}
53-
return RObject{ }; //dead code. compiler warning ommited.
5461
};
62+
return cloner;
5563
}
56-
else
64+
else
5765
{
58-
return [](error& pError, const RObject& pOther, alloc pAllocOn)-> RObject
59-
{
60-
pError = error::TypeNotCopyConstructible;
61-
return RObject{ };
66+
static const Cloner cloner = [](const RObject&, alloc) -> Return {
67+
return { error::TypeNotCopyConstructible, RObject{} };
6268
};
69+
return cloner;
6370
}
6471
}
6572

6673

74+
6775
template<class T, rtl::alloc _allocOn>
6876
inline RObject RObjectBuilder::build(T&& pVal, const bool pIsConstCastSafe)
6977
{
@@ -73,32 +81,37 @@ namespace rtl::detail {
7381
if constexpr (_allocOn == alloc::Heap)
7482
{
7583
static_assert(isRawPointer, "Invalid 'alloc' specified for non-pointer-type 'T'");
76-
_T* objPtr = static_cast<_T*>(pVal);
77-
const RObjectId robjId = RObjectId::create<std::unique_ptr<_T>, _allocOn>(pIsConstCastSafe);
78-
const std::vector<traits::ConverterPair>& conversions = getConverters<std::unique_ptr<_T>>();
79-
return RObject(std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(objPtr))), buildCloner<_T>(), robjId, conversions);
84+
return RObject(RObjectId::create<std::unique_ptr<_T>, _allocOn>(pIsConstCastSafe),
85+
std::any(RObjectUPtr<_T>(std::unique_ptr<_T>(static_cast<_T*>(pVal)))),
86+
buildCloner<_T>(),
87+
getConverters<std::unique_ptr<_T>>());
8088
}
8189
else if constexpr (_allocOn == alloc::Stack)
8290
{
8391
if constexpr (isRawPointer)
8492
{
85-
const RObjectId robjId = RObjectId::create<T, _allocOn>(pIsConstCastSafe);
86-
const std::vector<traits::ConverterPair>& conversions = getConverters<T>();
87-
return RObject(std::any(static_cast<const _T*>(pVal)), buildCloner<_T>(), robjId, conversions);
93+
return RObject(RObjectId::create<T, _allocOn>(pIsConstCastSafe),
94+
std::any(static_cast<const _T*>(pVal)),
95+
buildCloner<_T>(),
96+
getConverters<T>());
8897
}
8998
else
9099
{
91-
const RObjectId robjId = RObjectId::create<T, _allocOn>(pIsConstCastSafe);
92-
const std::vector<traits::ConverterPair>& conversions = getConverters<T>();
93100
if constexpr (traits::std_wrapper<_T>::type == Wrapper::Unique)
94101
{
95102
using U = traits::std_wrapper<_T>::value_type;
96-
return RObject(std::any(RObjectUPtr<U>(std::move(pVal))), buildCloner<_T>(), robjId, conversions);
103+
return RObject(RObjectId::create<T, _allocOn>(pIsConstCastSafe),
104+
std::any(RObjectUPtr<U>(std::move(pVal))),
105+
buildCloner<_T>(),
106+
getConverters<T>());
97107
}
98108
else
99109
{
100110
static_assert(std::is_copy_constructible_v<_T>, "T must be copy-constructible (std::any requires this).");
101-
return RObject(std::any(std::forward<T>(pVal)), buildCloner<_T>(), robjId, conversions);
111+
return RObject(RObjectId::create<T, _allocOn>(pIsConstCastSafe),
112+
std::any(std::forward<T>(pVal)),
113+
buildCloner<_T>(),
114+
getConverters<T>());
102115
}
103116
}
104117
}

0 commit comments

Comments
 (0)