From 517c446cd95d1f57a8d7748380987c3dd0d7583f Mon Sep 17 00:00:00 2001 From: Rainer Kartmann <rainer.kartmann@kit.edu> Date: Fri, 17 Dec 2021 16:11:51 +0100 Subject: [PATCH] Add instance.dataAs<AronDtoT>() and forEachInstanceAs(const AronDtoT& fn) --- .../armem/core/base/EntityInstanceBase.h | 9 ++++ .../armem/core/base/detail/iteration_mixins.h | 46 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h index 8f7b8aafc..0b877909c 100644 --- a/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h +++ b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h @@ -104,6 +104,15 @@ namespace armarx::armem::base return _data; } + /** + * @brief Get the data converted to a generated Aron DTO class. + */ + template <class AronDtoT> + AronDtoT dataAs() const + { + return AronDtoT::FromAron(_data); + } + // Misc diff --git a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h index c923a857e..876d0d6d7 100644 --- a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h +++ b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h @@ -1,7 +1,27 @@ #pragma once +#include <functional> #include <type_traits> +namespace +{ + template<typename F, typename Ret, typename A, typename... Rest> + A helper(Ret (F::*)(A, Rest...)); + + template<typename F, typename Ret, typename A, typename... Rest> + A helper(Ret (F::*)(A, Rest...) const); + + // volatile or lvalue/rvalue *this not required for lambdas (phew) + + template <typename FuncT> + struct first_argument + { + using type = decltype( helper(&FuncT::operator()) ); + }; + + template <typename FuncT> + using first_argument_t = typename first_argument<FuncT>::type; +} namespace armarx::armem::base::detail { @@ -116,6 +136,32 @@ namespace armarx::armem::base::detail return snapshot.forEachInstance(func); }); } + + /** + * Call `func` on the data of each instances converted to Aron DTO class. + * + * @code + * ().forEachEntityInstanceAs([](const my::arondto::CoolData& data) + * { + * ... + * }); + * @endcode + * + * The Aron DTO type is deduced from the passed function's first argument. + * + * @param func Function like: `bool process(const my::arondto::CoolData& data)` + */ + template <class AronDtoFunctionT> + bool forEachInstanceAs(AronDtoFunctionT&& func) const + { + return static_cast<const DerivedT*>(this)->forEachInstance( + [&func](const auto & instance) -> bool + { + using AronDtoT = typename std::remove_reference_t<first_argument_t<AronDtoFunctionT>>; + return func(instance.template dataAs<AronDtoT>()); + }); + } + }; -- GitLab