Back to home page

Project CMSSW displayed by LXR

 
 

    


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 }  // namespace edm
0162 #endif