Selector.h
Go to the documentation of this file.
1 #ifndef art_Framework_Principal_Selector_h
2 #define art_Framework_Principal_Selector_h
3 // vim: set sw=2 expandtab :
4 
5 // =====================================================================
6 // Classes for all "selector" objects, used to select EDProducts based
7 // on information in the associated Provenance.
8 //
9 // Users can use the classes defined below
10 //
11 // ModuleLabelSelector
12 // ProcessNameSelector
13 // ProductInstanceNameSelector
14 //
15 // Users can also use the class Selector, which can be constructed
16 // given a logical expression formed from any other selectors,
17 // combined with && (the AND operator), || (the OR operator) or ! (the
18 // NOT operator).
19 //
20 // For example, to select only products produced by a module with
21 // label "mymodule" and made in the process "PROD", one can use:
22 //
23 // Selector s{ModuleLabelSelector("mymodule") &&
24 // ProcessNameSelector("PROD")};
25 //
26 // If a module (EDProducter, EDFilter, EDAnalyzer, or OutputModule) is
27 // to use such a selector, it is best to initialize it directly upon
28 // construction of the module, rather than creating a new Selector
29 // instance for every event.
30 // =====================================================================
31 
34 
35 #include <memory>
36 #include <string>
37 #include <type_traits>
38 
39 namespace art {
40  template <typename T>
41  constexpr bool is_selector =
42  std::is_base_of_v<SelectorBase, std::remove_reference_t<T>>;
43 
44  //--------------------------------------------------------------------
45  // Class ProcessNameSelector.
46  // Selects EDProducts based upon process name.
47  //
48  // As a special case, a ProcessNameSelector created with the string
49  // "*" matches *any* process (and so is rather like having no
50  // ProcessNameSelector at all). The ProcessNameSelector does *not*
51  // understand the string "current_process" as a match to the current
52  // process name. To do so with the current design would require the
53  // use of accessing global data, which we would like to avoid. If
54  // such matching is desired in the future, a redesign of the selector
55  // system could be considered. For now, if users wish to retrieve
56  // products with the process name "current_process", they must use the
57  // getBy* facilities provided by Event and friends.
58  // -------------------------------------------------------------------
59 
61  public:
63  : pn_{pn.empty() ? std::string{"*"} : pn}
64  {}
65 
66  private:
67  bool
68  doMatch(BranchDescription const& p) const override
69  {
70  return (pn_ == "*") || (p.processName() == pn_);
71  }
72 
74  doPrint(std::string const& indent) const override
75  {
76  std::string result{indent + "Process name: "};
77  if (pn_ == "*") {
78  result += "(empty)";
79  } else {
80  result += "'" + pn_ + "'";
81  }
82  return result;
83  }
84 
86  };
87 
88  //------------------------------------------------------------------
89  // Class ProductInstanceNameSelector.
90  // Selects EDProducts based upon product instance name.
91  //------------------------------------------------------------------
92 
94  public:
95  explicit ProductInstanceNameSelector(std::string const& pin) : pin_{pin} {}
96 
97  private:
98  bool
99  doMatch(BranchDescription const& p) const override
100  {
101  return p.productInstanceName() == pin_;
102  }
103 
105  doPrint(std::string const& indent) const override
106  {
107  return indent + "Product instance name: '" + pin_ + '\'';
108  }
109 
111  };
112 
113  //------------------------------------------------------------------
114  // Class ModuleLabelSelector.
115  // Selects EDProducts based upon module label.
116  //------------------------------------------------------------------
117 
119  public:
120  explicit ModuleLabelSelector(std::string const& label) : label_{label} {}
121 
122  private:
123  bool
124  doMatch(BranchDescription const& p) const override
125  {
126  return p.moduleLabel() == label_;
127  }
128 
130  doPrint(std::string const& indent) const override
131  {
132  return indent + "Module label: '" + label_ + '\'';
133  }
134 
136  };
137 
138  //------------------------------------------------------------------
139  // Class MatchAllSelector.
140  // Dummy selector whose match function always returns true.
141  //------------------------------------------------------------------
142 
144  bool
145  doMatch(BranchDescription const&) const override
146  {
147  return true;
148  }
149 
151  doPrint(std::string const&) const override
152  {
153  return {};
154  }
155  };
156 
157  //----------------------------------------------------------
158  // AndHelper template.
159  // Used to form expressions involving && between other selectors.
160  //----------------------------------------------------------
161 
162  template <typename A, typename B>
163  class AndHelper : public SelectorBase {
164  public:
165  AndHelper(A const& a, B const& b) : a_{a}, b_{b} {}
166 
167  private:
168  bool
169  doMatch(BranchDescription const& p) const override
170  {
171  return a_.match(p) && b_.match(p);
172  }
173 
175  doPrint(std::string const& indent) const override
176  {
177  return a_.print(indent) + '\n' + b_.print(indent);
178  }
179 
180  A a_;
181  B b_;
182  };
183 
184  template <typename A, typename B>
185  std::enable_if_t<is_selector<A> && is_selector<B>, AndHelper<A, B>>
186  operator&&(A const& a, B const& b)
187  {
188  return AndHelper<A, B>{a, b};
189  }
190 
191  //----------------------------------------------------------
192  // OrHelper template.
193  // Used to form expressions involving || between other selectors.
194  //----------------------------------------------------------
195 
196  template <typename A, typename B>
197  class OrHelper : public SelectorBase {
198  public:
199  OrHelper(A const& a, B const& b) : a_{a}, b_{b} {}
200 
201  private:
202  bool
203  doMatch(BranchDescription const& p) const override
204  {
205  return a_.match(p) || b_.match(p);
206  }
207 
209  doPrint(std::string const& indent) const override
210  {
211  std::string result{indent + "[\n"};
212  result += indent + a_.print(indent) + '\n';
213  result += indent + indent + indent + "or\n";
214  result += indent + b_.print(indent) + '\n';
215  result += indent + ']';
216  return result;
217  }
218 
219  A a_;
220  B b_;
221  };
222 
223  template <typename A, typename B>
224  std::enable_if_t<is_selector<A> && is_selector<B>, OrHelper<A, B>>
225  operator||(A const& a, B const& b)
226  {
227  return OrHelper<A, B>{a, b};
228  }
229 
230  //----------------------------------------------------------
231  // NotHelper template.
232  // Used to form expressions involving ! acting on a selector.
233  //----------------------------------------------------------
234 
235  template <typename A>
236  class NotHelper : public SelectorBase {
237  public:
238  explicit NotHelper(A const& a) : a_{a} {}
239 
240  private:
241  bool
242  doMatch(BranchDescription const& p) const override
243  {
244  return !a_.match(p);
245  }
246 
248  doPrint(std::string const& indent) const override
249  {
250  std::string result{indent + "Not [\n"};
251  result += indent + a_.print(indent) + '\n';
252  result += indent + ']';
253  return result;
254  }
255  A a_;
256  };
257 
258  template <typename A>
259  std::enable_if_t<is_selector<A>, NotHelper<A>> operator!(A const& a)
260  {
261  return NotHelper<A>{a};
262  }
263 
264  //----------------------------------------------------------
265  // ComposedSelectorWrapper template
266  // Used to hold an expression formed from the various helpers.
267  //----------------------------------------------------------
268 
269  template <typename T>
270  class ComposedSelectorWrapper : public SelectorBase {
271  public:
272  using wrapped_type = T;
273  explicit ComposedSelectorWrapper(T const& t) : expression_{t} {}
274 
275  private:
276  bool
277  doMatch(BranchDescription const& p) const override
278  {
279  return expression_.match(p);
280  }
281 
283  doPrint(std::string const& indent) const override
284  {
285  return expression_.print(indent);
286  }
287 
289  };
290 
291  //----------------------------------------------------------
292  // Selector
293  //----------------------------------------------------------
294 
295  class Selector : public SelectorBase {
296  public:
297  template <typename T>
298  explicit Selector(T const& expression)
299  : sel_{new ComposedSelectorWrapper<T>{expression}}
300  {}
301 
302  private:
303  bool doMatch(BranchDescription const& p) const override;
304  std::string doPrint(std::string const& indent) const override;
305 
306  std::shared_ptr<SelectorBase> sel_;
307  };
308 
309 } // namespace art
310 
311 #endif /* art_Framework_Principal_Selector_h */
312 
313 // Local Variables:
314 // mode: c++
315 // End:
static QCString result
constexpr bool is_selector
Definition: Selector.h:41
AndHelper(A const &a, B const &b)
Definition: Selector.h:165
std::shared_ptr< SelectorBase > sel_
Definition: Selector.h:306
Selector(T const &expression)
Definition: Selector.h:298
std::string string
Definition: nybbler.cc:12
bool doMatch(BranchDescription const &p) const override
Definition: Selector.h:242
ProductInstanceNameSelector(std::string const &pin)
Definition: Selector.h:95
std::enable_if_t< is_selector< A >, NotHelper< A > > operator!(A const &a)
Definition: Selector.h:259
std::string doPrint(std::string const &) const override
Definition: Selector.h:151
bool doMatch(BranchDescription const &p) const override
Definition: Selector.h:169
bool doMatch(BranchDescription const &p) const override
Definition: Selector.h:203
std::string const & processName() const noexcept
std::string doPrint(std::string const &indent) const override
Definition: Selector.h:283
std::enable_if_t< is_selector< A > &&is_selector< B >, AndHelper< A, B > > operator&&(A const &a, B const &b)
Definition: Selector.h:186
bool doMatch(BranchDescription const &p) const override
Definition: Selector.h:68
std::string doPrint(std::string const &indent) const override
Definition: Selector.h:74
const double a
bool doMatch(BranchDescription const &) const override
Definition: Selector.h:145
bool doMatch(BranchDescription const &p) const override
Definition: Selector.h:124
p
Definition: test.py:223
std::string doPrint(std::string const &indent) const override
Definition: Selector.h:105
bool doMatch(BranchDescription const &p) const override
Definition: Selector.h:277
ModuleLabelSelector(std::string const &label)
Definition: Selector.h:120
std::string doPrint(std::string const &indent) const override
Definition: Selector.h:175
std::string doPrint(std::string const &indent) const override
Definition: Selector.h:209
std::string const & moduleLabel() const noexcept
OrHelper(A const &a, B const &b)
Definition: Selector.h:199
bool doMatch(BranchDescription const &p) const override
Definition: Selector.h:99
ComposedSelectorWrapper(T const &t)
Definition: Selector.h:273
std::string const & productInstanceName() const noexcept
ProcessNameSelector(std::string const &pn)
Definition: Selector.h:62
std::string doPrint(std::string const &indent) const override
Definition: Selector.h:248
static bool * b
Definition: config.cpp:1043
NotHelper(A const &a)
Definition: Selector.h:238
std::enable_if_t< is_selector< A > &&is_selector< B >, OrHelper< A, B > > operator||(A const &a, B const &b)
Definition: Selector.h:225
std::string doPrint(std::string const &indent) const override
Definition: Selector.h:130