From 440bfb38ed25db7ed9fdad7057e27ecc5ad5fa04 Mon Sep 17 00:00:00 2001 From: Rainer Kartmann <rainer.kartmann@kit.edu> Date: Thu, 5 Aug 2021 13:13:01 +0200 Subject: [PATCH] Add forEachChild(), rename functions to forEach{Snapshot, Instance} --- .../armem/core/base/CoreSegmentBase.h | 8 +-- .../libraries/armem/core/base/EntityBase.h | 12 ++--- .../armem/core/base/EntitySnapshotBase.h | 8 +-- .../libraries/armem/core/base/MemoryBase.h | 12 ++--- .../armem/core/base/ProviderSegmentBase.h | 8 +-- .../core/base/detail/MemoryContainerBase.h | 22 ++++++++ .../armem/core/base/detail/iteration_mixins.h | 54 ++++++++++++++----- .../armem/core/diskmemory/Entity.cpp | 2 +- .../armem/core/diskmemory/EntitySnapshot.cpp | 2 +- .../armem/core/longtermmemory/Entity.cpp | 2 +- .../core/longtermmemory/EntitySnapshot.cpp | 2 +- .../core/workingmemory/ice_conversions.cpp | 4 +- .../core/workingmemory/visitor/Visitor.cpp | 8 +-- .../armem/server/MemoryRemoteGui.cpp | 4 +- .../base/EntityQueryProcessorBase.h | 2 +- .../workingmemory/EntityQueryProcessor.cpp | 2 +- .../libraries/armem/test/ArMemForEachTest.cpp | 4 +- 17 files changed, 103 insertions(+), 53 deletions(-) diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h index 4ec1df3d1..feffe7c5f 100644 --- a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h +++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h @@ -151,7 +151,7 @@ namespace armarx::armem::base template <class ProviderSegmentFunctionT> bool forEachProviderSegment(ProviderSegmentFunctionT&& func) { - return base::detail::forEachChildPair(this->_container, func); + return this->forEachChild(func); } /** * @param func Function like: bool process(const ProviderSegmentT& provSeg) @@ -159,12 +159,12 @@ namespace armarx::armem::base template <class ProviderSegmentFunctionT> bool forEachProviderSegment(ProviderSegmentFunctionT&& func) const { - return base::detail::forEachChildPair(this->_container, func); + return this->forEachChild(func); } // forEachEntity() is provided by ForEachEntityMixin. - // forEachEntitySnapshot() is provided by ForEachEntitySnapshotMixin. - // forEachEntityInstance() is provided by ForEachEntityInstanceMixin. + // forEachSnapshot() is provided by ForEachEntitySnapshotMixin. + // forEachInstance() is provided by ForEachEntityInstanceMixin. [[deprecated("Direct container access is deprecated. Use forEach*() instead.")]] diff --git a/source/RobotAPI/libraries/armem/core/base/EntityBase.h b/source/RobotAPI/libraries/armem/core/base/EntityBase.h index 57dd4dad2..b480d09c0 100644 --- a/source/RobotAPI/libraries/armem/core/base/EntityBase.h +++ b/source/RobotAPI/libraries/armem/core/base/EntityBase.h @@ -283,19 +283,19 @@ namespace armarx::armem::base * @param func Function like: bool process(EntitySnapshotT& snapshot) */ template <class SnapshotFunctionT> - bool forEachEntitySnapshot(SnapshotFunctionT&& func) + bool forEachSnapshot(SnapshotFunctionT&& func) { - return base::detail::forEachChildPair(this->_container, func); + return this->forEachChild(func); } /** * @param func Function like void process(const EntitySnapshotT& snapshot) */ template <class SnapshotFunctionT> - bool forEachEntitySnapshot(SnapshotFunctionT&& func) const + bool forEachSnapshot(SnapshotFunctionT&& func) const { - return base::detail::forEachChildPair(this->_container, func); + return this->forEachChild(func); } - // forEachEntityInstance() is provided by ForEachEntityInstanceMixin. + // forEachInstance() is provided by ForEachEntityInstanceMixin. /** @@ -437,7 +437,7 @@ namespace armarx::armem::base { // ARMARX_INFO << "Entity: Merge name '" << m.name() << "' into '" << name() << "'"; - m.forEachEntitySnapshot([this](const EntitySnapshotT & snapshot) + m.forEachSnapshot([this](const EntitySnapshotT & snapshot) { auto it = this->_container.find(snapshot.time()); if (it == this->_container.end()) diff --git a/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h b/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h index 17c3eb576..288da3947 100644 --- a/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h +++ b/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h @@ -139,17 +139,17 @@ namespace armarx::armem::base * @param func Function like void process(EntityInstanceT& instance)> */ template <class InstanceFunctionT> - bool forEachEntityInstance(InstanceFunctionT&& func) + bool forEachInstance(InstanceFunctionT&& func) { - return base::detail::forEachChildSingle(this->_container, func); + return this->forEachChild(func); } /** * @param func Function like void process (const EntityInstanceT& instance) */ template <class InstanceFunctionT> - bool forEachEntityInstance(InstanceFunctionT&& func) const + bool forEachInstance(InstanceFunctionT&& func) const { - return base::detail::forEachChildSingle(this->_container, func); + return this->forEachChild(func); } [[deprecated("Direct container access is deprecated. Use forEach*() instead.")]] diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h index c5cf1fb2f..6b7b006cc 100644 --- a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h +++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h @@ -168,26 +168,26 @@ namespace armarx::armem::base // ITERATION /** - * @param func Function like: bool process(CoreSegmentT& provSeg) + * @param func Function like: bool process(CoreSegmentT& coreSeg) */ template <class CoreSegmentFunctionT> bool forEachCoreSegment(CoreSegmentFunctionT&& func) { - return base::detail::forEachChildPair(this->_container, func); + return this->forEachChild(func); } /** - * @param func Function like: bool process(const CoreSegmentT& provSeg) + * @param func Function like: bool process(const CoreSegmentT& coreSeg) */ template <class CoreSegmentFunctionT> bool forEachCoreSegment(CoreSegmentFunctionT&& func) const { - return base::detail::forEachChildPair(this->_container, func); + return this->forEachChild(func); } // forEachProviderSegment() is provided by ForEachProviderSegmentMixin. // forEachEntity() is provided by ForEachEntityMixin. - // forEachEntitySnapshot() is provided by ForEachEntitySnapshotMixin. - // forEachEntityInstance() is provided by ForEachEntityInstanceMixin. + // forEachSnapshot() is provided by ForEachEntitySnapshotMixin. + // forEachInstance() is provided by ForEachEntityInstanceMixin. [[deprecated("Direct container access is deprecated. Use forEach*() instead.")]] diff --git a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h index 41d25fb28..af94a5da1 100644 --- a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h +++ b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h @@ -143,7 +143,7 @@ namespace armarx::armem::base template <class EntityFunctionT> bool forEachEntity(EntityFunctionT&& func) { - return base::detail::forEachChildPair(this->_container, func); + return this->forEachChild(func); } /** * @param func Function like: bool process(const EntityT& entity) @@ -151,11 +151,11 @@ namespace armarx::armem::base template <class EntityFunctionT> bool forEachEntity(EntityFunctionT&& func) const { - return base::detail::forEachChildPair(this->_container, func); + return this->forEachChild(func); } - // forEachEntitySnapshot() is provided by ForEachEntitySnapshotMixin. - // forEachEntityInstance() is provided by ForEachEntityInstanceMixin. + // forEachSnapshot() is provided by ForEachEntitySnapshotMixin. + // forEachInstance() is provided by ForEachEntityInstanceMixin. [[deprecated("Direct container access is deprecated. Use forEach*() instead.")]] diff --git a/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.h b/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.h index 7565e15a7..9c5a03f34 100644 --- a/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.h +++ b/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.h @@ -3,6 +3,7 @@ #include <RobotAPI/libraries/armem/core/error/ArMemError.h> #include "MemoryItem.h" +#include "iteration_mixins.h" namespace armarx::armem::base::detail @@ -53,6 +54,27 @@ namespace armarx::armem::base::detail return _container.clear(); } + + // ITERATION + + /** + * @param func Function like: bool process(ChildT& provSeg) + */ + template <class ChildFunctionT> + bool forEachChild(ChildFunctionT&& func) + { + return base::detail::forEachChild(this->_container, func); + } + /** + * @param func Function like: bool process(const ChildT& provSeg) + */ + template <class ChildFunctionT> + bool forEachChild(ChildFunctionT&& func) const + { + return base::detail::forEachChild(this->_container, func); + } + + [[deprecated("Direct container access is deprecated. Use forEach*() instead.")]] typename ContainerT::const_iterator begin() const { 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 7436a737b..9a6f7e53b 100644 --- a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h +++ b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h @@ -1,11 +1,14 @@ #pragma once +#include <type_traits> + namespace armarx::armem::base::detail { // Helper functions to implement the forEach*() method at the current level. + // Single-valued containers. template <class ContainerT, class FunctionT> bool forEachChildSingle(ContainerT& container, FunctionT&& func) @@ -59,6 +62,31 @@ namespace armarx::armem::base::detail } + // see: https://en.cppreference.com/w/cpp/types/void_t + + // primary template handles types that have no nested ::type member: + template< class, class = void > + struct has_mapped_type : std::false_type { }; + + // specialization recognizes types that do have a nested ::type member: + template< class T > + struct has_mapped_type<T, std::void_t<typename T::mapped_type>> : std::true_type { }; + + + template <class ContainerT, class FunctionT> + bool forEachChild(ContainerT& container, FunctionT&& func) + { + if constexpr(has_mapped_type<ContainerT>::value) + { + return forEachChildPair(container, func); + } + else + { + return forEachChildSingle(container, func); + } + } + + // We use auto instead of, e.g. DerivedT::EntitySnapshotT, // as we cannot use the typedef before DerivedT was completely defined. @@ -71,12 +99,12 @@ namespace armarx::armem::base::detail * @param func Function like: bool process(EntityInstanceT& instance)> */ template <class InstanceFunctionT> - bool forEachEntityInstance(InstanceFunctionT&& func) + bool forEachInstance(InstanceFunctionT&& func) { - return static_cast<DerivedT*>(this)->forEachEntitySnapshot( + return static_cast<DerivedT*>(this)->forEachSnapshot( [&func](auto & snapshot) -> bool { - return snapshot.forEachEntityInstance(func); + return snapshot.forEachInstance(func); }); } @@ -84,12 +112,12 @@ namespace armarx::armem::base::detail * @param func Function like: bool process(const EntityInstanceT& instance) */ template <class InstanceFunctionT> - bool forEachEntityInstance(InstanceFunctionT&& func) const + bool forEachInstance(InstanceFunctionT&& func) const { - return static_cast<DerivedT*>(this)->forEachEntitySnapshot( + return static_cast<const DerivedT*>(this)->forEachSnapshot( [&func](const auto & snapshot) -> bool { - return snapshot.forEachEntityInstance(func); + return snapshot.forEachInstance(func); }); } }; @@ -102,12 +130,12 @@ namespace armarx::armem::base::detail * @param func Function like: bool process(EntitySnapshotT& snapshot)> */ template <class SnapshotFunctionT> - bool forEachEntitySnapshot(SnapshotFunctionT&& func) + bool forEachSnapshot(SnapshotFunctionT&& func) { return static_cast<DerivedT*>(this)->forEachEntity( [&func](auto & entity) -> bool { - return entity.forEachEntitySnapshot(func); + return entity.forEachSnapshot(func); }); } @@ -115,12 +143,12 @@ namespace armarx::armem::base::detail * @param func Function like: bool process(const EntitySnapshotT& snapshot) */ template <class SnapshotFunctionT> - bool forEachEntitySnapshot(SnapshotFunctionT&& func) const + bool forEachSnapshot(SnapshotFunctionT&& func) const { - return static_cast<DerivedT*>(this)->forEachEntity( + return static_cast<const DerivedT*>(this)->forEachEntity( [&func](const auto & entity) -> bool { - return entity.forEachEntitySnapshot(func); + return entity.forEachSnapshot(func); }); } }; @@ -148,7 +176,7 @@ namespace armarx::armem::base::detail template <class FunctionT> bool forEachEntity(FunctionT&& func) const { - return static_cast<DerivedT*>(this)->forEachProviderSegment( + return static_cast<const DerivedT*>(this)->forEachProviderSegment( [&func](const auto & providerSegment) -> bool { return providerSegment.forEachEntity(func); @@ -179,7 +207,7 @@ namespace armarx::armem::base::detail template <class FunctionT> bool forEachProviderSegment(FunctionT&& func) const { - return static_cast<DerivedT*>(this)->forEachCoreSegment( + return static_cast<const DerivedT*>(this)->forEachCoreSegment( [&func](const auto & coreSegment) -> bool { return coreSegment.forEachProviderSegment(func); diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp index c272ecc01..d4d0ac233 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp +++ b/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp @@ -66,7 +66,7 @@ namespace armarx::armem::d_ltm void Entity::append(const wm::Entity& m) { std::filesystem::create_directories(_fullPath()); - m.forEachEntitySnapshot([this](const wm::EntitySnapshot & s) + m.forEachSnapshot([this](const wm::EntitySnapshot & s) { if (auto it = _container.find(s.time()); it != _container.end()) { diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp index b6f0ff1e0..9354ab7d5 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp +++ b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp @@ -83,7 +83,7 @@ namespace armarx::armem::d_ltm _container.clear(); int i = 0; - m.forEachEntityInstance([this, &i](wm::EntityInstance & s) + m.forEachInstance([this, &i](wm::EntityInstance & s) { try { diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp index 62f8ad420..c8c4be11a 100644 --- a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp +++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp @@ -62,7 +62,7 @@ namespace armarx::armem::ltm mongocxx::database db = client[dbsettings.database]; mongocxx::collection coll = db[id().str()]; - m.forEachEntitySnapshot([this](const wm::EntitySnapshot & snapshot) + m.forEachSnapshot([this](const wm::EntitySnapshot & snapshot) { if (auto it = _container.find(snapshot.time()); it != _container.end()) { diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp index 313d6901d..1244abb46 100644 --- a/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp +++ b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp @@ -85,7 +85,7 @@ namespace armarx::armem::ltm auto array_builder = bsoncxx::builder::basic::array{}; int i = 0; - m.forEachEntityInstance([this, &array_builder, &i](const wm::EntityInstance & instance) + m.forEachInstance([this, &array_builder, &i](const wm::EntityInstance & instance) { auto wms = _container.emplace_back(id().withInstanceIndex(i++)); diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp index 4e429f170..3150feff1 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp +++ b/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp @@ -47,7 +47,7 @@ namespace armarx::armem detail::toIceItem(ice, snapshot); ice.instances.clear(); - snapshot.forEachEntityInstance([&ice](const wm::EntityInstance & instance) + snapshot.forEachInstance([&ice](const wm::EntityInstance & instance) { toIce(ice.instances.emplace_back(), instance); return true; @@ -69,7 +69,7 @@ namespace armarx::armem detail::toIceItem(ice, entity); ice.history.clear(); - entity.forEachEntitySnapshot([&ice](const wm::EntitySnapshot & snapshot) + entity.forEachSnapshot([&ice](const wm::EntitySnapshot & snapshot) { toIce(ice.history[toIce<long>(snapshot.time())], snapshot); return true; diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp index e9b42d775..125ca569d 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp +++ b/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp @@ -53,7 +53,7 @@ namespace armarx::armem::wm bool Visitor::applyTo(Entity& entity) { visitEnter(entity); - bool cont = entity.forEachEntitySnapshot([this](EntitySnapshot & snapshot) + bool cont = entity.forEachSnapshot([this](EntitySnapshot & snapshot) { return applyTo(snapshot); }); @@ -64,7 +64,7 @@ namespace armarx::armem::wm bool Visitor::applyTo(EntitySnapshot& snapshot) { visitEnter(snapshot); - bool cont = snapshot.forEachEntityInstance([this](EntityInstance & instance) + bool cont = snapshot.forEachInstance([this](EntityInstance & instance) { return applyTo(instance); }); @@ -114,7 +114,7 @@ namespace armarx::armem::wm bool Visitor::applyTo(const Entity& entity) { visitEnter(entity); - bool cont = entity.forEachEntitySnapshot([this](const EntitySnapshot & snapshot) + bool cont = entity.forEachSnapshot([this](const EntitySnapshot & snapshot) { return applyTo(snapshot); }); @@ -125,7 +125,7 @@ namespace armarx::armem::wm bool Visitor::applyTo(const EntitySnapshot& snapshot) { visitEnter(snapshot); - bool cont = snapshot.forEachEntityInstance([this](const EntityInstance & instance) + bool cont = snapshot.forEachInstance([this](const EntityInstance & instance) { return applyTo(instance); }); diff --git a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp index 55ab3391c..2207233b2 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp +++ b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp @@ -87,7 +87,7 @@ namespace armarx::armem::server if (int(entity.size()) <= maxHistorySize) { - entity.forEachEntitySnapshot(addChild); + entity.forEachSnapshot(addChild); } else { @@ -111,7 +111,7 @@ namespace armarx::armem::server { group.addChild(Label(makeNoItemsMessage("instances"))); } - snapshot.forEachEntityInstance([this, &group](const wm::EntityInstance & instance) + snapshot.forEachInstance([this, &group](const wm::EntityInstance & instance) { group.addChild(makeGroupBox(instance)); return true; diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h index 644ec0228..6713a3e69 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h @@ -78,7 +78,7 @@ namespace armarx::armem::base::query_proc (void) query; // Copy this entitiy and its contents. - entity.forEachEntitySnapshot([this, &result](const EntitySnapshotT & snapshot) + entity.forEachSnapshot([this, &result](const EntitySnapshotT & snapshot) { addResultSnapshot(result, snapshot); return true; diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp index 0c41d3a6f..a4945405e 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp +++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp @@ -23,7 +23,7 @@ namespace armarx::armem::wm::query_proc else { wm::EntitySnapshot copy = snapshot; - copy.forEachEntityInstance([](EntityInstance & i) + copy.forEachInstance([](EntityInstance & i) { i.setData(nullptr); return true; diff --git a/source/RobotAPI/libraries/armem/test/ArMemForEachTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemForEachTest.cpp index 013fae19b..8fc5e7099 100644 --- a/source/RobotAPI/libraries/armem/test/ArMemForEachTest.cpp +++ b/source/RobotAPI/libraries/armem/test/ArMemForEachTest.cpp @@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(test_forEach) BOOST_TEST_MESSAGE("Memory: \n" << memory.dump()); - memory.forEachEntityInstance([&](const wm::EntityInstance & i) -> bool + memory.forEachInstance([&](const wm::EntityInstance & i) -> bool { BOOST_TEST_CONTEXT(i.getLevelName() << " " << i.id()) { @@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(test_forEach) BOOST_CHECK_EQUAL(iids.size(), 0); } - memory.forEachEntitySnapshot([&](const wm::EntitySnapshot & s) -> bool + memory.forEachSnapshot([&](const wm::EntitySnapshot & s) -> bool { BOOST_TEST_CONTEXT(s.getLevelName() << " " << s.id()) { -- GitLab