Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace proxy_test {
* @return The result of the function call as a std::any object.
*/
template<class ..._args>
std::pair<rtl::error, rtl::RObject> forwardCall(const std::string& pFunctionName, _args&& ...params);
rtl::Return forwardCall(const std::string& pFunctionName, _args&& ...params);

/**
* @brief Forwards a call to a static method of the "Original" class.
Expand All @@ -41,6 +41,6 @@ namespace proxy_test {
* @return The result of the function call as a std::any object.
*/
template<class ..._args>
static std::pair<rtl::error, rtl::RObject> forwardStaticCall(const std::string& pFunctionName, _args&& ...params);
static rtl::Return forwardStaticCall(const std::string& pFunctionName, _args&& ...params);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ namespace proxy_test
* @return The result of the function call as a std::any object. If the method does not exist or the signature does not match, returns an empty std::any object.
*/
template<class ..._args>
inline std::pair<rtl::error, rtl::RObject> Proxy::forwardCall(const std::string& pFunctionName, _args&& ...params)
inline rtl::Return Proxy::forwardCall(const std::string& pFunctionName, _args&& ...params)
{
const auto orgMethod = OriginalReflection::getClass()->getMethod(pFunctionName);
if (!orgMethod.has_value()) {
return { rtl::error::FunctionNotRegisterd, rtl::RObject() };
return { rtl::error::FunctionNotRegisterd, rtl::RObject{ } };
}
if (orgMethod->hasSignature<_args...>()) {
return orgMethod->bind(m_originalObj).call(std::forward<_args>(params)...);
}
return { rtl::error::SignatureMismatch, rtl::RObject() };
return { rtl::error::SignatureMismatch, rtl::RObject{ } };
}


Expand All @@ -40,15 +40,15 @@ namespace proxy_test
* @return The result of the function call as a std::any object. If the method does not exist or the signature does not match, returns an empty std::any object.
*/
template<class ..._args>
inline std::pair<rtl::error, rtl::RObject> Proxy::forwardStaticCall(const std::string& pFunctionName, _args&& ...params)
inline rtl::Return Proxy::forwardStaticCall(const std::string& pFunctionName, _args&& ...params)
{
const auto orgMethod = OriginalReflection::getClass()->getMethod(pFunctionName);
if (!orgMethod.has_value()) {
return { rtl::error::FunctionNotRegisterd, rtl::RObject() };
return { rtl::error::FunctionNotRegisterd, rtl::RObject{ } };
}
if (orgMethod->hasSignature<_args...>()) {
return orgMethod->bind().call(std::forward<_args>(params)...);
}
return { rtl::error::SignatureMismatch, rtl::RObject() };
return { rtl::error::SignatureMismatch, rtl::RObject{ } };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace proxy_test
Proxy::Proxy()
: m_originalObj([&]() {
auto [err, robj] = OriginalReflection::getClass()->create<rtl::alloc::Heap>();
return (err == rtl::error::None ? std::move(robj) : rtl::RObject());
return (err == rtl::error::None ? std::move(robj) : rtl::RObject{ });
}())
{
assert(!m_originalObj.isEmpty() && "Reflected instance creation failed.");
Expand Down
23 changes: 12 additions & 11 deletions RTLBenchmarkApp/src/BenchMark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ namespace rtl_bench

void BenchMark::lambdaCall_noReturn(benchmark::State& state)
{
std::function sendMsg = [](const char* pMsg) {
static std::function sendMsg = [](const char* pMsg) {
sendMessage(pMsg);
};

Expand All @@ -90,19 +90,20 @@ namespace rtl_bench

void BenchMark::reflectedCall_noReturn(benchmark::State& state)
{
rtl::Function sendMsg = cxx_mirror().getFunction("sendMessage").value();
static rtl::Function sendMsg = cxx_mirror().getFunction("sendMessage").value();
static auto sendMsgCall = sendMsg.bind<const char*>();
for (auto _ : state)
{
benchmark::DoNotOptimize(sendMsg.bind<const char*>().call("reflected"));
benchmark::DoNotOptimize(sendMsgCall.call("reflected"));
}
}


void BenchMark::reflectedMethodCall_noReturn(benchmark::State& state)
{
rtl::Record rNode = cxx_mirror().getRecord("node").value();
rtl::Method sendMsg = rNode.getMethod("sendMessage").value();
rtl::RObject robj = rNode.create<rtl::alloc::Stack>().second;
static rtl::Record rNode = cxx_mirror().getRecord("node").value();
static rtl::Method sendMsg = rNode.getMethod("sendMessage").value();
static rtl::RObject robj = rNode.create<rtl::alloc::Stack>().rObject;

for (auto _ : state)
{
Expand All @@ -122,7 +123,7 @@ namespace rtl_bench

void BenchMark::lambdaCall_withReturn(benchmark::State& state)
{
std::function getMsg = [](const char* pMsg) {
static std::function getMsg = [](const char* pMsg) {
return getMessage(pMsg);
};

Expand All @@ -135,7 +136,7 @@ namespace rtl_bench

void BenchMark::reflectedCall_withReturn(benchmark::State& state)
{
rtl::Function getMsg = cxx_mirror().getFunction("getMessage").value();
static rtl::Function getMsg = cxx_mirror().getFunction("getMessage").value();
for (auto _ : state)
{
benchmark::DoNotOptimize(getMsg.bind<const char*>().call("reflected"));
Expand All @@ -145,9 +146,9 @@ namespace rtl_bench

void BenchMark::reflectedMethodCall_withReturn(benchmark::State& state)
{
rtl::Record rNode = cxx_mirror().getRecord("node").value();
rtl::Method getMsg = rNode.getMethod("getMessage").value();
rtl::RObject robj = rNode.create<rtl::alloc::Stack>().second;
static rtl::Record rNode = cxx_mirror().getRecord("node").value();
static rtl::Method getMsg = rNode.getMethod("getMessage").value();
static rtl::RObject robj = rNode.create<rtl::alloc::Stack>().rObject;

for (auto _ : state)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ namespace rtl_tests

string lastName = person::LAST_NAME;
{
auto [err, ret] = updateLastName->bind(constCast(RObject())).call(lastName);
auto [err, ret] = updateLastName->bind(constCast(RObject{ })).call(lastName);

EXPECT_TRUE(err == error::EmptyRObject);
ASSERT_TRUE(ret.isEmpty());
} {
auto [err, ret] = updateLastName->bind(constCast(RObject())).call(lastName);
auto [err, ret] = updateLastName->bind(constCast(RObject{ })).call(lastName);

EXPECT_TRUE(err == error::EmptyRObject);
ASSERT_TRUE(ret.isEmpty());
Expand Down
2 changes: 1 addition & 1 deletion ReflectionTemplateLib/access/inc/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ namespace rtl {
bool hasSignature() const;

template<class ..._args>
std::pair<error, RObject> operator()(_args&&...params) const noexcept;
Return operator()(_args&&...params) const noexcept;

template<class ..._signature>
const detail::FunctionCaller<_signature...> bind() const;
Expand Down
4 changes: 2 additions & 2 deletions ReflectionTemplateLib/access/inc/Function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ namespace rtl

/* @method: operator()()
@param: variadic arguments.
@return: std::pair<error, RObject>, possible error & return value of from the reflected call.
@return: Return, possible error & return value of from the reflected call.
* if the arguments did not match with any overload, returns RObject with error::SignatureMismatch
* providing optional syntax, Function::call() does the exact same thing.
*/ template<class ..._args>
inline std::pair<error, RObject> Function::operator()(_args&& ...params) const noexcept
inline Return Function::operator()(_args&& ...params) const noexcept
{
return bind().call(std::forward<_args>(params)...);
}
Expand Down
4 changes: 2 additions & 2 deletions ReflectionTemplateLib/access/inc/Method.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace rtl {

//invokes the constructor associated with this 'Method'
template<class ..._args>
std::pair<error, RObject> invokeCtor(alloc&& pAllocType, _args&&...params) const;
Return invokeCtor(alloc&& pAllocType, _args&&...params) const;

public:

Expand Down Expand Up @@ -94,7 +94,7 @@ namespace rtl {
* provides syntax like, 'method(pTarget)(params...)', keeping the target & params seperate.
*/ constexpr auto operator()(const RObject& pTarget) const
{
return [&](auto&&...params)-> std::pair<error, RObject> {
return [&](auto&&...params)-> Return {
return bind(pTarget).call(std::forward<decltype(params)>(params)...);
};
}
Expand Down
2 changes: 1 addition & 1 deletion ReflectionTemplateLib/access/inc/Method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace rtl
@return: RStatus
* calls the constructor with given arguments.
*/ template<class ..._args>
inline std::pair<error, RObject> Method::invokeCtor(alloc&& pAllocType, _args&& ...params) const
inline Return Method::invokeCtor(alloc&& pAllocType, _args&& ...params) const
{
return Function::bind().call<alloc, _args...>(std::forward<alloc>(pAllocType), std::forward<_args>(params)...);
}
Expand Down
23 changes: 17 additions & 6 deletions ReflectionTemplateLib/access/inc/RObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,30 @@ namespace rtl::detail

namespace rtl
{
struct Return;
class Function;

//Reflecting the object within.
class RObject
{
using Cloner = std::function<RObject(error&, const RObject&, rtl::alloc)>;
using Cloner = std::function< Return(const RObject&, rtl::alloc) >;

mutable Cloner m_getClone;
mutable std::any m_object;
mutable detail::RObjectId m_objectId;

mutable std::any m_object;
mutable const Cloner* m_getClone;
mutable const std::vector<traits::ConverterPair>* m_converters;

RObject(const RObject&) = default;
RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId);
RObject(const detail::RObjectId& pRObjId, std::any&& pObject, const Cloner& pCloner,
const std::vector<traits::ConverterPair>& pConverters);

static std::atomic<std::size_t>& getInstanceCounter();

std::size_t getConverterIndex(const std::size_t pToTypeId) const;

template<rtl::alloc _allocOn, detail::EntityKind _entityKind>
std::pair<rtl::error, RObject> createCopy() const;
Return createCopy() const;

template<class T>
std::optional<rtl::view<T>> performConversion(const std::size_t pIndex) const;
Expand Down Expand Up @@ -79,7 +85,7 @@ namespace rtl
bool canViewAs() const;

template<rtl::alloc _allocOn, rtl::copy _copyTarget = rtl::copy::Auto>
std::pair<rtl::error, RObject> clone() const;
Return clone() const;

template<class T, std::enable_if_t<traits::is_unique_ptr_v<T>, int> = 0>
std::optional<rtl::view<T>> view() const;
Expand All @@ -96,4 +102,9 @@ namespace rtl
friend detail::RObjExtractor;
friend detail::RObjectBuilder;
};

struct [[nodiscard]] Return {
error err;
RObject rObject;
};
}
58 changes: 37 additions & 21 deletions ReflectionTemplateLib/access/inc/RObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,25 @@

namespace rtl
{
inline RObject::RObject(std::any&& pObject, Cloner&& pCloner, const detail::RObjectId& pRObjectId)
: m_getClone(std::forward<Cloner>(pCloner))
inline RObject::RObject(const detail::RObjectId& pRObjId, std::any&& pObject, const Cloner& pCloner,
const std::vector<traits::ConverterPair>& pConverters)
: m_objectId(pRObjId)
, m_object(std::forward<std::any>(pObject))
, m_objectId(pRObjectId)
, m_getClone(&pCloner)
, m_converters(&pConverters)
{ }

inline RObject::RObject(RObject&& pOther) noexcept
: m_object(std::move(pOther.m_object))
, m_getClone(std::move(pOther.m_getClone))
, m_getClone(pOther.m_getClone)
, m_objectId(pOther.m_objectId)
, m_converters(pOther.m_converters)
{
// Explicitly clear moved-from source
pOther.m_object.reset();
pOther.m_objectId.reset();
pOther.m_objectId = {};
pOther.m_getClone = nullptr;
pOther.m_converters = nullptr;
}

inline std::atomic<std::size_t>& RObject::getInstanceCounter()
Expand All @@ -47,6 +51,20 @@ namespace rtl
return instanceCounter;
}


inline std::size_t RObject::getConverterIndex(const std::size_t pToTypeId) const
{
if (m_objectId.m_containsAs != detail::EntityKind::None) {
for (std::size_t index = 0; index < m_converters->size(); index++) {
if ((*m_converters)[index].first == pToTypeId) {
return index;
}
}
}
return index_none;
}


template<class T>
inline bool RObject::canViewAs() const
{
Expand All @@ -57,7 +75,7 @@ namespace rtl
}
}
const auto& typeId = detail::TypeId<T>::get();
return (m_objectId.m_typeId == typeId || m_objectId.getConverterIndex(typeId) != index_none);
return (m_objectId.m_typeId == typeId || getConverterIndex(typeId) != index_none);
}
}

Expand All @@ -66,7 +84,7 @@ namespace rtl
inline std::optional<rtl::view<T>> RObject::performConversion(const std::size_t pIndex) const
{
detail::EntityKind newKind = detail::EntityKind::None;
const traits::Converter& convert = m_objectId.m_converters[pIndex].second;
const traits::Converter& convert = (*m_converters)[pIndex].second;
const std::any& viewObj = convert(m_object, m_objectId.m_containsAs, newKind);
const T* viewRef = detail::RObjExtractor::getPointer<T>(viewObj, newKind);

Expand Down Expand Up @@ -128,7 +146,7 @@ namespace rtl
}
else
{
const std::size_t index = m_objectId.getConverterIndex(asTypeId);
const std::size_t index = getConverterIndex(asTypeId);
if (index != index_none) {
return performConversion<T>(index);
}
Expand All @@ -143,37 +161,35 @@ namespace rtl
namespace rtl
{
template<>
inline std::pair<error, RObject> RObject::createCopy<alloc::Heap, detail::EntityKind::Value>() const
inline Return RObject::createCopy<alloc::Heap, detail::EntityKind::Value>() const
{
error err = error::None;
return { err, m_getClone(err, *this, alloc::Heap) };
return (*m_getClone)(*this, alloc::Heap);
}


template<>
inline std::pair<error, RObject> RObject::createCopy<alloc::Stack, detail::EntityKind::Value>() const
inline Return RObject::createCopy<alloc::Stack, detail::EntityKind::Value>() const
{
error err = error::None;
return { err, m_getClone(err, *this, alloc::Stack) };
return (*m_getClone)(*this, alloc::Stack);
}


template<>
inline std::pair<error, RObject> RObject::createCopy<alloc::Heap, detail::EntityKind::Wrapper>() const
inline Return RObject::createCopy<alloc::Heap, detail::EntityKind::Wrapper>() const
{
return { error::StlWrapperHeapAllocForbidden, RObject() };
return { error::StlWrapperHeapAllocForbidden, RObject{} };
}


template<>
inline std::pair<error, RObject> RObject::createCopy<alloc::Stack, detail::EntityKind::Wrapper>() const
inline Return RObject::createCopy<alloc::Stack, detail::EntityKind::Wrapper>() const
{
if (m_objectId.m_wrapperType == detail::Wrapper::None) {
return { error::NotWrapperType, RObject() };
return { error::NotWrapperType, RObject{} };
}
else if (m_objectId.m_wrapperType == detail::Wrapper::Unique)
{
return { error::TypeNotCopyConstructible, RObject() };
return { error::TypeNotCopyConstructible, RObject{} };
}
else {
return { error::None, RObject(*this) };
Expand All @@ -182,10 +198,10 @@ namespace rtl


template<alloc _allocOn, copy _copyTarget>
inline std::pair<error, RObject> RObject::clone() const
inline Return RObject::clone() const
{
if (isEmpty()) {
return { error::EmptyRObject, RObject() };
return { error::EmptyRObject, RObject{} };
}
if constexpr (_copyTarget == copy::Value) {
return createCopy<_allocOn, detail::EntityKind::Value>();
Expand Down
Loading
Loading