Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-23 03:13:13

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_(std::ostream& os,
0090                    bool optional,
0091                    bool& startWithComma,
0092                    int indentation,
0093                    CfiOptions& options,
0094                    bool& wroteSomething) const override {
0095       switch_.writeCfi(os, optional, 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, optional, startWithComma, indentation, options, wroteSomething);
0112       }
0113     }
0114 
0115     void print_(std::ostream& os, bool optional, bool writeToCfi, DocFormatHelper& dfh) const override {
0116       printBase(os,
0117                 optional,
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, 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, 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 }  // namespace edm
0178 #endif