LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
NameSelector.cxx
Go to the documentation of this file.
1 
9 // our library
11 
12 // framework libraries
14 
15 #include <ostream>
16 
17 namespace testing {
18 
19  //----------------------------------------------------------------------------
20  //--- testing::NameSelector
21  //----------------------------------------------------------------------------
24 
25  //----------------------------------------------------------------------------
27  {
28  ProcessItem(known_names, name);
29  } // NameSelector::ParseName()
30 
31  //----------------------------------------------------------------------------
33  {
34  ++(query_registry[name]);
35  return LookupResponse(name);
36  } // NameSelector::Query()
37 
38  //----------------------------------------------------------------------------
39  bool NameSelector::Accepted(Name_t name) const
40  {
41  Response_t response = Query(name);
42  if (response == rsThrow) {
44  << "NameSelector: name '" << name << "' not configured.";
45  }
46  return response == rsAccepted;
47  } // NameSelector::Accepted()
48 
49  //----------------------------------------------------------------------------
50  void NameSelector::PrintConfiguration(std::ostream& out) const
51  {
52 
53  // resort the known elements
54  std::map<Response_t, Names_t> elements;
55  for (KnownNames_t::value_type const& element : known_names)
56  if (element.first != DefaultName) elements[element.second.response].insert(element.first);
57 
58  size_t nKnownElements = 0;
59  if (!elements[rsAccepted].empty()) {
60  auto const& selected_elements = elements[rsAccepted];
61  Names_t::const_iterator iName = selected_elements.cbegin(), nend = selected_elements.cend();
62  out << " accept " << selected_elements.size() << ": '" << *(iName++) << "'";
63  while (iName != nend)
64  out << ", '" << *(iName++) << "'";
65  out << ";";
66  nKnownElements += selected_elements.size();
67  } // if accepting anything
68  if (!elements[rsRejected].empty()) {
69  auto const& selected_elements = elements[rsRejected];
70  Names_t::const_iterator iName = selected_elements.cbegin(), nend = selected_elements.cend();
71  out << " reject " << selected_elements.size() << ": '" << *(iName++) << "'";
72  while (iName != nend)
73  out << ", '" << *(iName++) << "'";
74  out << ";";
75  nKnownElements += selected_elements.size();
76  } // if accepting anything
77  if (!elements[rsThrow].empty()) {
78  auto const& selected_elements = elements[rsThrow];
79  Names_t::const_iterator iName = selected_elements.cbegin(), nend = selected_elements.cend();
80  out << " throw on " << selected_elements.size() << ": '" << *(iName++) << "'";
81  while (iName != nend)
82  out << ", '" << *(iName++) << "'";
83  out << ";";
84  nKnownElements += selected_elements.size();
85  } // if accepting anything
86  if (nKnownElements > 0) out << " otherwise,";
87  switch (DefaultResponse()) {
88  case rsAccepted: out << " accept everything"; break;
89  case rsRejected: out << " reject everything"; break;
90  case rsThrow: out << " throw on anything"; break;
91  default: out << " I don't know";
92  } // switch
93  } // NameSelector::PrintConfiguration()
94 
95  //----------------------------------------------------------------------------
97  {
98  KnownNames_t::const_iterator iResponse = known_names.find(name);
99  return (iResponse == known_names.end()) ? DefaultResponse() : iResponse->second.response;
100  } // NameSelector::LookupResponse()
101 
102  //----------------------------------------------------------------------------
103  template <>
104  void NameSelector::AddFirstName<>(KnownNames_t& name_set, Name_t name)
105  {
106  ProcessItem(name_set, name);
107  } // NameSelector::AddFirstName<>()
108 
109  //----------------------------------------------------------------------------
110  void NameSelector::InsertItem(KnownNames_t& name_set, Name_t item, Response_t response) const
111  {
112  name_set[item] = {response};
113  } // NameSelector::InsertItem()
114 
115  //----------------------------------------------------------------------------
117  KnownNames_t::value_type item,
118  Response_t response) const
119  {
120  // response is the instruction we have about how to add the item
121  // item.second.response is what the default answer for that item is
122  Response_t final_response; // uninitialized
123  switch (response) {
124  case rsAccepted:
125  final_response = item.second.response; // respect the response
126  break;
127  case rsRejected: // flip the response
128  switch (item.second.response) {
129  case rsAccepted: final_response = rsRejected; break;
130  case rsRejected: final_response = rsAccepted; break;
131  default:
133  << __func__ << ": unexpected code flow: invalid added response";
134  } // switch item response
135  break;
136  default:
138  << __func__ << ": unexpected code flow: invalid response";
139  } // switch response
140  InsertItem(name_set, item.first, final_response);
141  } // NameSelector::InsertItem(KnownNames_t::value_type)
142 
143  //----------------------------------------------------------------------------
144  void NameSelector::ProcessItem(KnownNames_t& name_set, Name_t item) const
145  {
146  // special: if this name is actually a directive to clear all
147  if (item == ClearAllName) {
148  ClearNameSet(name_set); // clear everything except the default
149  return;
150  } // if clear all
151  Response_t response = ParseMode(item);
152  Definitions_t::const_iterator iDefinition = FindDefinition(item);
153  if (iDefinition == definitions.end())
154  InsertItem(name_set, item, response);
155  else {
156  for (KnownNames_t::value_type const& element : iDefinition->second)
157  InsertItem(name_set, element, response);
158  }
159  } // NameSelector::ProcessItem()
160 
161  //----------------------------------------------------------------------------
163  {
164  bool bForceDef = false;
165  if (!item.empty()) {
166  if (item[0] == '@') {
167  bForceDef = true;
168  item.erase(0, 1);
169  }
170  }
171  Definitions_t::const_iterator iDefinition = definitions.find(item);
172  if ((iDefinition == definitions.end()) && bForceDef) {
173  throw art::Exception(art::errors::LogicError) << "no set named '" << item << "'\n";
174  }
175  return iDefinition;
176  } // NameSelector::FindDefinition()
177 
178  //----------------------------------------------------------------------------
180  {
181  KnownNames_t::iterator iName = name_set.begin(), nend = name_set.end();
182  while (iName != nend) {
183  if (iName->first == DefaultName)
184  ++iName;
185  else
186  iName = name_set.erase(iName);
187  } // while
188  } // NameSelector::ClearNameSet()
189 
190  //----------------------------------------------------------------------------
192  {
193  NameSelector::Names_t names;
194  for (auto const& query_info : query_registry) {
195  if (query_info.first == DefaultName) continue;
196  if (LookupResponse(query_info.first) != answer) continue;
197  names.insert(query_info.first);
198  } // for
199  return names;
200  } // NameSelector::QueriedWithStatus()
201 
202  //----------------------------------------------------------------------------
203  bool NameSelector::DoCheckQueryRegistry(std::ostream* out /* = nullptr */) const
204  {
205  Names_t missing;
206  for (auto const& elem : known_names) {
207  if (query_registry[elem.first] > 0U) continue;
208  if (elem.first == DefaultName) continue;
209  missing.insert(elem.first);
210  } // for
211  if (out && !missing.empty()) {
212  (*out) << missing.size() << " items not queried:";
213  for (Name_t const& name : missing)
214  (*out) << " " << name;
215  (*out) << std::endl;
216  }
217  return missing.empty();
218  } // NameSelector::CheckQueryRegistry()
219 
220  //----------------------------------------------------------------------------
222  Response_t default_mode /* = rsAccepted */)
223  {
224  if (item[0] == '+') {
225  item.erase(0, 1);
226  return rsAccepted;
227  }
228  if (item[0] == '-') {
229  item.erase(0, 1);
230  return rsRejected;
231  }
232  return default_mode;
233  } // NameSelector::ParseMode()
234 
235  //----------------------------------------------------------------------------
236 
237 } // namespace testing
intermediate_table::iterator iterator
static Name_t const ClearAllName
name instructing to delete all names
Definition: NameSelector.h:173
LArSoft test utilities.
std::set< Name_t > Names_t
list of names
Definition: NameSelector.h:41
bool DoCheckQueryRegistry(std::ostream *out=nullptr) const
static Response_t ParseMode(Name_t &item, Response_t default_answer=rsAccepted)
Strips the mode specifier from item and returns the insertion mode.
Definitions_t::const_iterator FindDefinition(Name_t &item) const
Strips set specifier and returns iterator to the definition, or end()
std::map< Name_t, NameResponse_t > KnownNames_t
Information about known names.
Definition: NameSelector.h:182
Response_t DefaultResponse() const
Returns the default answer for names that are not registered.
Definition: NameSelector.h:149
bool Accepted(Name_t name) const
Returns whether the name is accepted as good.
intermediate_table::const_iterator const_iterator
void PrintConfiguration(std::ostream &) const
Prints the configuration into a stream.
Response_t LookupResponse(Name_t name) const
Returns the response for the specified name (does not register query)
void ParseName(Name_t name)
Parses a name and adds it to the selector.
A class providing a selection list.
Definitions_t definitions
a set of definitions
Definition: NameSelector.h:192
void ProcessItem(KnownNames_t &name_set, Name_t item) const
Fills name_set with an item.
Response_t
Possible responses.
Definition: NameSelector.h:44
KnownNames_t known_names
list of known names, with category
Definition: NameSelector.h:190
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static Name_t const DefaultName
name representing the default
Definition: NameSelector.h:172
Names_t QueriedWithStatus(Response_t answer) const
Returns the list of queried names whose response is answer.
void ClearNameSet(KnownNames_t &name_set) const
Erases all the names in the selector (default answer is unchanged)
QueryRegistry_t query_registry
record of all the queries
Definition: NameSelector.h:194
throw art::Exception (art::errors::Configuration)
Definition: NameSelector.h:47
void InsertItem(KnownNames_t &name_set, Name_t item, Response_t response) const
Adds an item to the name set, working in specified mode.
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109
std::string Name_t
type representing a name
Definition: NameSelector.h:40
Response_t Query(Name_t name) const
Returns the response for the specified name (does not throw)