Consumer.h
Go to the documentation of this file.
1 #ifndef art_Framework_Principal_Consumer_h
2 #define art_Framework_Principal_Consumer_h
3 
4 //============================================================================
5 // Consumer is the base class for all module types that retrieve
6 // products. See below for guidance as to which interface should be
7 // called for a given context.
8 //
9 // N.B. All 'consumes*' or 'mayConsume*' calls should be done in a
10 // module's constructor, before processing any beginJob
11 // callbacks.
12 //
13 // Unconditional retrieval of products
14 // -----------------------------------
15 //
16 // For products that are always intended to be retrieved for a given
17 // module execution, the 'consumes' family of calls should be invoked
18 // in a user's module constructor (e.g.):
19 //
20 // consumes<int>(input_tag); // => ProductToken<int>
21 // consumesMany<int>(); // => void
22 // consumesView<int>(input_tag); // => ViewToken<int>
23 //
24 // Making such calls tells the framework that the particular module in
25 // question will make the following product retrievals (e.g.):
26 //
27 // e.getValidHandle<int>(input_tag);
28 // e.getManyByType<int>();
29 // art::View<int> v;
30 // e.getView(input_tag, v);
31 //
32 // The returned type of the consumes calls are shown above. To
33 // eventually facilitate faster product lookup, the returned tokens
34 // can be supplied by the user (e.g.):
35 //
36 // ProductToken<int> intToken_; // data member of module class
37 // e.getValidHandle(intToken_); // => ValidHandle<int>
38 //
39 // ViewToken<int> viewToken_; // data member of module class
40 // std::vector<int const*> v;
41 // e.getView(viewToken_, v);
42 //
43 // The consumesMany function template does not return a token.
44 //
45 // Conditional retrieval of products
46 // ---------------------------------
47 //
48 // If there are situations in which a product *may* be retrieved
49 // (e.g. within an 'if' block), then the *mayConsume* interface should
50 // be considered instead of the consumes interface:
51 //
52 // mayConsume<int>(input_tag); // => ProductToken<int>
53 // mayConsumeMany<int>(); // => void
54 // mayConsumeView<int>(); // => ViewToken<int>
55 //
56 // The return types of the functions are the same as their 'consumes'
57 // partners for unconditional product retrieving. However, how the
58 // tokens are used by the framework may be different than how they are
59 // used in the 'consumes' case.
60 
61 // Retrieving products in non-module contexts
62 // ------------------------------------------
63 //
64 // There are cases where products are retrieved in non-module
65 // contexts. Although such product retrieval is not forbidden, it is
66 // not a generally recommended usage pattern. The 'consumes'
67 // interface is, therefore, not supported in non-module contexts.
68 //============================================================================
69 
76 #include "cetlib/exempt_ptr.h"
77 
78 namespace fhicl {
79  class ParameterSet;
80 }
81 
82 namespace art {
83 
84  class DataViewImpl;
85  class ModuleDescription;
86 
87  class Consumer {
88  struct InvalidTag {};
89 
90  public:
91  explicit Consumer() = default;
92 
93  static cet::exempt_ptr<Consumer> non_module_context();
94 
95  template <typename T, BranchType = InEvent>
96  ProductToken<T> consumes(InputTag const&);
97 
98  template <typename T, BranchType = InEvent>
99  void consumesMany();
100 
101  template <typename Element, BranchType = InEvent>
102  ViewToken<Element> consumesView(InputTag const&);
103 
104  // mayConsume variants, which should be used whenever product
105  // retrievals do not always occur whenever the user is presented
106  // with a transactional object.
107  template <typename T, BranchType = InEvent>
108  ProductToken<T> mayConsume(InputTag const&);
109 
110  template <typename T, BranchType = InEvent>
111  void mayConsumeMany();
112 
113  template <typename Element, BranchType = InEvent>
114  ViewToken<Element> mayConsumeView(InputTag const&);
115 
116  protected:
117  friend class DataViewImpl;
118  void validateConsumedProduct(BranchType const bt, ProductInfo const& pi);
119 
120  // After the modules are constructed, their ModuleDescription
121  // values are assigned. We receive the values of that assignment.
122  void setModuleDescription(ModuleDescription const& md);
123 
124  // Once all of the 'consumes(Many)' calls have been made for this
125  // recorder, the consumables are sorted, and the configuration is
126  // retrieved to specify the desired behavior in the case of a
127  // missing consumes clause.
128  void prepareForJob(fhicl::ParameterSet const& pset);
129  void showMissingConsumes() const;
130 
131  private:
133  explicit Consumer(InvalidTag) : moduleContext_{false} {}
134 
135  bool moduleContext_{true};
136  bool requireConsumes_{false};
137  ConsumableProducts consumables_{};
138  ConsumableProductSets missingConsumes_{};
139  cet::exempt_ptr<ModuleDescription const> moduleDescription_{nullptr};
140  };
141 }
142 
143 //===========================================================================
144 template <typename T, art::BranchType BT>
147 {
148  if (!moduleContext_)
149  return ProductToken<T>::invalid();
150 
151  consumables_[BT].emplace_back(ConsumableType::Product,
152  TypeID{typeid(T)},
153  it.label(),
154  it.instance(),
155  it.process());
156  return ProductToken<T>{it};
157 }
158 
159 template <typename T, art::BranchType BT>
160 void
162 {
163  if (!moduleContext_)
164  return;
165 
166  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
167 }
168 
169 template <typename T, art::BranchType BT>
172 {
173  if (!moduleContext_)
174  return ViewToken<T>::invalid();
175 
176  consumables_[BT].emplace_back(ConsumableType::ViewElement,
177  TypeID{typeid(T)},
178  it.label(),
179  it.instance(),
180  it.process());
181  return ViewToken<T>{it};
182 }
183 
184 //=======================================================================
185 // mayConsume variants
186 
187 template <typename T, art::BranchType BT>
190 {
191  if (!moduleContext_)
192  return ProductToken<T>::invalid();
193 
194  consumables_[BT].emplace_back(ConsumableType::Product,
195  TypeID{typeid(T)},
196  it.label(),
197  it.instance(),
198  it.process());
199  return ProductToken<T>{it};
200 }
201 
202 template <typename T, art::BranchType BT>
203 void
205 {
206  if (!moduleContext_)
207  return;
208 
209  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
210 }
211 
212 template <typename T, art::BranchType BT>
215 {
216  if (!moduleContext_)
217  return ViewToken<T>::invalid();
218 
219  consumables_[BT].emplace_back(ConsumableType::ViewElement,
220  TypeID{typeid(T)},
221  it.label(),
222  it.instance(),
223  it.process());
224  return ViewToken<T>{it};
225 }
226 
227 #endif /* art_Framework_Principal_Consumer_h */
228 
229 // Local Variables:
230 // mode: c++
231 // End:
set< int >::iterator it
std::array< ConsumableProductVectorPerBranch, NumBranchTypes > ConsumableProducts
Definition: ProductInfo.h:55
ViewToken< Element > consumesView(InputTag const &)
Consumer(InvalidTag)
Definition: Consumer.h:133
std::string const & process() const noexcept
Definition: InputTag.h:67
void mayConsumeMany()
Definition: Consumer.h:204
std::string const & instance() const noexcept
Definition: InputTag.h:60
ProductToken< T > mayConsume(InputTag const &)
void consumesMany()
Definition: Consumer.h:161
BranchType
Definition: BranchType.h:18
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
double T
Definition: Xdiff_gwt.C:5
std::array< ConsumableProductSetPerBranch, NumBranchTypes > ConsumableProductSets
Definition: ProductInfo.h:57
ProductToken< T > consumes(InputTag const &)
std::string const & label() const noexcept
Definition: InputTag.h:55
ViewToken< Element > mayConsumeView(InputTag const &)