LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ProducesCollector.cc
Go to the documentation of this file.
4 
5 #include "range/v3/view/map.hpp"
6 
7 #include <map>
8 #include <set>
9 #include <string>
10 
11 using namespace std;
12 
13 namespace art {
14 
15  namespace {
16 
17  // A user may attempt to declare:
18  //
19  // produces<Assns<A,B>>(instance_name);
20  // produces<Assns<B,A>>(instance_name);
21  //
22  // in their module constructor. If the instance names are the same
23  // for both produces declarations, then this is a logic error, since
24  // Assns<A,B> and Assns<B,A> correspond to the same set of
25  // associations. This error can be detected by checking the
26  // friendlyClassName, which resolves to the same string for
27  // Assns<A,B> and Assns<B,A>.
28  void
29  check_for_duplicate_friendly_names(TypeLabelLookup_t const& typeLabels)
30  {
31  using ::ranges::views::keys;
32  map<string, set<string>> instanceToFriendlyNames;
33  for (auto const& type_label : typeLabels | keys) {
34  auto unique_entry = type_label.productInstanceName();
35  if (type_label.hasEmulatedModule()) {
36  // Whenever 'produces' is called, the module label is always
37  // the same for a given ProducesCollector object. However,
38  // for 'reconstitutes', the user provides a module label,
39  // and it is therefore necessary for this check to allow
40  // different module labels with the same type and instance
41  // name.
42  unique_entry += "_" + type_label.emulatedModule();
43  }
44  auto result = instanceToFriendlyNames[unique_entry].emplace(
45  type_label.typeID().friendlyClassName());
46  if (!result.second) {
48  "check_for_duplicate_friendly_names: ")
49  << "An attempt has been made to call the equivalent of\n\n"
50  << " produces<" << type_label.typeID().className() << ">(\""
51  << type_label.productInstanceName() << "\")\n\n"
52  << "which results in a prepared (\"friendly\") name of:\n\n"
53  << " " << *result.first << "\n\n"
54  << "That friendly name has already been registered for this "
55  "module.\n"
56  << "Please check to make sure that produces<> has not already "
57  "been\n"
58  << "called for an Assns<> with reversed template arguments. "
59  "Such\n"
60  << "behavior is not supported. Contact artists@fnal.gov for "
61  "guidance.\n";
62  }
63  }
64  }
65 
66  } // unnamed namespace
67 
68  TypeLabel const&
69  ProducesCollector::insertOrThrow(BranchType const bt, TypeLabel const& tl)
70  {
71  auto result = typeLabelList_[bt].emplace(tl, BranchDescription{});
72  if (!result.second) {
73  ostringstream oss;
74  oss << "An attempt was made to declare the following product in the same "
75  "module:\n"
76  << "Branch type: " << bt << '\n'
77  << "Class name: " << tl.className() << '\n'
78  << "Product instance name: " << tl.productInstanceName() << '\n';
79  throw Exception{
81  "An error occurred during a call to 'produces' or 'reconstitutes'."}
82  << oss.str();
83  }
84  return result.first->first;
85  }
86 
87  void
88  ProducesCollector::fillDescriptions(ModuleDescription const& md)
89  {
90  auto fillDescriptionsPerBT = [this, &md](BranchType const bt) {
91  auto& expectedProducts = typeLabelList_[bt];
92  // Go through products that will be produced in the current process.
93  check_for_duplicate_friendly_names(expectedProducts);
94 
95  for (auto& [typeLabel, pd] : expectedProducts) {
96  pd = BranchDescription{bt,
97  typeLabel,
98  md.moduleLabel(),
99  md.parameterSetID(),
100  md.processConfiguration()};
101  }
102  };
103  for_each_branch_type(fillDescriptionsPerBT);
104  }
105 
106 }
std::string const & productInstanceName() const
Definition: TypeLabel.h:52
std::string const & moduleLabel() const
STL namespace.
std::map< TypeLabel, BranchDescription > TypeLabelLookup_t
Definition: type_aliases.h:20
ProcessConfiguration const & processConfiguration() const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
fhicl::ParameterSetID const & parameterSetID() const
BranchType
Definition: BranchType.h:20
Definition: MVAAlg.h:12
void for_each_branch_type(F f)
Definition: BranchType.h:38
std::string className() const
Definition: TypeLabel.h:41