File indexing completed on 2025-03-26 01:51:12
0001 #ifndef FWCore_ParameterSet_ParameterSwitch_h
0002 #define FWCore_ParameterSet_ParameterSwitch_h
0003
0004 #include "FWCore/ParameterSet/interface/ParameterSwitchBase.h"
0005 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
0006 #include "FWCore/Utilities/interface/value_ptr.h"
0007 #include "FWCore/ParameterSet/interface/ParameterDescription.h"
0008 #include "FWCore/ParameterSet/interface/ParameterDescriptionCases.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 #include "FWCore/Utilities/interface/Algorithms.h"
0011 #include "FWCore/ParameterSet/interface/DocFormatHelper.h"
0012
0013 #include <map>
0014 #include <memory>
0015 #include <set>
0016 #include <string>
0017 #include <utility>
0018 #include <sstream>
0019 #include <ostream>
0020 #include <iomanip>
0021
0022 namespace edm {
0023
0024 template <class T>
0025 class ParameterSwitch : public ParameterSwitchBase {
0026 public:
0027 typedef std::map<T, edm::value_ptr<ParameterDescriptionNode> > CaseMap;
0028 typedef typename std::map<T, edm::value_ptr<ParameterDescriptionNode> >::const_iterator CaseMapConstIter;
0029
0030 ParameterSwitch(ParameterDescription<T> const& switchParameter,
0031 std::unique_ptr<ParameterDescriptionCases<T> > cases)
0032 : switch_(switchParameter), cases_(*cases->caseMap()) {
0033 if (cases->duplicateCaseValues()) {
0034 throwDuplicateCaseValues(switchParameter.label());
0035 }
0036 }
0037
0038 ParameterDescriptionNode* clone() const override { return new ParameterSwitch(*this); }
0039
0040 private:
0041 void checkAndGetLabelsAndTypes_(std::set<std::string>& usedLabels,
0042 std::set<ParameterTypes>& parameterTypes,
0043 std::set<ParameterTypes>& wildcardTypes) const override {
0044 std::set<std::string> caseLabels;
0045 std::set<ParameterTypes> caseParameterTypes;
0046 std::set<ParameterTypes> caseWildcardTypes;
0047 for_all(cases_,
0048 std::bind(&ParameterSwitch::checkCaseLabels,
0049 std::placeholders::_1,
0050 std::ref(caseLabels),
0051 std::ref(caseParameterTypes),
0052 std::ref(caseWildcardTypes)));
0053
0054 insertAndCheckLabels(switch_.label(), usedLabels, caseLabels);
0055
0056 insertAndCheckTypes(switch_.type(), caseParameterTypes, caseWildcardTypes, parameterTypes, wildcardTypes);
0057
0058 if (cases_.find(switch_.getDefaultValue()) == cases_.end()) {
0059 throwNoCaseForDefault(switch_.label());
0060 }
0061 }
0062
0063 void validate_(ParameterSet& pset, std::set<std::string>& validatedLabels, Modifier modifier) const override {
0064 switch_.validate(pset, validatedLabels, modifier);
0065 if (switch_.exists(pset)) {
0066 T switchValue;
0067 if (switch_.isTracked()) {
0068 switchValue = pset.getParameter<T>(switch_.label());
0069 } else {
0070 switchValue = pset.getUntrackedParameter<T>(switch_.label());
0071 }
0072 typename CaseMap::const_iterator selectedCase = cases_.find(switchValue);
0073 if (selectedCase != cases_.end()) {
0074 selectedCase->second->validate(pset, validatedLabels, Modifier::kNone);
0075 } else {
0076 std::stringstream ss;
0077 ss << "The switch parameter with label \"" << switch_.label() << "\" has been assigned an illegal value.\n"
0078 << "The value from the configuration is \"" << switchValue << "\".\n"
0079 << "The allowed values are:\n";
0080
0081 for (CaseMapConstIter iter = cases_.begin(), iEnd = cases_.end(); iter != iEnd; ++iter) {
0082 ss << " " << iter->first << "\n";
0083 }
0084 throwNoCaseForSwitchValue(ss.str());
0085 }
0086 }
0087 }
0088
0089 void writeCfi_(std::ostream& os,
0090 Modifier modifier,
0091 bool& startWithComma,
0092 int indentation,
0093 CfiOptions& options,
0094 bool& wroteSomething) const override {
0095 switch_.writeCfi(os, modifier, startWithComma, indentation, options, wroteSomething);
0096
0097 if (std::holds_alternative<cfi::ClassFile>(options)) {
0098 std::set<std::string> labels;
0099 std::set<ParameterTypes> parameterTypes;
0100 std::set<ParameterTypes> wildcardTypes;
0101 for (auto const& n : cases_) {
0102 n.second->checkAndGetLabelsAndTypes(labels, parameterTypes, wildcardTypes);
0103 }
0104 for (auto const& l : labels) {
0105 cfi::parameterMustBeTyped(options, l);
0106 }
0107 }
0108
0109 typename CaseMap::const_iterator selectedCase = cases_.find(switch_.getDefaultValue());
0110 if (selectedCase != cases_.end()) {
0111 selectedCase->second->writeCfi(os, modifier, startWithComma, indentation, options, wroteSomething);
0112 }
0113 }
0114
0115 void print_(std::ostream& os, Modifier modifier, bool writeToCfi, DocFormatHelper& dfh) const override {
0116 printBase(os,
0117 modifier,
0118 writeToCfi,
0119 dfh,
0120 switch_.label(),
0121 switch_.isTracked(),
0122 parameterTypeEnumToString(switch_.type()));
0123 }
0124
0125 void printNestedContent_(std::ostream& os, bool optional, DocFormatHelper& dfh) const override {
0126 DocFormatHelper new_dfh(dfh);
0127 printNestedContentBase(os, dfh, new_dfh, switch_.label());
0128
0129 switch_.print(os, modifierIsOptional(optional), true, new_dfh);
0130 for_all(cases_,
0131 std::bind(&ParameterSwitchBase::printCaseT<T>,
0132 std::placeholders::_1,
0133 std::ref(os),
0134 optional,
0135 std::ref(new_dfh),
0136 std::cref(switch_.label())));
0137
0138 new_dfh.setPass(1);
0139 new_dfh.setCounter(0);
0140
0141 new_dfh.indent(os);
0142 os << "switch:\n";
0143 switch_.print(os, modifierIsOptional(optional), true, new_dfh);
0144 for_all(cases_,
0145 std::bind(&ParameterSwitchBase::printCaseT<T>,
0146 std::placeholders::_1,
0147 std::ref(os),
0148 optional,
0149 std::ref(new_dfh),
0150 std::cref(switch_.label())));
0151
0152 new_dfh.setPass(2);
0153 new_dfh.setCounter(0);
0154
0155 switch_.printNestedContent(os, optional, new_dfh);
0156 for_all(cases_,
0157 std::bind(&ParameterSwitchBase::printCaseT<T>,
0158 std::placeholders::_1,
0159 std::ref(os),
0160 optional,
0161 std::ref(new_dfh),
0162 std::cref(switch_.label())));
0163 }
0164
0165 bool exists_(ParameterSet const& pset) const override { return switch_.exists(pset); }
0166
0167 static void checkCaseLabels(std::pair<T, edm::value_ptr<ParameterDescriptionNode> > const& thePair,
0168 std::set<std::string>& labels,
0169 std::set<ParameterTypes>& parameterTypes,
0170 std::set<ParameterTypes>& wildcardTypes) {
0171 thePair.second->checkAndGetLabelsAndTypes(labels, parameterTypes, wildcardTypes);
0172 }
0173
0174 ParameterDescription<T> switch_;
0175 CaseMap cases_;
0176 };
0177 }
0178 #endif