File indexing completed on 2025-01-31 02:19:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0011
0012 #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h"
0013
0014 #include "FWCore/Utilities/interface/Algorithms.h"
0015 #include "FWCore/Utilities/interface/EDMException.h"
0016 #include "FWCore/Reflection/interface/DictionaryTools.h"
0017 #include "FWCore/Utilities/interface/TypeID.h"
0018 #include "FWCore/Reflection/interface/TypeWithDict.h"
0019 #include "FWCore/Utilities/interface/WrappedClassName.h"
0020
0021 #include "TDictAttributeMap.h"
0022
0023 #include <cassert>
0024 #include <iterator>
0025 #include <limits>
0026 #include <set>
0027 #include <sstream>
0028 #include <ostream>
0029
0030 namespace edm {
0031
0032 ProductRegistry::ProductRegistry() : productList_(), transient_() {}
0033
0034 ProductRegistry::Transients::Transients()
0035 : frozen_(false),
0036 productProduced_(),
0037 anyProductProduced_(false),
0038 productLookups_{{std::make_unique<ProductResolverIndexHelper>(),
0039 std::make_unique<ProductResolverIndexHelper>(),
0040 std::make_unique<ProductResolverIndexHelper>(),
0041 std::make_unique<ProductResolverIndexHelper>()}},
0042 nextIndexValues_(),
0043 branchIDToIndex_() {
0044 for (bool& isProduced : productProduced_)
0045 isProduced = false;
0046 }
0047
0048 void ProductRegistry::Transients::reset() {
0049 frozen_ = false;
0050 for (bool& isProduced : productProduced_)
0051 isProduced = false;
0052 anyProductProduced_ = false;
0053
0054
0055 for (auto& iterProductLookup : productLookups_) {
0056 iterProductLookup = std::make_unique<ProductResolverIndexHelper>();
0057 }
0058 nextIndexValues_.fill(0);
0059
0060 branchIDToIndex_.clear();
0061 }
0062
0063 ProductRegistry::ProductRegistry(ProductList const& productList, bool toBeFrozen)
0064 : productList_(productList), transient_() {
0065 freezeIt(toBeFrozen);
0066 }
0067
0068 void ProductRegistry::addProduct(ProductDescription const& productDesc, bool fromListener) {
0069 assert(productDesc.produced());
0070 throwIfFrozen();
0071 std::pair<ProductList::iterator, bool> ret =
0072 productList_.insert(std::make_pair(BranchKey(productDesc), productDesc));
0073 if (!ret.second) {
0074 auto const& previous = *productList_.find(BranchKey(productDesc));
0075 if (previous.second.produced()) {
0076
0077 throw Exception(errors::LogicError, "Duplicate Product Identifier")
0078 << "\nThe Framework requires a unique branch name for each product\n"
0079 << "which consists of four parts: a friendly class name, module label,\n"
0080 << "product instance name, and process name. A product has been\n"
0081 << "registered with a duplicate branch name. The most common way\n"
0082 << "to fix this error is to modify the product instance name in\n"
0083 << "one of the offending 'produces' function calls. Another fix\n"
0084 << "would be to delete one of them if they are for the same product.\n\n"
0085 << " friendly class name = " << previous.second.friendlyClassName() << "\n"
0086 << " module label = " << previous.second.moduleLabel() << "\n"
0087 << " product instance name = " << previous.second.productInstanceName() << "\n"
0088 << " process name = " << previous.second.processName() << "\n\n"
0089 << "The following additional information is not used as part of\n"
0090 << "the unique branch identifier.\n\n"
0091 << " branch types = " << previous.second.branchType() << " " << productDesc.branchType() << "\n"
0092 << " class name = " << previous.second.fullClassName() << "\n\n"
0093 << "Note that if the four parts of the branch name are the same,\n"
0094 << "then this error will occur even if the branch types differ!\n\n";
0095 } else {
0096
0097 throw Exception(errors::Configuration, "Duplicate Process Name.\n")
0098 << "The process name " << productDesc.processName() << " was previously used for products in the input.\n"
0099 << "This has caused branch name conflicts between input products and new products.\n"
0100 << "Please modify the configuration file to use a distinct process name.\n"
0101 << "Alternately, drop all input products using that process name and the\n"
0102 << "descendants of those products.\n";
0103 }
0104 }
0105 addCalled(productDesc, fromListener);
0106 }
0107
0108 void ProductRegistry::addLabelAlias(ProductDescription const& productDesc,
0109 std::string const& labelAlias,
0110 std::string const& instanceAlias) {
0111 assert(productDesc.produced());
0112 assert(productDesc.branchID().isValid());
0113 throwIfFrozen();
0114 ProductDescription bd(productDesc, labelAlias, instanceAlias);
0115 std::pair<ProductList::iterator, bool> ret = productList_.insert(std::make_pair(BranchKey(bd), bd));
0116 assert(ret.second);
0117 transient_.aliasToOriginal_.emplace_back(
0118 PRODUCT_TYPE, productDesc.unwrappedTypeID(), labelAlias, instanceAlias, productDesc.moduleLabel());
0119 addCalled(bd, false);
0120 }
0121
0122 void ProductRegistry::copyProduct(ProductDescription const& productDesc) {
0123 assert(!productDesc.produced());
0124 throwIfFrozen();
0125 BranchKey k = BranchKey(productDesc);
0126 ProductList::iterator iter = productList_.find(k);
0127 if (iter == productList_.end()) {
0128 productList_.insert(std::make_pair(k, productDesc));
0129 } else {
0130 assert(combinable(iter->second, productDesc));
0131 iter->second.merge(productDesc);
0132 }
0133 }
0134
0135 bool ProductRegistry::anyProducts(BranchType brType) const {
0136 throwIfNotFrozen();
0137 for (ProductList::const_iterator it = productList_.begin(), itEnd = productList_.end(); it != itEnd; ++it) {
0138 if (it->second.branchType() == brType) {
0139 return true;
0140 }
0141 }
0142 return false;
0143 }
0144
0145 std::shared_ptr<ProductResolverIndexHelper const> ProductRegistry::productLookup(BranchType branchType) const {
0146 return get_underlying_safe(transient_.productLookups_[branchType]);
0147 }
0148
0149 std::shared_ptr<ProductResolverIndexHelper> ProductRegistry::productLookup(BranchType branchType) {
0150 return get_underlying_safe(transient_.productLookups_[branchType]);
0151 }
0152
0153 void ProductRegistry::setFrozen(bool initializeLookupInfo) {
0154 if (frozen())
0155 return;
0156 freezeIt();
0157 if (initializeLookupInfo) {
0158 initializeLookupTables(nullptr, nullptr, nullptr);
0159 }
0160 sort_all(transient_.aliasToOriginal_);
0161 }
0162
0163 void ProductRegistry::setFrozen(std::set<TypeID> const& productTypesConsumed,
0164 std::set<TypeID> const& elementTypesConsumed,
0165 std::string const& processName) {
0166 if (frozen())
0167 return;
0168 freezeIt();
0169 initializeLookupTables(&productTypesConsumed, &elementTypesConsumed, &processName);
0170 sort_all(transient_.aliasToOriginal_);
0171 }
0172
0173 void ProductRegistry::throwIfFrozen() const {
0174 if (frozen()) {
0175 throw cms::Exception("ProductRegistry", "throwIfFrozen")
0176 << "cannot modify the ProductRegistry because it is frozen\n";
0177 }
0178 }
0179
0180 void ProductRegistry::throwIfNotFrozen() const {
0181 if (!frozen()) {
0182 throw cms::Exception("ProductRegistry", "throwIfNotFrozen")
0183 << "cannot read the ProductRegistry because it is not yet frozen\n";
0184 }
0185 }
0186
0187 void ProductRegistry::addCalled(ProductDescription const&, bool) {}
0188
0189 std::vector<std::string> ProductRegistry::allBranchNames() const {
0190 std::vector<std::string> result;
0191 result.reserve(productList().size());
0192
0193 for (auto const& product : productList()) {
0194 result.push_back(product.second.branchName());
0195 }
0196 return result;
0197 }
0198
0199 std::vector<ProductDescription const*> ProductRegistry::allProductDescriptions() const {
0200 std::vector<ProductDescription const*> result;
0201 result.reserve(productList().size());
0202
0203 for (auto const& product : productList()) {
0204 result.push_back(&product.second);
0205 }
0206 return result;
0207 }
0208
0209 void ProductRegistry::updateFromInput(ProductList const& other) {
0210 for (auto const& product : other) {
0211 copyProduct(product.second);
0212 }
0213 }
0214
0215 void ProductRegistry::updateFromInput(std::vector<ProductDescription> const& other) {
0216 for (ProductDescription const& productDescription : other) {
0217 copyProduct(productDescription);
0218 }
0219 }
0220
0221 void ProductRegistry::addFromInput(edm::ProductRegistry const& other) {
0222 throwIfFrozen();
0223 for (auto const& prod : other.productList_) {
0224 ProductList::iterator iter = productList_.find(prod.first);
0225 if (iter == productList_.end()) {
0226 productList_.insert(std::make_pair(prod.first, prod.second));
0227 addCalled(prod.second, false);
0228 } else {
0229 assert(combinable(iter->second, prod.second));
0230 iter->second.merge(prod.second);
0231 }
0232 }
0233 }
0234
0235 void ProductRegistry::setUnscheduledProducts(std::set<std::string> const& unscheduledLabels) {
0236 throwIfFrozen();
0237
0238 bool hasAliases = false;
0239 std::vector<BranchID> onDemandIDs;
0240 for (auto& prod : productList_) {
0241 if (prod.second.produced() && prod.second.branchType() == InEvent &&
0242 unscheduledLabels.end() != unscheduledLabels.find(prod.second.moduleLabel())) {
0243 prod.second.setOnDemand(true);
0244 onDemandIDs.push_back(prod.second.branchID());
0245 }
0246 if (prod.second.produced() && prod.second.isAlias()) {
0247 hasAliases = true;
0248 }
0249 }
0250
0251
0252 if (hasAliases) {
0253 std::sort(onDemandIDs.begin(), onDemandIDs.end());
0254 for (auto& prod : productList_) {
0255 if (prod.second.isAlias()) {
0256 if (std::binary_search(onDemandIDs.begin(), onDemandIDs.end(), prod.second.aliasForBranchID())) {
0257 prod.second.setOnDemand(true);
0258 }
0259 }
0260 }
0261 }
0262 }
0263
0264 std::string ProductRegistry::merge(ProductRegistry const& other,
0265 std::string const& fileName,
0266 ProductDescription::MatchMode branchesMustMatch) {
0267 std::ostringstream differences;
0268
0269 ProductRegistry::ProductList::iterator j = productList_.begin();
0270 ProductRegistry::ProductList::iterator s = productList_.end();
0271 ProductRegistry::ProductList::const_iterator i = other.productList().begin();
0272 ProductRegistry::ProductList::const_iterator e = other.productList().end();
0273
0274
0275 while (j != s || i != e) {
0276 if (j != s && j->second.produced()) {
0277
0278 ++j;
0279 } else if (j == s || (i != e && i->first < j->first)) {
0280 if (i->second.present()) {
0281 differences << "Branch '" << i->second.branchName() << "' is in file '" << fileName << "'\n";
0282 differences << " but not in previous files.\n";
0283 } else {
0284 productList_.insert(*i);
0285 transient_.branchIDToIndex_[i->second.branchID()] = getNextIndexValue(i->second.branchType());
0286 ++nextIndexValue(i->second.branchType());
0287 }
0288 ++i;
0289 } else if (i == e || (j != s && j->first < i->first)) {
0290 if (j->second.present() &&
0291 (branchesMustMatch == ProductDescription::Strict || j->second.branchType() == InProcess)) {
0292 differences << "Branch '" << j->second.branchName() << "' is in previous files\n";
0293 differences << " but not in file '" << fileName << "'.\n";
0294 }
0295 ++j;
0296 } else {
0297 std::string difs = match(j->second, i->second, fileName);
0298 if (difs.empty()) {
0299 j->second.merge(i->second);
0300 } else {
0301 differences << difs;
0302 }
0303 ++i;
0304 ++j;
0305 }
0306 }
0307 return differences.str();
0308 }
0309
0310 void ProductRegistry::initializeLookupTables(std::set<TypeID> const* productTypesConsumed,
0311 std::set<TypeID> const* elementTypesConsumed,
0312 std::string const* processName) {
0313 std::map<TypeID, TypeID> containedTypeMap;
0314 std::map<TypeID, std::vector<TypeID>> containedTypeToBaseTypesMap;
0315
0316 std::vector<std::string> missingDictionaries;
0317 std::vector<std::string> branchNamesForMissing;
0318 std::vector<std::string> producedTypes;
0319
0320 transient_.branchIDToIndex_.clear();
0321
0322 for (auto const& product : productList_) {
0323 auto const& desc = product.second;
0324
0325 checkForDuplicateProcessName(desc, processName);
0326
0327 if (desc.produced() && !desc.transient()) {
0328 setProductProduced(desc.branchType());
0329 }
0330
0331
0332 if (desc.present()) {
0333
0334
0335
0336
0337 if (!desc.produced()) {
0338 if (!checkDictionary(missingDictionaries, desc.className(), desc.unwrappedType())) {
0339 checkDictionaryOfWrappedType(missingDictionaries, desc.className());
0340 branchNamesForMissing.emplace_back(desc.branchName());
0341 producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
0342 continue;
0343 }
0344 }
0345 TypeID typeID(desc.unwrappedType().typeInfo());
0346
0347 auto iterContainedType = containedTypeMap.find(typeID);
0348 bool alreadySawThisType = (iterContainedType != containedTypeMap.end());
0349
0350 if (!desc.produced() && !alreadySawThisType) {
0351 if (!checkDictionary(missingDictionaries, desc.wrappedName(), desc.wrappedType())) {
0352 branchNamesForMissing.emplace_back(desc.branchName());
0353 producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
0354 continue;
0355 }
0356 }
0357
0358 TypeID wrappedTypeID(desc.wrappedType().typeInfo());
0359
0360 TypeID containedTypeID;
0361 if (alreadySawThisType) {
0362 containedTypeID = iterContainedType->second;
0363 } else {
0364 containedTypeID = productholderindexhelper::getContainedTypeFromWrapper(wrappedTypeID, typeID.className());
0365 }
0366 bool hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
0367
0368 std::vector<TypeID>* baseTypesOfContainedType = nullptr;
0369
0370 if (!alreadySawThisType) {
0371 bool alreadyCheckedConstituents = desc.produced() && !desc.transient();
0372 if (!alreadyCheckedConstituents && !desc.transient()) {
0373
0374 if (!checkClassDictionaries(missingDictionaries, desc.wrappedName(), desc.wrappedType())) {
0375 branchNamesForMissing.emplace_back(desc.branchName());
0376 producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
0377 continue;
0378 }
0379 }
0380
0381 if (hasContainedType) {
0382 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
0383 if (iterBaseTypes == containedTypeToBaseTypesMap.end()) {
0384 std::vector<TypeID> baseTypes;
0385 if (!public_base_classes(missingDictionaries, containedTypeID, baseTypes)) {
0386 branchNamesForMissing.emplace_back(desc.branchName());
0387 if (desc.produced()) {
0388 producedTypes.emplace_back(desc.className() + std::string(" (produced in current process)"));
0389 } else {
0390 producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
0391 }
0392 continue;
0393 }
0394 iterBaseTypes = containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, baseTypes)).first;
0395 }
0396 baseTypesOfContainedType = &iterBaseTypes->second;
0397 }
0398
0399
0400
0401 containedTypeMap.emplace(typeID, containedTypeID);
0402 } else {
0403 if (hasContainedType) {
0404 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
0405 if (iterBaseTypes != containedTypeToBaseTypesMap.end()) {
0406 baseTypesOfContainedType = &iterBaseTypes->second;
0407 }
0408 }
0409 }
0410
0411 if (productTypesConsumed != nullptr && !desc.produced()) {
0412 bool mainTypeConsumed = (productTypesConsumed->find(typeID) != productTypesConsumed->end());
0413 bool containedTypeConsumed =
0414 hasContainedType && (elementTypesConsumed->find(containedTypeID) != elementTypesConsumed->end());
0415 if (hasContainedType && !containedTypeConsumed && baseTypesOfContainedType != nullptr) {
0416 for (TypeID const& baseType : *baseTypesOfContainedType) {
0417 if (elementTypesConsumed->find(TypeID(baseType.typeInfo())) != elementTypesConsumed->end()) {
0418 containedTypeConsumed = true;
0419 break;
0420 }
0421 }
0422 }
0423 if (!containedTypeConsumed) {
0424 if (mainTypeConsumed) {
0425
0426
0427
0428
0429 if (hasContainedType) {
0430 containedTypeID = TypeID(typeid(void));
0431 }
0432 } else {
0433
0434
0435
0436
0437 continue;
0438 }
0439 }
0440 }
0441 ProductResolverIndex index = productLookup(desc.branchType())
0442 ->insert(typeID,
0443 desc.moduleLabel().c_str(),
0444 desc.productInstanceName().c_str(),
0445 desc.processName().c_str(),
0446 containedTypeID,
0447 baseTypesOfContainedType);
0448
0449 transient_.branchIDToIndex_[desc.branchID()] = index;
0450 }
0451 }
0452 if (!missingDictionaries.empty()) {
0453 std::string context("Calling ProductRegistry::initializeLookupTables");
0454 throwMissingDictionariesException(missingDictionaries, context, producedTypes, branchNamesForMissing);
0455 }
0456
0457 for (auto& iterProductLookup : transient_.productLookups_) {
0458 iterProductLookup->setFrozen();
0459 }
0460
0461 unsigned int indexIntoNextIndexValue = 0;
0462 for (auto const& iterProductLookup : transient_.productLookups_) {
0463 transient_.nextIndexValues_[indexIntoNextIndexValue] = iterProductLookup->nextIndexValue();
0464 ++indexIntoNextIndexValue;
0465 }
0466
0467 for (auto const& product : productList_) {
0468 auto const& desc = product.second;
0469 if (transient_.branchIDToIndex_.find(desc.branchID()) == transient_.branchIDToIndex_.end()) {
0470 transient_.branchIDToIndex_[desc.branchID()] = getNextIndexValue(desc.branchType());
0471 ++nextIndexValue(desc.branchType());
0472 }
0473 }
0474 checkDictionariesOfConsumedTypes(
0475 productTypesConsumed, elementTypesConsumed, containedTypeMap, containedTypeToBaseTypesMap);
0476
0477 addElementTypesForAliases(elementTypesConsumed, containedTypeMap, containedTypeToBaseTypesMap);
0478 }
0479
0480 void ProductRegistry::addElementTypesForAliases(
0481 std::set<TypeID> const* elementTypesConsumed,
0482 std::map<TypeID, TypeID> const& containedTypeMap,
0483 std::map<TypeID, std::vector<TypeID>> const& containedTypeToBaseTypesMap) {
0484 Transients::AliasToOriginalVector elementAliases;
0485 for (auto& item : transient_.aliasToOriginal_) {
0486 auto iterContainedType = containedTypeMap.find(std::get<Transients::kType>(item));
0487 if (iterContainedType == containedTypeMap.end()) {
0488 edm::Exception ex(errors::LogicError);
0489 ex << "containedTypeMap did not contain " << std::get<Transients::kType>(item).className()
0490 << " that is used in EDAlias " << std::get<Transients::kModuleLabel>(item)
0491 << ".\nThis should not happen, contact framework developers";
0492 ex.addContext("Calling ProductRegistry::initializeLookupTables()");
0493 throw ex;
0494 }
0495 auto const& containedTypeID = iterContainedType->second;
0496 bool const hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
0497 if (not hasContainedType) {
0498 continue;
0499 }
0500
0501 if (elementTypesConsumed->find(containedTypeID) != elementTypesConsumed->end()) {
0502 elementAliases.emplace_back(ELEMENT_TYPE,
0503 containedTypeID,
0504 std::get<Transients::kModuleLabel>(item),
0505 std::get<Transients::kProductInstanceName>(item),
0506 std::get<Transients::kAliasForModuleLabel>(item));
0507 }
0508
0509 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
0510 if (iterBaseTypes == containedTypeToBaseTypesMap.end()) {
0511 continue;
0512 }
0513 for (TypeID const& baseTypeID : iterBaseTypes->second) {
0514 if (elementTypesConsumed->find(baseTypeID) != elementTypesConsumed->end()) {
0515 elementAliases.emplace_back(ELEMENT_TYPE,
0516 baseTypeID,
0517 std::get<Transients::kModuleLabel>(item),
0518 std::get<Transients::kProductInstanceName>(item),
0519 std::get<Transients::kAliasForModuleLabel>(item));
0520 }
0521 }
0522 }
0523 transient_.aliasToOriginal_.insert(transient_.aliasToOriginal_.end(),
0524 std::make_move_iterator(elementAliases.begin()),
0525 std::make_move_iterator(elementAliases.end()));
0526 }
0527
0528 void ProductRegistry::checkDictionariesOfConsumedTypes(
0529 std::set<TypeID> const* productTypesConsumed,
0530 std::set<TypeID> const* elementTypesConsumed,
0531 std::map<TypeID, TypeID> const& containedTypeMap,
0532 std::map<TypeID, std::vector<TypeID>>& containedTypeToBaseTypesMap) {
0533 std::vector<std::string> missingDictionaries;
0534 std::set<std::string> consumedTypesWithMissingDictionaries;
0535
0536 if (productTypesConsumed) {
0537
0538 for (auto const& consumedTypeID : *productTypesConsumed) {
0539
0540
0541
0542 if (containedTypeMap.find(consumedTypeID) == containedTypeMap.end()) {
0543 std::string wrappedName = wrappedClassName(consumedTypeID.className());
0544 TypeWithDict wrappedType = TypeWithDict::byName(wrappedName);
0545 if (!checkDictionary(missingDictionaries, wrappedName, wrappedType)) {
0546 checkDictionary(missingDictionaries, consumedTypeID);
0547 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0548 continue;
0549 }
0550 bool transient = false;
0551 TDictAttributeMap* wp = wrappedType.getClass()->GetAttributeMap();
0552 if (wp && wp->HasKey("persistent") && !strcmp(wp->GetPropertyAsString("persistent"), "false")) {
0553 transient = true;
0554 }
0555 if (transient) {
0556 if (!checkDictionary(missingDictionaries, consumedTypeID)) {
0557 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0558 }
0559
0560 TypeID containedTypeID = productholderindexhelper::getContainedTypeFromWrapper(
0561 TypeID(wrappedType.typeInfo()), consumedTypeID.className());
0562 bool hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
0563 if (hasContainedType) {
0564 if (containedTypeToBaseTypesMap.find(containedTypeID) == containedTypeToBaseTypesMap.end()) {
0565 std::vector<TypeID> bases;
0566
0567 if (!public_base_classes(missingDictionaries, containedTypeID, bases)) {
0568 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0569 }
0570 containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, bases));
0571 }
0572 }
0573 } else {
0574 if (!checkClassDictionaries(missingDictionaries, wrappedName, wrappedType)) {
0575 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0576 }
0577 }
0578 }
0579 }
0580 if (!missingDictionaries.empty()) {
0581 std::string context(
0582 "Calling ProductRegistry::initializeLookupTables, checking dictionaries for consumed products");
0583 throwMissingDictionariesException(missingDictionaries, context, consumedTypesWithMissingDictionaries, false);
0584 }
0585 }
0586
0587 if (elementTypesConsumed) {
0588 missingDictionaries.clear();
0589 consumedTypesWithMissingDictionaries.clear();
0590 for (auto const& consumedTypeID : *elementTypesConsumed) {
0591 if (containedTypeToBaseTypesMap.find(consumedTypeID) == containedTypeToBaseTypesMap.end()) {
0592 std::vector<TypeID> bases;
0593
0594 if (!public_base_classes(missingDictionaries, consumedTypeID, bases)) {
0595 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0596 }
0597 }
0598 }
0599 if (!missingDictionaries.empty()) {
0600 std::string context(
0601 "Calling ProductRegistry::initializeLookupTables, checking dictionaries for elements of products consumed "
0602 "using View");
0603 throwMissingDictionariesException(missingDictionaries, context, consumedTypesWithMissingDictionaries, true);
0604 }
0605 }
0606 }
0607
0608 void ProductRegistry::checkForDuplicateProcessName(ProductDescription const& desc,
0609 std::string const* processName) const {
0610 if (processName && !desc.produced() && (*processName == desc.processName())) {
0611 throw Exception(errors::Configuration, "Duplicate Process Name.\n")
0612 << "The process name " << *processName << " was previously used for products in the input.\n"
0613 << "Please modify the configuration file to use a distinct process name.\n"
0614 << "Alternately, drop all input products using that process name and the\n"
0615 << "descendants of those products.\n";
0616 }
0617 }
0618
0619 ProductResolverIndex ProductRegistry::indexFrom(BranchID const& iID) const {
0620 std::map<BranchID, ProductResolverIndex>::const_iterator itFind = transient_.branchIDToIndex_.find(iID);
0621 if (itFind == transient_.branchIDToIndex_.end()) {
0622 return ProductResolverIndexInvalid;
0623 }
0624 return itFind->second;
0625 }
0626
0627 std::vector<std::string> ProductRegistry::aliasToModules(KindOfType kindOfType,
0628 TypeID const& type,
0629 std::string_view moduleLabel,
0630 std::string_view productInstanceName) const {
0631 auto aliasFields = [](auto const& item) {
0632 return std::tie(std::get<Transients::kKind>(item),
0633 std::get<Transients::kType>(item),
0634 std::get<Transients::kModuleLabel>(item),
0635 std::get<Transients::kProductInstanceName>(item));
0636 };
0637 auto const target = std::tuple(kindOfType, type, moduleLabel, productInstanceName);
0638 auto found =
0639 std::lower_bound(transient_.aliasToOriginal_.begin(),
0640 transient_.aliasToOriginal_.end(),
0641 target,
0642 [aliasFields](auto const& item, auto const& target) { return aliasFields(item) < target; });
0643 std::vector<std::string> ret;
0644 for (; found != transient_.aliasToOriginal_.end() and aliasFields(*found) == target; ++found) {
0645 ret.emplace_back(std::get<Transients::kAliasForModuleLabel>(*found));
0646 }
0647 return ret;
0648 }
0649
0650 void ProductRegistry::print(std::ostream& os) const {
0651 for (auto const& product : productList_) {
0652 os << product.second << "\n-----\n";
0653 }
0654 }
0655
0656 ProductResolverIndex const& ProductRegistry::getNextIndexValue(BranchType branchType) const {
0657 return transient_.nextIndexValues_[branchType];
0658 }
0659
0660 ProductResolverIndex& ProductRegistry::nextIndexValue(BranchType branchType) {
0661 return transient_.nextIndexValues_[branchType];
0662 }
0663 }