createProductLookups.cc
Go to the documentation of this file.
2 // vim: set sw=2:
3 
7 
8 #include <algorithm>
9 #include <string>
10 #include <unordered_map>
11 
12 using namespace art;
13 
14 namespace {
15 
16  struct CheapTag {
20  };
21 
22  inline bool
23  operator==(CheapTag const& left, CheapTag const& right)
24  {
25  return left.label == right.label && left.instance == right.instance &&
26  left.process == right.process;
27  }
28 
29  class PendingBTLEntry {
30  public:
31  PendingBTLEntry(std::string const& fcn,
32  std::string const& moduleLabel,
33  std::string const& instanceName,
34  std::string const& procName,
35  ProductID const pid)
36  : fcn_{fcn}, ct_{moduleLabel, instanceName, procName}, pid_{pid}
37  {}
38 
39  std::string const&
40  fcn() const noexcept
41  {
42  return fcn_;
43  }
44  CheapTag const&
45  ct() const noexcept
46  {
47  return ct_;
48  }
49  std::string const&
50  process() const noexcept
51  {
52  return ct_.process;
53  }
54  ProductID
55  pid() const
56  {
57  return pid_;
58  }
59 
60  private:
61  std::string fcn_;
62  CheapTag ct_;
63  ProductID pid_;
64  };
65 }
66 
69 {
70  // Computing the product lookups does not rely on any ROOT facilities.
72  std::vector<PendingBTLEntry> pendingEntries;
73  std::unordered_map<ProductID, CheapTag, ProductID::Hash> insertedABVs;
74  for (auto const& pr : descriptions) {
75  auto const pid = pr.first;
76  auto const& pd = pr.second;
77  auto const& prodFCN = pd.friendlyClassName();
78  auto const& procName = pd.processName();
79  result[prodFCN][procName].emplace_back(pid);
80 
81  // Additional work only for Assns lookup
82  auto const& moduleLabel = pd.moduleLabel();
83  auto const& instanceName = pd.productInstanceName();
84  auto const& className = pd.producedClassName();
85 
86  if (!is_assns(className))
87  continue;
88 
90  if (!baseName.empty()) {
91  // We're an Assns<A, B, D>, with a base Assns<A, B>.
92  pendingEntries.emplace_back(art::friendlyname::friendlyName(baseName),
93  moduleLabel,
94  instanceName,
95  procName,
96  pid);
97  } else {
98  // Add our pid to the list of real Assns<A, B, void>
99  // products already registered.
100  insertedABVs.emplace(pid, CheapTag{moduleLabel, instanceName, procName});
101  }
102  }
103 
104  auto const iend = insertedABVs.cend();
105  // Preserve useful ordering, only inserting if we don't already have
106  // a *real* Assns<A, B, void> for that module label / instance name
107  // combination.
108  std::for_each(
109  pendingEntries.cbegin(),
110  pendingEntries.cend(),
111  [&result, &insertedABVs, iend](auto const& pe) {
112  auto& pids = result[pe.fcn()][pe.process()];
113  if (pids.empty() ||
114  !std::any_of(pids.cbegin(),
115  pids.cend(),
116  [&insertedABVs, &iend, &pe](ProductID const pid) {
117  auto i = insertedABVs.find(pid);
118  return i != iend && pe.ct() == i->second;
119  })) {
120  pids.emplace_back(pe.pid());
121  }
122  });
123 
124  return result;
125 }
bool operator==(Provenance const &a, Provenance const &b) noexcept
Definition: Provenance.cc:141
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
static QCString result
std::string string
Definition: nybbler.cc:12
const std::string instance
static QCString className
Definition: declinfo.cpp:669
def process(f, kind)
Definition: search.py:254
string name_of_assns_base(string assns_type_name)
Definition: TypeID.cc:185
ProductLookup_t createProductLookups(ProductDescriptionsByID const &descriptions)
std::string friendlyName(std::string const &iFullName)
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
std::map< ProductID, BranchDescription > ProductDescriptionsByID
static QCString baseName
Definition: scanner.cpp:10890
std::map< std::string, ProcessLookup > ProductLookup_t
Definition: type_aliases.h:23
bool is_assns(std::string const &type_name)
Definition: TypeID.h:66