2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
4 #include "CxxUtils/checker_macros.h"
5 #include "GaudiKernel/AlgTool.h"
6 #include "Gaudi/Sequence.h"
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,
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 ?
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 );
34 while ( !stack.empty() ) {
35 auto* a_tool = stack.back();
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 );
46 // @TODO warn about cicular tool dependencies ?
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());
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( );