File indexing completed on 2023-03-17 11:03:21
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, bool optional) const override {
0064 switch_.validate(pset, validatedLabels, optional);
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, false);
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_(
0090 std::ostream& os, bool optional, bool& startWithComma, int indentation, bool& wroteSomething) const override {
0091 switch_.writeCfi(os, optional, startWithComma, indentation, wroteSomething);
0092
0093 typename CaseMap::const_iterator selectedCase = cases_.find(switch_.getDefaultValue());
0094 if (selectedCase != cases_.end()) {
0095 selectedCase->second->writeCfi(os, optional, startWithComma, indentation, wroteSomething);
0096 }
0097 }
0098
0099 void print_(std::ostream& os, bool optional, bool writeToCfi, DocFormatHelper& dfh) const override {
0100 printBase(os,
0101 optional,
0102 writeToCfi,
0103 dfh,
0104 switch_.label(),
0105 switch_.isTracked(),
0106 parameterTypeEnumToString(switch_.type()));
0107 }
0108
0109 void printNestedContent_(std::ostream& os, bool optional, DocFormatHelper& dfh) const override {
0110 DocFormatHelper new_dfh(dfh);
0111 printNestedContentBase(os, dfh, new_dfh, switch_.label());
0112
0113 switch_.print(os, optional, true, new_dfh);
0114 for_all(cases_,
0115 std::bind(&ParameterSwitchBase::printCaseT<T>,
0116 std::placeholders::_1,
0117 std::ref(os),
0118 optional,
0119 std::ref(new_dfh),
0120 std::cref(switch_.label())));
0121
0122 new_dfh.setPass(1);
0123 new_dfh.setCounter(0);
0124
0125 new_dfh.indent(os);
0126 os << "switch:\n";
0127 switch_.print(os, optional, true, new_dfh);
0128 for_all(cases_,
0129 std::bind(&ParameterSwitchBase::printCaseT<T>,
0130 std::placeholders::_1,
0131 std::ref(os),
0132 optional,
0133 std::ref(new_dfh),
0134 std::cref(switch_.label())));
0135
0136 new_dfh.setPass(2);
0137 new_dfh.setCounter(0);
0138
0139 switch_.printNestedContent(os, optional, new_dfh);
0140 for_all(cases_,
0141 std::bind(&ParameterSwitchBase::printCaseT<T>,
0142 std::placeholders::_1,
0143 std::ref(os),
0144 optional,
0145 std::ref(new_dfh),
0146 std::cref(switch_.label())));
0147 }
0148
0149 bool exists_(ParameterSet const& pset) const override { return switch_.exists(pset); }
0150
0151 static void checkCaseLabels(std::pair<T, edm::value_ptr<ParameterDescriptionNode> > const& thePair,
0152 std::set<std::string>& labels,
0153 std::set<ParameterTypes>& parameterTypes,
0154 std::set<ParameterTypes>& wildcardTypes) {
0155 thePair.second->checkAndGetLabelsAndTypes(labels, parameterTypes, wildcardTypes);
0156 }
0157
0158 ParameterDescription<T> switch_;
0159 CaseMap cases_;
0160 };
0161 }
0162 #endif