test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EDConsumerBase.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWCore/Framework
4 // Class : EDConsumerBase
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Chris Jones
10 // Created: Tue, 02 Apr 2013 21:36:06 GMT
11 //
12 
13 // system include files
14 #include <algorithm>
15 #include <cassert>
16 #include <cstring>
17 #include <set>
18 #include <utility>
19 
20 // user include files
29 
30 using namespace edm;
31 
32 //
33 // constants, enums and typedefs
34 //
35 
36 //
37 // static data member definitions
38 //
39 
40 //
41 // constructors and destructor
42 //
43 //EDConsumerBase::EDConsumerBase()
44 //{
45 //}
46 
47 // EDConsumerBase::EDConsumerBase(const EDConsumerBase& rhs)
48 // {
49 // // do actual copying here;
50 // }
51 
53 {
54 }
55 
56 //
57 // assignment operators
58 //
59 // const EDConsumerBase& EDConsumerBase::operator=(const EDConsumerBase& rhs)
60 // {
61 // //An exception safe implementation is
62 // EDConsumerBase temp(rhs);
63 // swap(rhs);
64 //
65 // return *this;
66 // }
67 
68 //
69 // member functions
70 //
73  ConsumesCollector c{this};
74  return c;
75 }
76 
77 static const edm::InputTag kWasEmpty("@EmptyLabel@");
78 
79 edm::InputTag const&
81  if (iTag.label().empty()) {
82  return kWasEmpty;
83  }
84  return iTag;
85 }
86 
87 unsigned int
88 EDConsumerBase::recordConsumes(BranchType iBranch, TypeToGet const& iType, edm::InputTag const& iTag, bool iAlwaysGets) {
89 
90  if(frozen_) {
91  throwConsumesCallAfterFrozen(iType, iTag);
92  }
93 
94  unsigned int index =m_tokenInfo.size();
95 
96  bool skipCurrentProcess = iTag.willSkipCurrentProcess();
97 
98  const size_t labelSize = iTag.label().size();
99  const size_t productInstanceSize = iTag.instance().size();
100  unsigned int labelStart = m_tokenLabels.size();
101  unsigned short delta1 = labelSize+1;
102  unsigned short delta2 = labelSize+2+productInstanceSize;
103  m_tokenInfo.emplace_back(TokenLookupInfo{iType.type(), ProductHolderIndexInvalid, skipCurrentProcess, iBranch},
104  iAlwaysGets,
105  LabelPlacement{labelStart,delta1,delta2},
106  iType.kind());
107 
108  const size_t additionalSize =
109  skipCurrentProcess ?
110  labelSize+productInstanceSize+3 :
111  labelSize+productInstanceSize+iTag.process().size()+3;
112 
113  m_tokenLabels.reserve(m_tokenLabels.size()+additionalSize);
114  {
115  const std::string& m =iTag.label();
116  m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
117  m_tokenLabels.push_back('\0');
118  }
119  {
120  const std::string& m =iTag.instance();
121  m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
122  m_tokenLabels.push_back('\0');
123  }
124  {
125  if (!skipCurrentProcess) {
126  const std::string& m =iTag.process();
127  m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
128  m_tokenLabels.push_back('\0');
129  } else {
130  m_tokenLabels.push_back('\0');
131  }
132  }
133  return index;
134 }
135 
136 void
138  ProductHolderIndexHelper const& iHelper)
139 {
140  frozen_ = true;
141  {
142  auto itKind = m_tokenInfo.begin<kKind>();
143  auto itLabels = m_tokenInfo.begin<kLabels>();
144  for(auto itInfo = m_tokenInfo.begin<kLookupInfo>(),itEnd = m_tokenInfo.end<kLookupInfo>();
145  itInfo != itEnd; ++itInfo,++itKind,++itLabels) {
146  if(itInfo->m_branchType == iBranchType) {
147  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
148  const char* moduleLabel = &(m_tokenLabels[labelStart]);
149  itInfo->m_index = ProductHolderIndexAndSkipBit(iHelper.index(*itKind,
150  itInfo->m_type,
151  moduleLabel,
152  moduleLabel+itLabels->m_deltaToProductInstance,
153  moduleLabel+itLabels->m_deltaToProcessName),
154  itInfo->m_index.skipCurrentProcess());
155  }
156  }
157  }
158 
159  //now add resolved requests to get many to the end of our list
160  // a get many will have an empty module label
161  for(size_t i=0, iEnd = m_tokenInfo.size(); i!=iEnd;++i) {
162  //need to copy since pointer could be invalidated by emplace_back
163  auto const info = m_tokenInfo.get<kLookupInfo>(i);
164  if(info.m_branchType == iBranchType &&
165  info.m_index.productHolderIndex() == ProductHolderIndexInvalid &&
166  m_tokenLabels[m_tokenInfo.get<kLabels>(i).m_startOfModuleLabel]=='\0') {
167  //find all matching types
168  const auto kind=m_tokenInfo.get<kKind>(i);
169  auto matches = iHelper.relatedIndexes(kind,info.m_type);
170 
171  //NOTE: This could be changed to contain the true labels for what is being
172  // requested but for now I want to remember these are part of a get many
174  bool alwaysGet = m_tokenInfo.get<kAlwaysGets>(i);
175  for(unsigned int j=0;j!=matches.numberOfMatches();++j) {
176  //only keep the ones that are for a specific data item and not a collection
177  if(matches.isFullyResolved(j)) {
178  auto index =matches.index(j);
179  m_tokenInfo.emplace_back(TokenLookupInfo{info.m_type, index, info.m_index.skipCurrentProcess(), info.m_branchType},
180  alwaysGet,
181  labels,
182  kind);
183  }
184  }
185  }
186  }
187  m_tokenInfo.shrink_to_fit();
188 
189  if(iBranchType == InEvent) {
190  itemsToGet(iBranchType, itemsToGetFromEvent_);
191  }
192 }
193 
194 //
195 // const member functions
196 //
198 EDConsumerBase::indexFrom(EDGetToken iToken, BranchType iBranch, TypeID const& iType) const
199 {
200  if(unlikely(iToken.index()>=m_tokenInfo.size())) {
201  throwBadToken(iType,iToken);
202  }
203  const auto& info = m_tokenInfo.get<kLookupInfo>(iToken.index());
204  if (likely(iBranch == info.m_branchType)) {
205  if (likely(iType == info.m_type)) {
206  return info.m_index;
207  } else {
208  throwTypeMismatch(iType, iToken);
209  }
210  } else {
211  throwBranchMismatch(iBranch,iToken);
212  }
214 }
215 
216 void
217 EDConsumerBase::itemsToGet(BranchType iBranch, std::vector<ProductHolderIndexAndSkipBit>& oIndices) const
218 {
219  //how many are we adding?
220  unsigned int count=0;
221  {
222  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
223  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
224  itEnd = m_tokenInfo.end<kLookupInfo>();
225  it != itEnd; ++it,++itAlwaysGet) {
226  if(iBranch==it->m_branchType) {
227  if (it->m_index.productHolderIndex() != ProductHolderIndexInvalid) {
228  if(*itAlwaysGet) {
229  ++count;
230  }
231  }
232  }
233  }
234  }
235  oIndices.reserve(oIndices.size()+count);
236  {
237  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
238  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
239  itEnd = m_tokenInfo.end<kLookupInfo>();
240  it != itEnd; ++it,++itAlwaysGet) {
241  if(iBranch==it->m_branchType) {
242  if (it->m_index.productHolderIndex() != ProductHolderIndexInvalid) {
243  if(*itAlwaysGet) {
244  oIndices.push_back(it->m_index);
245  }
246  }
247  }
248  }
249  }
250 }
251 
252 void
253 EDConsumerBase::itemsMayGet(BranchType iBranch, std::vector<ProductHolderIndexAndSkipBit>& oIndices) const
254 {
255  //how many are we adding?
256  unsigned int count=0;
257  {
258  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
259  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
260  itEnd = m_tokenInfo.end<kLookupInfo>();
261  it != itEnd; ++it,++itAlwaysGet) {
262  if(iBranch==it->m_branchType) {
263  if (it->m_index.productHolderIndex() != ProductHolderIndexInvalid) {
264  if(not *itAlwaysGet) {
265  ++count;
266  }
267  }
268  }
269  }
270  }
271  oIndices.reserve(oIndices.size()+count);
272  {
273  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
274  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
275  itEnd = m_tokenInfo.end<kLookupInfo>();
276  it != itEnd; ++it,++itAlwaysGet) {
277  if(iBranch==it->m_branchType) {
278  if (it->m_index.productHolderIndex() != ProductHolderIndexInvalid) {
279  if(not *itAlwaysGet) {
280  oIndices.push_back(it->m_index);
281  }
282  }
283  }
284  }
285  }
286 }
287 
288 void
290 {
291  unsigned int index = iToken.index();
292  auto labels = m_tokenInfo.get<kLabels>(index);
293  unsigned int start = labels.m_startOfModuleLabel;
294  oLabels.module = &(m_tokenLabels[start]);
295  oLabels.productInstance = oLabels.module+labels.m_deltaToProductInstance;
296  oLabels.process = oLabels.module+labels.m_deltaToProcessName;
297 }
298 
299 bool
300 EDConsumerBase::registeredToConsume(ProductHolderIndex iIndex, bool skipCurrentProcess, BranchType iBranch) const
301 {
302  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
303  itEnd = m_tokenInfo.end<kLookupInfo>();
304  it != itEnd; ++it) {
305  if(it->m_index.productHolderIndex() == iIndex and
306  it->m_index.skipCurrentProcess() == skipCurrentProcess and
307  it->m_branchType == iBranch) {
308  return true;
309  }
310  }
311  //TEMPORARY: Remember so we do not have to do this again
312  //non thread-safe
313  EDConsumerBase* nonConstThis = const_cast<EDConsumerBase*>(this);
314  nonConstThis->m_tokenInfo.emplace_back(TokenLookupInfo{TypeID{}, iIndex, skipCurrentProcess, iBranch},
315  true,
316  LabelPlacement{0,0,0},
317  PRODUCT_TYPE);
318 
319  return false;
320 }
321 
322 bool
324 {
325  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
326  itEnd = m_tokenInfo.end<kLookupInfo>();
327  it != itEnd; ++it) {
328  //consumesMany entries do not have their index resolved
329  if(it->m_index.productHolderIndex() == ProductHolderIndexInvalid and
330  it->m_type == iType and
331  it->m_branchType == iBranch) {
332  return true;
333  }
334  }
335  //TEMPORARY: Remember so we do not have to do this again
336  //non thread-safe
337  EDConsumerBase* nonConstThis = const_cast<EDConsumerBase*>(this);
338  nonConstThis->m_tokenInfo.emplace_back(TokenLookupInfo{iType,ProductHolderIndexInvalid, false, iBranch},
339  true,
340  LabelPlacement{0,0,0},
341  PRODUCT_TYPE);
342  return false;
343 
344 }
345 
346 
347 void
349 {
350  throw cms::Exception("TypeMismatch")<<"A get using a EDGetToken used the C++ type '"<<iType.className()<<"' but the consumes call was for type '"<<m_tokenInfo.get<kLookupInfo>(iToken.index()).m_type.className()<<"'.\n Please modify either the consumes or get call so the types match.";
351 }
352 void
354  throw cms::Exception("BranchTypeMismatch")<<"A get using a EDGetToken was done in "<<BranchTypeToString(iBranch)<<" but the consumes call was for "<<BranchTypeToString(m_tokenInfo.get<kLookupInfo>(iToken.index()).m_branchType)<<".\n Please modify the consumes call to use the correct branch type.";
355 }
356 
357 void
359 {
360  if(iToken.isUninitialized()) {
361  throw cms::Exception("BadToken")<<"A get using a EDGetToken with the C++ type '"<<iType.className()<<"' was made using an uninitialized token.\n Please check that the variable is being initialized from a 'consumes' call.";
362  }
363  throw cms::Exception("BadToken")<<"A get using a EDGetToken with the C++ type '"<<iType.className()<<"' was made using a token with a value "<<iToken.index()<<" which is beyond the range used by this module.\n Please check that the variable is being initialized from a 'consumes' call from this module.\n You can not share EDGetToken values between modules.";
364 }
365 
366 void
368  throw cms::Exception("LogicError") << "A module declared it consumes a product after its constructor.\n"
369  << "This must be done in the contructor\n"
370  << "The product type was: " << typeToGet.type() << "\n"
371  << "and " << inputTag << "\n";
372 }
373 
374 namespace {
375  struct CharStarComp {
376  bool operator()(const char* iLHS, const char* iRHS) const {
377  return strcmp(iLHS,iRHS) < 0;
378  }
379  };
380 }
381 
382 void
384  std::string const& iModuleLabel,
385  bool iPrint,
386  std::vector<char const*>& oModuleLabels) const {
387  std::set<char const*, CharStarComp> uniqueModules;
388  for(unsigned int index = 0, iEnd = m_tokenInfo.size(); index < iEnd; ++index) {
389  auto const& info = m_tokenInfo.get<kLookupInfo>(index);
390  if(not info.m_index.skipCurrentProcess()) {
391  auto const& labels = m_tokenInfo.get<kLabels>(index);
392  unsigned int const start = labels.m_startOfModuleLabel;
393  char const* processName = &(m_tokenLabels[start+labels.m_deltaToProcessName]);
394  if(iPrint) {
395  LogAbsolute("ModuleDependency") << "ModuleDependency '" << iModuleLabel <<
396  "' may consume product of type '" << info.m_type.className() <<
397  "' with input tag '" << &(m_tokenLabels[start]) <<
398  ':' << &(m_tokenLabels[start+labels.m_deltaToProductInstance]) <<
399  ':' << processName << "'";;
400  }
401  if((not processName) or processName[0]==0 or iProcessName == processName) {
402  uniqueModules.insert(&(m_tokenLabels[start]));
403  }
404  }
405  }
406 
407  oModuleLabels = std::vector<const char*>(uniqueModules.begin(),uniqueModules.end());
408 }
409 
410 
411 namespace {
412  void
413  insertFoundModuleLabel(const char* consumedModuleLabel,
414  std::vector<ModuleDescription const*>& modules,
415  std::set<std::string>& alreadyFound,
416  std::map<std::string, ModuleDescription const*> const& labelsToDesc,
417  ProductRegistry const& preg) {
418  // Convert from label string to module description, eliminate duplicates,
419  // then insert into the vector of modules
420  auto it = labelsToDesc.find(consumedModuleLabel);
421  if(it != labelsToDesc.end()) {
422  if(alreadyFound.insert(consumedModuleLabel).second) {
423  modules.push_back(it->second);
424  }
425  return;
426  }
427  // Deal with EDAlias's by converting to the original module label first
428  std::vector<std::pair<std::string, std::string> > const& aliasToOriginal = preg.aliasToOriginal();
429  std::pair<std::string, std::string> target(consumedModuleLabel, std::string());
430  auto iter = std::lower_bound(aliasToOriginal.begin(), aliasToOriginal.end(), target);
431  if(iter != aliasToOriginal.end() && iter->first == consumedModuleLabel) {
432 
433  std::string const& originalModuleLabel = iter->second;
434  auto iter2 = labelsToDesc.find(originalModuleLabel);
435  if(iter2 != labelsToDesc.end()) {
436  if(alreadyFound.insert(originalModuleLabel).second) {
437  modules.push_back(iter2->second);
438  }
439  return;
440  }
441  }
442  // Ignore the source products, we are only interested in module products.
443  // As far as I know, it should never be anything else so throw if something
444  // unknown gets passed in.
445  if(std::string(consumedModuleLabel) != "source") {
446  throw cms::Exception("EDConsumerBase", "insertFoundModuleLabel")
447  << "Couldn't find ModuleDescription for the consumed module label: "
448  << std::string(consumedModuleLabel) << "\n";
449  }
450  }
451 }
452 
453 void
454 EDConsumerBase::modulesWhoseProductsAreConsumed(std::vector<ModuleDescription const*>& modules,
455  ProductRegistry const& preg,
456  std::map<std::string, ModuleDescription const*> const& labelsToDesc,
457  std::string const& processName) const {
458 
459  ProductHolderIndexHelper const& iHelper = *preg.productLookup(InEvent);
460 
461  std::set<std::string> alreadyFound;
462 
463  auto itKind = m_tokenInfo.begin<kKind>();
464  auto itLabels = m_tokenInfo.begin<kLabels>();
465  for(auto itInfo = m_tokenInfo.begin<kLookupInfo>(),itEnd = m_tokenInfo.end<kLookupInfo>();
466  itInfo != itEnd; ++itInfo,++itKind,++itLabels) {
467 
468  if(itInfo->m_branchType == InEvent) {
469 
470  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
471  const char* consumedModuleLabel = &(m_tokenLabels[labelStart]);
472  const char* consumedProcessName = consumedModuleLabel+itLabels->m_deltaToProcessName;
473 
474  if(*consumedModuleLabel != '\0') { // not a consumesMany
475  if(*consumedProcessName != '\0') { // process name is specified in consumes call
476  if (processName == consumedProcessName &&
477  iHelper.index(*itKind,
478  itInfo->m_type,
479  consumedModuleLabel,
480  consumedModuleLabel+itLabels->m_deltaToProductInstance,
481  consumedModuleLabel+itLabels->m_deltaToProcessName) != ProductHolderIndexInvalid) {
482  insertFoundModuleLabel(consumedModuleLabel, modules, alreadyFound, labelsToDesc, preg);
483  }
484  } else { // process name was empty
485  auto matches = iHelper.relatedIndexes(*itKind,
486  itInfo->m_type,
487  consumedModuleLabel,
488  consumedModuleLabel+itLabels->m_deltaToProductInstance);
489  for(unsigned int j = 0; j < matches.numberOfMatches(); ++j) {
490  if(processName == matches.processName(j)) {
491  insertFoundModuleLabel(consumedModuleLabel, modules, alreadyFound, labelsToDesc, preg);
492  }
493  }
494  }
495  // consumesMany case
496  } else if(itInfo->m_index.productHolderIndex() == ProductHolderIndexInvalid) {
497  auto matches = iHelper.relatedIndexes(*itKind,
498  itInfo->m_type);
499  for(unsigned int j = 0; j < matches.numberOfMatches(); ++j) {
500  if(processName == matches.processName(j)) {
501  insertFoundModuleLabel(matches.moduleLabel(j), modules, alreadyFound, labelsToDesc, preg);
502  }
503  }
504  }
505  }
506  }
507 }
508 
509 std::vector<ConsumesInfo>
511 
512  // Use this to eliminate duplicate entries related
513  // to consumesMany items where only the type was specified
514  // and the there are multiple matches. In these cases the
515  // label, instance, and process will be empty.
516  std::set<edm::TypeID> alreadySeenTypes;
517 
518  std::vector<ConsumesInfo> result;
519  auto itAlways = m_tokenInfo.begin<kAlwaysGets>();
520  auto itKind = m_tokenInfo.begin<kKind>();
521  auto itLabels = m_tokenInfo.begin<kLabels>();
522  for(auto itInfo = m_tokenInfo.begin<kLookupInfo>(),itEnd = m_tokenInfo.end<kLookupInfo>();
523  itInfo != itEnd; ++itInfo,++itKind,++itLabels, ++itAlways) {
524 
525  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
526  const char* consumedModuleLabel = &(m_tokenLabels[labelStart]);
527  const char* consumedInstance = consumedModuleLabel+itLabels->m_deltaToProductInstance;
528  const char* consumedProcessName = consumedModuleLabel+itLabels->m_deltaToProcessName;
529 
530  // consumesMany case
531  if(*consumedModuleLabel == '\0') {
532  if(!alreadySeenTypes.insert(itInfo->m_type).second) {
533  continue;
534  }
535  }
536 
537  // Just copy the information into the ConsumesInfo data structure
538  result.emplace_back(itInfo->m_type,
539  consumedModuleLabel,
540  consumedInstance,
541  consumedProcessName,
542  itInfo->m_branchType,
543  *itKind,
544  *itAlways,
545  itInfo->m_index.skipCurrentProcess());
546  }
547  return result;
548 }
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
int i
Definition: DBlmapReader.cc:9
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
static const TGPicture * info(bool iBackgroundIsBlack)
std::vector< ConsumesInfo > consumesInfo() const
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
KindOfType kind() const
Definition: TypeToGet.h:45
void updateLookup(BranchType iBranchType, ProductHolderIndexHelper const &)
ProductHolderIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=0) const
void itemsToGet(BranchType, std::vector< ProductHolderIndexAndSkipBit > &) const
void itemsMayGet(BranchType, std::vector< ProductHolderIndexAndSkipBit > &) const
void throwTypeMismatch(edm::TypeID const &, EDGetToken) const
void throwBadToken(edm::TypeID const &iType, EDGetToken iToken) const
ProductHolderIndexAndSkipBit indexFrom(EDGetToken, BranchType, TypeID const &) const
std::shared_ptr< ProductHolderIndexHelper const > productLookup(BranchType branchType) const
unsigned int ProductHolderIndex
void throwConsumesCallAfterFrozen(TypeToGet const &, InputTag const &) const
edm::SoATuple< TokenLookupInfo, bool, LabelPlacement, edm::KindOfType > m_tokenInfo
void modulesWhoseProductsAreConsumed(std::vector< ModuleDescription const * > &modules, ProductRegistry const &preg, std::map< std::string, ModuleDescription const * > const &labelsToDesc, std::string const &processName) const
BranchType
Definition: BranchType.h:11
tuple result
Definition: mps_fire.py:84
char const * process
Definition: ProductLabels.h:7
unsigned int recordConsumes(BranchType iBranch, TypeToGet const &iType, edm::InputTag const &iTag, bool iAlwaysGets)
#define unlikely(x)
#define likely(x)
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
int j
Definition: DBlmapReader.cc:9
void throwBranchMismatch(BranchType, EDGetToken) const
bool isUninitialized() const
Definition: EDGetToken.h:47
char const * module
Definition: ProductLabels.h:5
std::vector< char > m_tokenLabels
edm::InputTag const & checkIfEmpty(edm::InputTag const &tag)
static const edm::InputTag kWasEmpty("@EmptyLabel@")
std::vector< std::pair< std::string, std::string > > const & aliasToOriginal() const
bool willSkipCurrentProcess() const
Definition: InputTag.h:42
bool registeredToConsumeMany(TypeID const &, BranchType) const
std::string const & BranchTypeToString(BranchType const &branchType)
Definition: BranchType.cc:99
void labelsForToken(EDGetToken iToken, Labels &oLabels) const
std::string const & label() const
Definition: InputTag.h:36
std::string const & process() const
Definition: InputTag.h:40
char const * productInstance
Definition: ProductLabels.h:6
bool registeredToConsume(ProductHolderIndex, bool, BranchType) const
TypeID const & type() const
Definition: TypeToGet.h:44
void modulesDependentUpon(std::string const &iProcessName, std::string const &iModuleLabel, bool iPrint, std::vector< char const * > &oModuleLabels) const
std::vector< ProductHolderIndexAndSkipBit > itemsToGetFromEvent_
std::string const & className() const
Definition: TypeID.cc:46
preg
Definition: Schedule.cc:374
std::string const & instance() const
Definition: InputTag.h:37
unsigned int index() const
Definition: EDGetToken.h:46