12 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
13 #include <tracking/trackFindingCDC/utilities/Functional.h>
14 #include <framework/logging/Logger.h>
19 #include <type_traits>
29 namespace TrackFindingCDC {
36 template<
class AProperties,
class ASubPropertiesFactory>
40 using This = DynTree<AProperties, ASubPropertiesFactory>;
50 class Node :
public AProperties {
70 using AProperties::AProperties;
73 using AProperties::operator=;
94 B2ASSERT(
"DynTree datastructure only supports levels < 255",
getLevel() < 255);
97 Node* parentNode =
this;
102 child.m_parent =
this;
121 template<
class AWalker>
122 void walk(AWalker& walker)
124 static_assert(std::is_assignable<std::function<
bool(
Node*)>, AWalker>(),
"");
126 bool walkChildren = walker(
this);
128 if (children and walkChildren) {
129 for (
Node& childNode : *children) {
130 childNode.walk(walker);
140 template<
class AWalker,
class APriorityMeasure>
141 void walk(AWalker& walker, APriorityMeasure& priority)
143 static_assert(std::is_assignable<std::function<
bool(Node*)>, AWalker>(),
"");
144 static_assert(std::is_assignable<std::function<
float(Node*)>, APriorityMeasure>(),
"");
146 bool walkChildren = walker(
this);
148 if (children and walkChildren) {
149 std::vector<std::pair<float, Node*> > prioritisedChildNodes;
150 size_t nChildren = children->size();
152 prioritisedChildNodes.reserve(nChildren);
154 for (
Node& childNode : *children) {
155 float childPriority = priority(&childNode);
156 if (std::isnan(childPriority))
continue;
157 prioritisedChildNodes.push_back(std::make_pair(childPriority, &childNode));
160 std::make_heap(prioritisedChildNodes.begin(), prioritisedChildNodes.end());
162 while (not prioritisedChildNodes.empty()) {
163 std::pop_heap(prioritisedChildNodes.begin(), prioritisedChildNodes.end());
164 Node* priorityChildNode = prioritisedChildNodes.back().second;
165 prioritisedChildNodes.pop_back();
167 priorityChildNode->walk(walker, priority);
171 erase_remove_if(prioritisedChildNodes,
172 [&reheap, &priority](std::pair<float, Node*>& prioritisedChildNode) {
173 float childPriority = priority(prioritisedChildNode.second);
174 if (std::isnan(childPriority))
return true;
176 reheap |= prioritisedChildNode.first != childPriority;
177 prioritisedChildNode.first = childPriority;
182 std::make_heap(prioritisedChildNodes.begin(), prioritisedChildNodes.end());
185 assert(prioritisedChildNodes.empty());
253 auto countNodes = [&nNodes](
const Node*) ->
bool {
268 std::map<int, int> nNodesByLevel;
269 auto countNodes = [&nNodesByLevel](
const Node * node) ->
bool {
270 if (nNodesByLevel.count(node->getLevel()) == 0)
272 nNodesByLevel[node->getLevel()] = 1;
274 nNodesByLevel[node->getLevel()]++;
278 const_cast<DynTree&
>(*this).walk(countNodes);
280 return nNodesByLevel;
289 if (subProperties.empty()) {
293 result->resize(subProperties.size(), Node(subProperties.back()));
295 for (
auto& properties : subProperties) {
296 clearIfApplicable(result->at(iSubNode));
297 result->at(iSubNode) = properties;
316 template<
class AWalker>
317 void walk(AWalker& walker)
319 static_assert(std::is_assignable<std::function<
bool(Node*)>, AWalker>(),
"");
325 template<
class AWalker,
class APriorityMeasure>
326 void walk(AWalker& walker, APriorityMeasure& priority)
328 static_assert(std::is_assignable<std::function<
bool(Node*)>, AWalker>(),
"");
329 static_assert(std::is_assignable<std::function<
float(Node*)>, APriorityMeasure>(),
"");
341 for (Node& node : children) {
342 clearIfApplicable(node);
365 std::deque<typename Node::Children>
m_children;