diff --git a/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h index 8f7b8aafc4cebd74c241bfb1245388a943897e01..0b877909c4a35e5b867d21de7840b1625b5e74dc 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 c923a857e1d016b06b313f7e860ab57ec438a9d4..876d0d6d73bed644d3b8316c5479f0c15b39b97f 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>()); + }); + } + };