CMS 3D CMS Logo

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(), ProductResolverIndexInvalid, 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  const std::string& m = iTag.process();
126  if (m == InputTag::kCurrentProcess) {
128  }
129  if (!skipCurrentProcess) {
130  m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
131  m_tokenLabels.push_back('\0');
132  } else {
133  m_tokenLabels.push_back('\0');
134  }
135  }
136  return index;
137 }
138 
139 void
141  ProductResolverIndexHelper const& iHelper,
142  bool iPrefetchMayGet)
143 {
144  frozen_ = true;
146  {
147  auto itKind = m_tokenInfo.begin<kKind>();
148  auto itLabels = m_tokenInfo.begin<kLabels>();
149  for(auto itInfo = m_tokenInfo.begin<kLookupInfo>(),itEnd = m_tokenInfo.end<kLookupInfo>();
150  itInfo != itEnd; ++itInfo,++itKind,++itLabels) {
151  if(itInfo->m_branchType == iBranchType) {
152  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
153  const char* moduleLabel = &(m_tokenLabels[labelStart]);
154  itInfo->m_index = ProductResolverIndexAndSkipBit(iHelper.index(*itKind,
155  itInfo->m_type,
156  moduleLabel,
157  moduleLabel+itLabels->m_deltaToProductInstance,
158  moduleLabel+itLabels->m_deltaToProcessName),
159  itInfo->m_index.skipCurrentProcess());
160  }
161  }
162  }
163 
164  //now add resolved requests to get many to the end of our list
165  // a get many will have an empty module label
166  for(size_t i=0, iEnd = m_tokenInfo.size(); i!=iEnd;++i) {
167  //need to copy since pointer could be invalidated by emplace_back
168  auto const info = m_tokenInfo.get<kLookupInfo>(i);
169  if(info.m_branchType == iBranchType &&
170  info.m_index.productResolverIndex() == ProductResolverIndexInvalid &&
171  m_tokenLabels[m_tokenInfo.get<kLabels>(i).m_startOfModuleLabel]=='\0') {
172  //find all matching types
173  const auto kind=m_tokenInfo.get<kKind>(i);
174  auto matches = iHelper.relatedIndexes(kind,info.m_type);
175 
176  //NOTE: This could be changed to contain the true labels for what is being
177  // requested but for now I want to remember these are part of a get many
179  bool alwaysGet = m_tokenInfo.get<kAlwaysGets>(i);
180  for(unsigned int j=0;j!=matches.numberOfMatches();++j) {
181  //only keep the ones that are for a specific data item and not a collection
182  if(matches.isFullyResolved(j)) {
183  auto index =matches.index(j);
184  m_tokenInfo.emplace_back(TokenLookupInfo{info.m_type, index, info.m_index.skipCurrentProcess(), info.m_branchType},
185  alwaysGet,
186  labels,
187  kind);
188  }
189  }
190  }
191  }
192  m_tokenInfo.shrink_to_fit();
193 
194  itemsToGet(iBranchType, itemsToGetFromBranch_[iBranchType]);
195  if(iPrefetchMayGet) {
196  itemsMayGet(iBranchType, itemsToGetFromBranch_[iBranchType]);
197  }
198 }
199 
200 //
201 // const member functions
202 //
204 EDConsumerBase::indexFrom(EDGetToken iToken, BranchType iBranch, TypeID const& iType) const
205 {
206  if(unlikely(iToken.index()>=m_tokenInfo.size())) {
207  throwBadToken(iType,iToken);
208  }
209  const auto& info = m_tokenInfo.get<kLookupInfo>(iToken.index());
210  if (likely(iBranch == info.m_branchType)) {
211  if (likely(iType == info.m_type)) {
212  return info.m_index;
213  } else {
214  throwTypeMismatch(iType, iToken);
215  }
216  } else {
217  throwBranchMismatch(iBranch,iToken);
218  }
220 }
221 
222 void
223 EDConsumerBase::itemsToGet(BranchType iBranch, std::vector<ProductResolverIndexAndSkipBit>& oIndices) const
224 {
225  //how many are we adding?
226  unsigned int count=0;
227  {
228  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
229  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
230  itEnd = m_tokenInfo.end<kLookupInfo>();
231  it != itEnd; ++it,++itAlwaysGet) {
232  if(iBranch==it->m_branchType) {
233  if (it->m_index.productResolverIndex() != ProductResolverIndexInvalid) {
234  if(*itAlwaysGet) {
235  ++count;
236  }
237  }
238  }
239  }
240  }
241  oIndices.reserve(oIndices.size()+count);
242  {
243  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
244  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
245  itEnd = m_tokenInfo.end<kLookupInfo>();
246  it != itEnd; ++it,++itAlwaysGet) {
247  if(iBranch==it->m_branchType) {
248  if (it->m_index.productResolverIndex() != ProductResolverIndexInvalid) {
249  if(*itAlwaysGet) {
250  oIndices.push_back(it->m_index);
251  }
252  }
253  }
254  }
255  }
256 }
257 
258 void
259 EDConsumerBase::itemsMayGet(BranchType iBranch, std::vector<ProductResolverIndexAndSkipBit>& oIndices) const
260 {
261  //how many are we adding?
262  unsigned int count=0;
263  {
264  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
265  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
266  itEnd = m_tokenInfo.end<kLookupInfo>();
267  it != itEnd; ++it,++itAlwaysGet) {
268  if(iBranch==it->m_branchType) {
269  if (it->m_index.productResolverIndex() != ProductResolverIndexInvalid) {
270  if(not *itAlwaysGet) {
271  ++count;
272  }
273  }
274  }
275  }
276  }
277  oIndices.reserve(oIndices.size()+count);
278  {
279  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
280  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
281  itEnd = m_tokenInfo.end<kLookupInfo>();
282  it != itEnd; ++it,++itAlwaysGet) {
283  if(iBranch==it->m_branchType) {
284  if (it->m_index.productResolverIndex() != ProductResolverIndexInvalid) {
285  if(not *itAlwaysGet) {
286  oIndices.push_back(it->m_index);
287  }
288  }
289  }
290  }
291  }
292 }
293 
294 void
296 {
297  unsigned int index = iToken.index();
298  auto labels = m_tokenInfo.get<kLabels>(index);
299  unsigned int start = labels.m_startOfModuleLabel;
300  oLabels.module = &(m_tokenLabels[start]);
301  oLabels.productInstance = oLabels.module+labels.m_deltaToProductInstance;
302  oLabels.process = oLabels.module+labels.m_deltaToProcessName;
303 }
304 
305 bool
306 EDConsumerBase::registeredToConsume(ProductResolverIndex iIndex, bool skipCurrentProcess, BranchType iBranch) const
307 {
308  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
309  itEnd = m_tokenInfo.end<kLookupInfo>();
310  it != itEnd; ++it) {
311  if(it->m_index.productResolverIndex() == iIndex and
312  it->m_index.skipCurrentProcess() == skipCurrentProcess and
313  it->m_branchType == iBranch) {
314  return true;
315  }
316  }
317  //TEMPORARY: Remember so we do not have to do this again
318  //non thread-safe
319  EDConsumerBase* nonConstThis = const_cast<EDConsumerBase*>(this);
320  nonConstThis->m_tokenInfo.emplace_back(TokenLookupInfo{TypeID{}, iIndex, skipCurrentProcess, iBranch},
321  true,
322  LabelPlacement{0,0,0},
323  PRODUCT_TYPE);
324 
325  return false;
326 }
327 
328 bool
330 {
331  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
332  itEnd = m_tokenInfo.end<kLookupInfo>();
333  it != itEnd; ++it) {
334  //consumesMany entries do not have their index resolved
335  if(it->m_index.productResolverIndex() == ProductResolverIndexInvalid and
336  it->m_type == iType and
337  it->m_branchType == iBranch) {
338  return true;
339  }
340  }
341  //TEMPORARY: Remember so we do not have to do this again
342  //non thread-safe
343  EDConsumerBase* nonConstThis = const_cast<EDConsumerBase*>(this);
344  nonConstThis->m_tokenInfo.emplace_back(TokenLookupInfo{iType,ProductResolverIndexInvalid, false, iBranch},
345  true,
346  LabelPlacement{0,0,0},
347  PRODUCT_TYPE);
348  return false;
349 
350 }
351 
352 
353 void
355 {
356  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.";
357 }
358 void
360  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.";
361 }
362 
363 void
365 {
366  if(iToken.isUninitialized()) {
367  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.";
368  }
369  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.";
370 }
371 
372 void
374  throw cms::Exception("LogicError") << "A module declared it consumes a product after its constructor.\n"
375  << "This must be done in the contructor\n"
376  << "The product type was: " << typeToGet.type() << "\n"
377  << "and " << inputTag << "\n";
378 }
379 
380 namespace {
381  struct CharStarComp {
382  bool operator()(const char* iLHS, const char* iRHS) const {
383  return strcmp(iLHS,iRHS) < 0;
384  }
385  };
386 }
387 
388 namespace {
389  void
390  insertFoundModuleLabel(const char* consumedModuleLabel,
391  std::vector<ModuleDescription const*>& modules,
392  std::set<std::string>& alreadyFound,
393  std::map<std::string, ModuleDescription const*> const& labelsToDesc,
394  ProductRegistry const& preg) {
395  // Convert from label string to module description, eliminate duplicates,
396  // then insert into the vector of modules
397  auto it = labelsToDesc.find(consumedModuleLabel);
398  if(it != labelsToDesc.end()) {
399  if(alreadyFound.insert(consumedModuleLabel).second) {
400  modules.push_back(it->second);
401  }
402  return;
403  }
404  // Deal with EDAlias's by converting to the original module label first
405  std::vector<std::pair<std::string, std::string> > const& aliasToOriginal = preg.aliasToOriginal();
406  std::pair<std::string, std::string> target(consumedModuleLabel, std::string());
407  auto iter = std::lower_bound(aliasToOriginal.begin(), aliasToOriginal.end(), target);
408  if(iter != aliasToOriginal.end() && iter->first == consumedModuleLabel) {
409 
410  std::string const& originalModuleLabel = iter->second;
411  auto iter2 = labelsToDesc.find(originalModuleLabel);
412  if(iter2 != labelsToDesc.end()) {
413  if(alreadyFound.insert(originalModuleLabel).second) {
414  modules.push_back(iter2->second);
415  }
416  return;
417  }
418  }
419  // Ignore the source products, we are only interested in module products.
420  // As far as I know, it should never be anything else so throw if something
421  // unknown gets passed in.
422  if(std::string(consumedModuleLabel) != "source") {
423  throw cms::Exception("EDConsumerBase", "insertFoundModuleLabel")
424  << "Couldn't find ModuleDescription for the consumed module label: "
425  << std::string(consumedModuleLabel) << "\n";
426  }
427  }
428 }
429 
430 void
431 EDConsumerBase::modulesWhoseProductsAreConsumed(std::vector<ModuleDescription const*>& modules,
432  ProductRegistry const& preg,
433  std::map<std::string, ModuleDescription const*> const& labelsToDesc,
434  std::string const& processName) const {
435 
436  ProductResolverIndexHelper const& iHelper = *preg.productLookup(InEvent);
437 
438  std::set<std::string> alreadyFound;
439 
440  auto itKind = m_tokenInfo.begin<kKind>();
441  auto itLabels = m_tokenInfo.begin<kLabels>();
442  for(auto itInfo = m_tokenInfo.begin<kLookupInfo>(),itEnd = m_tokenInfo.end<kLookupInfo>();
443  itInfo != itEnd; ++itInfo,++itKind,++itLabels) {
444 
445  if(itInfo->m_branchType == InEvent and
446  (not itInfo->m_index.skipCurrentProcess())) {
447 
448  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
449  const char* consumedModuleLabel = &(m_tokenLabels[labelStart]);
450  const char* consumedProcessName = consumedModuleLabel+itLabels->m_deltaToProcessName;
451 
452  if(*consumedModuleLabel != '\0') { // not a consumesMany
453  if(*consumedProcessName != '\0') { // process name is specified in consumes call
454  if (processName == consumedProcessName &&
455  iHelper.index(*itKind,
456  itInfo->m_type,
457  consumedModuleLabel,
458  consumedModuleLabel+itLabels->m_deltaToProductInstance,
459  consumedModuleLabel+itLabels->m_deltaToProcessName) != ProductResolverIndexInvalid) {
460  insertFoundModuleLabel(consumedModuleLabel, modules, alreadyFound, labelsToDesc, preg);
461  }
462  } else { // process name was empty
463  auto matches = iHelper.relatedIndexes(*itKind,
464  itInfo->m_type,
465  consumedModuleLabel,
466  consumedModuleLabel+itLabels->m_deltaToProductInstance);
467  for(unsigned int j = 0; j < matches.numberOfMatches(); ++j) {
468  if(processName == matches.processName(j)) {
469  insertFoundModuleLabel(consumedModuleLabel, modules, alreadyFound, labelsToDesc, preg);
470  }
471  }
472  }
473  // consumesMany case
474  } else if(itInfo->m_index.productResolverIndex() == ProductResolverIndexInvalid) {
475  auto matches = iHelper.relatedIndexes(*itKind,
476  itInfo->m_type);
477  for(unsigned int j = 0; j < matches.numberOfMatches(); ++j) {
478  if(processName == matches.processName(j)) {
479  insertFoundModuleLabel(matches.moduleLabel(j), modules, alreadyFound, labelsToDesc, preg);
480  }
481  }
482  }
483  }
484  }
485 }
486 
487 void
489 
490  frozen_ = true;
491 
494 
495  std::vector<char> newTokenLabels;
496 
497  // first calculate the size of the new vector and reserve memory for it
498  std::vector<char>::size_type newSize = 0;
499  std::string newProcessName;
500  for(auto iter = m_tokenInfo.begin<kLabels>(), itEnd = m_tokenInfo.end<kLabels>();
501  iter != itEnd; ++iter) {
502  newProcessName = &m_tokenLabels[iter->m_startOfModuleLabel + iter->m_deltaToProcessName];
503  if (newProcessName == InputTag::kCurrentProcess) {
504  newProcessName = processName;
505  }
506  newSize += (iter->m_deltaToProcessName + newProcessName.size() + 1);
507  }
508  newTokenLabels.reserve(newSize);
509 
510  unsigned int newStartOfModuleLabel = 0;
511  for(auto iter = m_tokenInfo.begin<kLabels>(), itEnd = m_tokenInfo.end<kLabels>();
512  iter != itEnd; ++iter) {
513 
514  unsigned int startOfModuleLabel = iter->m_startOfModuleLabel;
515  unsigned short deltaToProcessName = iter->m_deltaToProcessName;
516 
517  iter->m_startOfModuleLabel = newStartOfModuleLabel;
518 
519  newProcessName = &m_tokenLabels[startOfModuleLabel + deltaToProcessName];
520  if (newProcessName == InputTag::kCurrentProcess) {
521  newProcessName = processName;
522  }
523 
524  newStartOfModuleLabel += (deltaToProcessName + newProcessName.size() + 1);
525 
526  // Copy in both the module label and instance, they are the same
527  newTokenLabels.insert(newTokenLabels.end(),
528  m_tokenLabels.begin() + startOfModuleLabel,
529  m_tokenLabels.begin() + (startOfModuleLabel + deltaToProcessName));
530 
531  newTokenLabels.insert(newTokenLabels.end(), newProcessName.begin(), newProcessName.end());
532  newTokenLabels.push_back('\0');
533  }
534  m_tokenLabels = std::move(newTokenLabels);
535  }
536 }
537 
538 std::vector<ConsumesInfo>
540 
541  // Use this to eliminate duplicate entries related
542  // to consumesMany items where only the type was specified
543  // and the there are multiple matches. In these cases the
544  // label, instance, and process will be empty.
545  std::set<edm::TypeID> alreadySeenTypes;
546 
547  std::vector<ConsumesInfo> result;
548  auto itAlways = m_tokenInfo.begin<kAlwaysGets>();
549  auto itKind = m_tokenInfo.begin<kKind>();
550  auto itLabels = m_tokenInfo.begin<kLabels>();
551  for(auto itInfo = m_tokenInfo.begin<kLookupInfo>(),itEnd = m_tokenInfo.end<kLookupInfo>();
552  itInfo != itEnd; ++itInfo,++itKind,++itLabels, ++itAlways) {
553 
554  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
555  const char* consumedModuleLabel = &(m_tokenLabels[labelStart]);
556  const char* consumedInstance = consumedModuleLabel+itLabels->m_deltaToProductInstance;
557  const char* consumedProcessName = consumedModuleLabel+itLabels->m_deltaToProcessName;
558 
559  // consumesMany case
560  if(*consumedModuleLabel == '\0') {
561  if(!alreadySeenTypes.insert(itInfo->m_type).second) {
562  continue;
563  }
564  }
565 
566  // Just copy the information into the ConsumesInfo data structure
567  result.emplace_back(itInfo->m_type,
568  consumedModuleLabel,
569  consumedInstance,
570  consumedProcessName,
571  itInfo->m_branchType,
572  *itKind,
573  *itAlways,
574  itInfo->m_index.skipCurrentProcess());
575  }
576  return result;
577 }
Definition: start.py:1
static const TGPicture * info(bool iBackgroundIsBlack)
std::vector< ConsumesInfo > consumesInfo() const
unsigned int ProductResolverIndex
KindOfType kind() const
Definition: TypeToGet.h:45
void updateLookup(BranchType iBranchType, ProductResolverIndexHelper const &, bool iPrefetchMayGet)
void throwTypeMismatch(edm::TypeID const &, EDGetToken) const
void throwBadToken(edm::TypeID const &iType, EDGetToken iToken) const
#define noexcept
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
uint16_t size_type
BranchType
Definition: BranchType.h:11
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)
ProductResolverIndexAndSkipBit indexFrom(EDGetToken, BranchType, TypeID const &) const
bool registeredToConsume(ProductResolverIndex, bool, BranchType) const
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
void itemsToGet(BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
void throwBranchMismatch(BranchType, EDGetToken) const
static const std::string kCurrentProcess
Definition: InputTag.h:51
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
void itemsMayGet(BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
std::string const & BranchTypeToString(BranchType const &branchType)
Definition: BranchType.cc:99
std::shared_ptr< ProductResolverIndexHelper const > productLookup(BranchType branchType) const
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
HLT enums.
TypeID const & type() const
Definition: TypeToGet.h:44
std::string const & className() const
Definition: TypeID.cc:46
virtual ~EDConsumerBase() noexcept(false)
void convertCurrentProcessAlias(std::string const &processName)
Convert "@currentProcess" in InputTag process names to the actual current process name...
std::string const & instance() const
Definition: InputTag.h:37
unsigned int index() const
Definition: EDGetToken.h:46
def move(src, dest)
Definition: eostools.py:510
ProductResolverIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=nullptr) const
std::array< std::vector< ProductResolverIndexAndSkipBit >, edm::NumBranchTypes > itemsToGetFromBranch_