CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/FWCore/ParameterSet/interface/ParameterSwitch.h

Go to the documentation of this file.
00001 #ifndef FWCore_ParameterSet_ParameterSwitch_h
00002 #define FWCore_ParameterSet_ParameterSwitch_h
00003 
00004 #include "FWCore/ParameterSet/interface/ParameterSwitchBase.h"
00005 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
00006 #include "FWCore/Utilities/interface/value_ptr.h"
00007 #include "FWCore/ParameterSet/interface/ParameterDescription.h"
00008 #include "FWCore/ParameterSet/interface/ParameterDescriptionCases.h"
00009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00010 #include "FWCore/Utilities/interface/Algorithms.h"
00011 #include "FWCore/ParameterSet/interface/DocFormatHelper.h"
00012 
00013 #include "boost/bind.hpp"
00014 
00015 #include <map>
00016 #include <memory>
00017 #include <set>
00018 #include <string>
00019 #include <utility>
00020 #include <sstream>
00021 #include <ostream>
00022 #include <iomanip>
00023 
00024 namespace edm {
00025 
00026   template<class T>
00027   class ParameterSwitch : public ParameterSwitchBase {
00028 
00029   public:
00030     typedef std::map<T, edm::value_ptr<ParameterDescriptionNode> > CaseMap;
00031     typedef typename std::map<T, edm::value_ptr<ParameterDescriptionNode> >::const_iterator CaseMapConstIter;
00032 
00033     ParameterSwitch(ParameterDescription<T> const& switchParameter,
00034                     std::auto_ptr<ParameterDescriptionCases<T> > cases) :
00035       switch_(switchParameter),
00036       cases_(*cases->caseMap())
00037     {
00038       if (cases->duplicateCaseValues()) {
00039         throwDuplicateCaseValues(switchParameter.label());
00040       }
00041     }
00042 
00043     virtual ParameterDescriptionNode* clone() const {
00044       return new ParameterSwitch(*this);
00045     }
00046 
00047   private:
00048 
00049     virtual void checkAndGetLabelsAndTypes_(std::set<std::string> & usedLabels,
00050                                             std::set<ParameterTypes> & parameterTypes,
00051                                             std::set<ParameterTypes> & wildcardTypes) const {
00052 
00053       std::set<std::string> caseLabels;
00054       std::set<ParameterTypes> caseParameterTypes;
00055       std::set<ParameterTypes> caseWildcardTypes;
00056       for_all(cases_, boost::bind(&ParameterSwitch::checkCaseLabels,
00057                                   _1,
00058                                   boost::ref(caseLabels),
00059                                   boost::ref(caseParameterTypes),
00060                                   boost::ref(caseWildcardTypes)));
00061 
00062       insertAndCheckLabels(switch_.label(),
00063                            usedLabels,
00064                            caseLabels);
00065 
00066       insertAndCheckTypes(switch_.type(),
00067                           caseParameterTypes,
00068                           caseWildcardTypes,
00069                           parameterTypes,
00070                           wildcardTypes);
00071 
00072       if (cases_.find(switch_.getDefaultValue()) == cases_.end()) {
00073         throwNoCaseForDefault(switch_.label());
00074       }
00075     }
00076 
00077     virtual void validate_(ParameterSet & pset,
00078                            std::set<std::string> & validatedLabels,
00079                            bool optional) const {
00080 
00081       switch_.validate(pset, validatedLabels, optional);
00082       if (switch_.exists(pset)) {
00083         T switchValue;   
00084         if (switch_.isTracked()) {
00085           switchValue = pset.getParameter<T>(switch_.label());
00086         }
00087         else {
00088           switchValue = pset.getUntrackedParameter<T>(switch_.label());
00089         }
00090         typename CaseMap::const_iterator selectedCase = cases_.find(switchValue);
00091         if (selectedCase != cases_.end()) {
00092           selectedCase->second->validate(pset, validatedLabels, false);
00093         }
00094         else {
00095           std::stringstream ss;
00096           ss << "The switch parameter with label \""
00097              << switch_.label()
00098              << "\" has been assigned an illegal value.\n"
00099              << "The value from the configuration is \""
00100              << switchValue
00101              << "\".\n"
00102              << "The allowed values are:\n";
00103 
00104           for (CaseMapConstIter iter = cases_.begin(), iEnd = cases_.end();
00105                iter != iEnd;
00106                ++iter) {
00107             ss << "  " << iter->first << "\n";
00108           }
00109           throwNoCaseForSwitchValue(ss.str());
00110         }
00111       }
00112     }
00113 
00114     virtual void writeCfi_(std::ostream & os,
00115                           bool & startWithComma,
00116                           int indentation,
00117                           bool & wroteSomething) const {
00118       switch_.writeCfi(os, startWithComma, indentation, wroteSomething);
00119 
00120       typename CaseMap::const_iterator selectedCase = cases_.find(switch_.getDefaultValue());
00121       if (selectedCase != cases_.end()) {
00122         selectedCase->second->writeCfi(os, startWithComma, indentation, wroteSomething);
00123       }
00124     }
00125 
00126     virtual void print_(std::ostream & os,
00127                         bool optional,
00128                         bool writeToCfi,
00129                         DocFormatHelper & dfh) {
00130       printBase(os, optional, writeToCfi, dfh, switch_.label(), switch_.isTracked(), parameterTypeEnumToString(switch_.type()));
00131     }
00132 
00133     virtual void printNestedContent_(std::ostream & os,
00134                                      bool optional,
00135                                      DocFormatHelper & dfh) {
00136 
00137       DocFormatHelper new_dfh(dfh);
00138       printNestedContentBase(os, dfh, new_dfh, switch_.label());
00139 
00140       switch_.print(os, optional, true, new_dfh);
00141       for_all(cases_, boost::bind(&ParameterSwitchBase::printCaseT<T>,
00142                                   _1,
00143                                   boost::ref(os),
00144                                   optional,
00145                                   boost::ref(new_dfh),
00146                                   boost::cref(switch_.label())));
00147 
00148       new_dfh.setPass(1);
00149       new_dfh.setCounter(0);
00150 
00151       new_dfh.indent(os);
00152       os << "switch:\n";
00153       switch_.print(os, optional, true, new_dfh);
00154       for_all(cases_, boost::bind(&ParameterSwitchBase::printCaseT<T>,
00155                                   _1,
00156                                   boost::ref(os),
00157                                   optional,
00158                                   boost::ref(new_dfh),
00159                                   boost::cref(switch_.label())));
00160 
00161       new_dfh.setPass(2);
00162       new_dfh.setCounter(0);
00163 
00164       switch_.printNestedContent(os, optional, new_dfh);
00165       for_all(cases_, boost::bind(&ParameterSwitchBase::printCaseT<T>,
00166                                   _1,
00167                                   boost::ref(os),
00168                                   optional,
00169                                   boost::ref(new_dfh),
00170                                   boost::cref(switch_.label())));
00171     }
00172 
00173     virtual bool exists_(ParameterSet const& pset) const { return switch_.exists(pset); }
00174 
00175     static void checkCaseLabels(std::pair<T, edm::value_ptr<ParameterDescriptionNode> > const& thePair,
00176                                 std::set<std::string> & labels,
00177                                 std::set<ParameterTypes> & parameterTypes,
00178                                 std::set<ParameterTypes> & wildcardTypes) {
00179       thePair.second->checkAndGetLabelsAndTypes(labels, parameterTypes, wildcardTypes);
00180     }
00181 
00182     ParameterDescription<T> switch_;
00183     CaseMap cases_;
00184   };
00185 }
00186 #endif