ATLAS Offline Software
Loading...
Searching...
No Matches
GaudiComponentVisitor.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4#include "CxxUtils/checker_macros.h"
5#include "GaudiKernel/AlgTool.h"
6#include "Gaudi/Sequence.h"
7
8namespace xGaudi {
9
10 namespace {
11 template <class T_Component>
12 void reverseAppend( const std::vector<T_Component*>& src,
13 std::vector<T_Component*>& dest,
14 const std::regex& reject_filter,
15 bool use_filter ) {
16 dest.reserve( dest.size() + src.size() );
17 std::copy_if( src.rbegin(), src.rend(), std::back_inserter( dest ), [&]( const auto& i ) {
18 return !use_filter || !std::regex_match( i->name(), reject_filter );
19 } ); // @TODO include type ?
20 }
21 } // namespace
22
23 template <class T_Component, class T_TestVisited>
24 void ComponentVisitor<T_Component,T_TestVisited>::recursiveVisit( const std::vector<T_Component*>& components,
25 ComponentVisitor<T_Component, T_TestVisited>::IVisitor const& visitor,
26 const std::regex& reject_filter,
27 T_TestVisited &visited) {
28 bool use_filter = ( &reject_filter != &ComponentVisitorBase::s_noFilter ) &&
29 ( !std::regex_match( "", reject_filter ) ); // @TODO remove empty string match-test ?
30 std::vector<T_Component*> stack;
31 // reverse tool lost to process tools in given order
32 reverseAppend( components, stack, reject_filter, use_filter );
33
34 while ( !stack.empty() ) {
35 auto* a_tool = stack.back();
36 stack.pop_back();
37 if ( a_tool ) {
38 // keep track of tools which have been visited to prevent infinite loops in case of circular tool dependencies.
39 if ( visited.insert( a_tool ).second ) {
40 visitor.visit( a_tool );
41 // also visit all child tools
42 if (const std::vector<T_Component *> *childs( getChilds(a_tool)); childs ) {
43 reverseAppend( *childs, stack, reject_filter, use_filter );
44 }
45 }
46 // @TODO warn about cicular tool dependencies ?
47 }
48 }
49 }
50
51 template <>
52 inline std::vector<IAlgTool *> *ComponentVisitor<IAlgTool>::getChilds(IAlgTool *a_tool) {
53 if ( auto* tool_impl = dynamic_cast<AlgTool*>( a_tool ); tool_impl ) {
54 std::vector<IAlgTool *> &tools ATLAS_THREAD_SAFE = const_cast< std::vector<IAlgTool *> &>(const_cast<const AlgTool *>(tool_impl)->tools());
55 return &tools;
56 }
57 else {
58 return nullptr;
59 }
60 }
61
62 template <>
63 inline std::vector<Gaudi::Algorithm *> *ComponentVisitor<Gaudi::Algorithm, NoVisitTester>::getChilds(Gaudi::Algorithm *an_alg) {
64 if (Gaudi::Sequence *seq=dynamic_cast<Gaudi::Sequence *>(an_alg); seq) {
65 return seq->subAlgorithms( );
66 }
67 else {
68 return nullptr;
69 }
70 }
71}