CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 #ifndef FWCore_ParameterSet_ParameterSetDescription_h
00002 #define FWCore_ParameterSet_ParameterSetDescription_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     ParameterSet
00006 // Class  :     ParameterSetDescription
00007 // 
00026 //
00027 // Original Author:  Chris Jones
00028 //         Created:  Tue Jul 31 15:18:40 EDT 2007
00029 //
00030 
00031 #include "FWCore/Utilities/interface/value_ptr.h"
00032 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
00033 
00034 #include <vector>
00035 #include <set>
00036 #include <string>
00037 #include <memory>
00038 #include <iosfwd>
00039 
00040 namespace edm {
00041 
00042   class ParameterSet;
00043   class ParameterDescriptionBase;
00044   class ParameterWildcardBase;
00045   class ParameterDescriptionNode;
00046   template <typename T> class ParameterDescription;
00047   template <typename T> class ParameterDescriptionCases;
00048   class DocFormatHelper;
00049 
00050   class ParameterSetDescription {
00051   public:
00052     class SetDescriptionEntry {
00053     public:
00054       bool optional() const { return optional_; }
00055       bool writeToCfi() const { return writeToCfi_; }
00056       edm::value_ptr<ParameterDescriptionNode> const& node() const { return node_; }
00057       void setOptional(bool value) { optional_ = value; }
00058       void setWriteToCfi(bool value) { writeToCfi_ = value; }
00059       void setNode(std::auto_ptr<ParameterDescriptionNode> node) { node_ = node; }
00060     private:
00061       bool optional_;
00062       bool writeToCfi_;
00063       edm::value_ptr<ParameterDescriptionNode> node_;
00064     };
00065 
00066     typedef std::vector<SetDescriptionEntry> SetDescriptionEntries;
00067     typedef SetDescriptionEntries::const_iterator const_iterator;
00068 
00069     ParameterSetDescription();
00070     virtual ~ParameterSetDescription();
00071 
00072     std::string const& comment() const { return comment_; }
00073     void setComment(std::string const & value);
00074     void setComment(char const* value);
00075 
00077     void setAllowAnything();
00078       
00079     // This is set only for parameterizables which have not set their descriptions.
00080     // This should only be called to allow backwards compatibility.
00081     void setUnknown();
00082 
00083     // ***** In these next 8 functions named "add", T is the parameter type ******
00084     // Exceptions: For parameters of type ParameterSet, T should be a
00085     // ParameterSetDescription instead of a ParameterSet.  And do not
00086     // use these next 8 functions for parameters of type vector<ParameterSet>
00087 
00088     template<typename T, typename U>
00089     ParameterDescriptionBase * add(U const& iLabel, T const& value) {
00090       return add<T, U>(iLabel, value, true, false, true);
00091     }
00092 
00093     template<typename T, typename U>
00094     ParameterDescriptionBase * addUntracked(U const& iLabel, T const& value) {
00095       return add<T, U>(iLabel, value, false, false, true);
00096     }
00097 
00098     template<typename T, typename U>
00099     ParameterDescriptionBase * addOptional(U const& iLabel, T const& value) {
00100       return add<T, U>(iLabel, value, true, true, true);
00101     }
00102 
00103     template<typename T, typename U>
00104     ParameterDescriptionBase * addOptionalUntracked(U const& iLabel, T const& value) {
00105       return add<T, U>(iLabel, value, false, true, true);
00106     }
00107 
00108     // For the next 4 functions, there is no default so they will not get injected
00109     // during validation if missing and they will not get written into cfi files.
00110 
00111     template<typename T, typename U>
00112     ParameterDescriptionBase * add(U const& iLabel) {
00113       return add<T, U>(iLabel, true, false, false);
00114     }
00115 
00116     template<typename T, typename U>
00117     ParameterDescriptionBase * addUntracked(U const& iLabel) {
00118       return add<T, U>(iLabel, false, false, false);
00119     }
00120 
00121     template<typename T, typename U>
00122     ParameterDescriptionBase * addOptional(U const& iLabel) {
00123       return add<T, U>(iLabel, true, true, false);
00124     }
00125 
00126     template<typename T, typename U>
00127     ParameterDescriptionBase * addOptionalUntracked(U const& iLabel) {
00128       return add<T, U>(iLabel, false, true, false);
00129     }
00130 
00131     // ***** Use these 8 functions for parameters of type vector<ParameterSet> *****
00132     // When a vector<ParameterSet> appears in a configuration, all of its
00133     // elements will be validated using the description in the argument named
00134     // "validator" below.  The argument named "defaults" is used when the
00135     // a vector<ParameterSet> is required to be in the configuration and
00136     // is absent.  Note that these default ParameterSet's will be validated
00137     // as if they had appeared in the configuration so they must be consistent
00138     // with the description and missing parameters that have defaults in
00139     // in the description will be inserted during validation.  These defaults
00140     // are also used when writing cfi files.
00141 
00142     template<typename U>
00143     ParameterDescriptionBase * addVPSet(U const& iLabel,
00144                                         ParameterSetDescription const& validator,
00145                                         std::vector<ParameterSet> const& defaults) {
00146       return addVPSet<U>(iLabel, validator, defaults, true, false, true);
00147     }
00148 
00149     template<typename U>
00150     ParameterDescriptionBase * addVPSetUntracked(U const& iLabel,
00151                                         ParameterSetDescription const& validator,
00152                                         std::vector<ParameterSet> const& defaults) {
00153       return addVPSet<U>(iLabel, validator, defaults, false, false, true);
00154     }
00155 
00156     template<typename U>
00157     ParameterDescriptionBase * addVPSetOptional(U const& iLabel,
00158                                         ParameterSetDescription const& validator,
00159                                         std::vector<ParameterSet> const& defaults) {
00160       return addVPSet<U>(iLabel, validator, defaults, true, true, true);
00161     }
00162 
00163     template<typename U>
00164     ParameterDescriptionBase * addVPSetOptionalUntracked(U const& iLabel,
00165                                         ParameterSetDescription const& validator,
00166                                         std::vector<ParameterSet> const& defaults) {
00167       return addVPSet<U>(iLabel, validator, defaults, false, true, true);
00168     }
00169 
00170     template<typename U>
00171     ParameterDescriptionBase * addVPSet(U const& iLabel,
00172                                         ParameterSetDescription const& validator) {
00173       return addVPSet<U>(iLabel, validator, true, false, false);
00174     }
00175 
00176     template<typename U>
00177     ParameterDescriptionBase * addVPSetUntracked(U const& iLabel,
00178                                         ParameterSetDescription const& validator) {
00179       return addVPSet<U>(iLabel, validator, false, false, false);
00180     }
00181 
00182     template<typename U>
00183     ParameterDescriptionBase * addVPSetOptional(U const& iLabel,
00184                                         ParameterSetDescription const& validator) {
00185       return addVPSet<U>(iLabel, validator, true, true, false);
00186     }
00187 
00188     template<typename U>
00189     ParameterDescriptionBase * addVPSetOptionalUntracked(U const& iLabel,
00190                                         ParameterSetDescription const& validator) {
00191       return addVPSet<U>(iLabel, validator, false, true, false);
00192     }
00193 
00194     // ********* Wildcards *********
00195 
00196     template<typename T, typename U>
00197     ParameterWildcardBase * addWildcard(U const& pattern) {
00198       return addWildcard<T, U>(pattern, true);
00199     }
00200 
00201     template<typename T, typename U>
00202     ParameterWildcardBase * addWildcardUntracked(U const& pattern) {
00203       return addWildcard<T, U>(pattern, false);
00204     }
00205 
00206     // ********* Used to insert generic nodes of any type ************
00207 
00208     ParameterDescriptionNode* addNode(ParameterDescriptionNode const& node);
00209     ParameterDescriptionNode* addNode(std::auto_ptr<ParameterDescriptionNode> node);
00210     ParameterDescriptionNode* addOptionalNode(ParameterDescriptionNode const& node, bool writeToCfi);
00211     ParameterDescriptionNode* addOptionalNode(std::auto_ptr<ParameterDescriptionNode> node, bool writeToCfi);
00212 
00213     // ********* Switches ************
00214     // ifValue will only work with type T as a bool, int, or string.
00215     // T holds the value of the switch variable.
00216     // If you try using any other type, then it will not compile.
00217     template <typename T>
00218     ParameterDescriptionNode*
00219     ifValue(ParameterDescription<T> const& switchParameter,
00220             std::auto_ptr<ParameterDescriptionCases<T> > cases) {
00221       return ifValue<T>(switchParameter, cases, false, true);
00222     }
00223 
00224     template <typename T>
00225     ParameterDescriptionNode*
00226     ifValueOptional(ParameterDescription<T> const& switchParameter,
00227                     std::auto_ptr<ParameterDescriptionCases<T> > cases,
00228                     bool writeToCfi) {
00229       return ifValue<T>(switchParameter, cases, true, writeToCfi);
00230     }
00231 
00232     // ********* if exists ************
00233     ParameterDescriptionNode*
00234     ifExists(ParameterDescriptionNode const& node1,
00235              ParameterDescriptionNode const& node2) {
00236       return ifExists(node1, node2, false, true);
00237     }
00238 
00239     ParameterDescriptionNode*
00240     ifExistsOptional(ParameterDescriptionNode const& node1,
00241                           ParameterDescriptionNode const& node2,
00242                           bool writeToCfi) {
00243       return ifExists(node1, node2, true, writeToCfi);
00244     }
00245 
00246     // ********* for parameters that are a list of allowed labels *********
00247     template<typename T, typename U>
00248     ParameterDescriptionNode*
00249     labelsFrom(U const& iLabel) {
00250       return labelsFrom<T,U>(iLabel, true, false, true);
00251     }
00252 
00253     template<typename T, typename U>
00254     ParameterDescriptionNode*
00255     labelsFromUntracked(U const& iLabel) {
00256       return labelsFrom<T,U>(iLabel, false, false, true);
00257     }
00258 
00259     template<typename T, typename U>
00260     ParameterDescriptionNode*
00261     labelsFromOptional(U const& iLabel, bool writeToCfi) {
00262       return labelsFrom<T,U>(iLabel, true, true, writeToCfi);
00263     }
00264 
00265     template<typename T, typename U>
00266     ParameterDescriptionNode*
00267     labelsFromOptionalUntracked(U const& iLabel, bool writeToCfi) {
00268       return labelsFrom<T,U>(iLabel, false, true, writeToCfi);
00269     }
00270 
00271     // These next four functions only work when the template
00272     // parameters are:
00273     // T = ParameterSetDescription and V = ParameterSetDescription
00274     // or
00275     // T = vector<ParameterSet> and V = ParameterSetDescription
00276     // In either case U can be either a string or char*
00277     // Note the U and V can be determined from the arguments, but
00278     // T must be explicitly specified by the calling function.
00279     template<typename T, typename U, typename V>
00280     ParameterDescriptionNode*
00281     labelsFrom(U const& iLabel, V const& desc) {
00282       return labelsFrom<T,U,V>(iLabel, true, false, true, desc);
00283     }
00284 
00285     template<typename T, typename U, typename V>
00286     ParameterDescriptionNode*
00287     labelsFromUntracked(U const& iLabel, V const& desc) {
00288       return labelsFrom<T,U,V>(iLabel, false, false, true, desc);
00289     }
00290 
00291     template<typename T, typename U, typename V>
00292     ParameterDescriptionNode*
00293     labelsFromOptional(U const& iLabel, bool writeToCfi, V const& desc) {
00294       return labelsFrom<T,U,V>(iLabel, true, true, writeToCfi, desc);
00295     }
00296 
00297     template<typename T, typename U, typename V>
00298     ParameterDescriptionNode*
00299     labelsFromOptionalUntracked(U const& iLabel, bool writeToCfi, V const& desc) {
00300       return labelsFrom<T,U,V>(iLabel, false, true, writeToCfi, desc);
00301     }
00302 
00303     bool anythingAllowed() const { return anythingAllowed_; }
00304     bool isUnknown() const { return unknown_; }
00305 
00306     const_iterator begin() const {
00307       return entries_.begin();
00308     }
00309 
00310     const_iterator end() const {
00311       return entries_.end();
00312     }
00313 
00314     // Better performance if space is reserved for the number of
00315     // top level parameters before any are added.
00316     void reserve(SetDescriptionEntries::size_type n) {
00317       entries_.reserve(n);
00318     }
00319 
00320     void validate(ParameterSet & pset) const;
00321 
00322     void writeCfi(std::ostream & os, bool startWithComma, int indentation) const; 
00323 
00324     void print(std::ostream & os, DocFormatHelper & dfh) const; 
00325 
00326     bool isLabelUnused(std::string const& label) const;
00327 
00328   private:
00329 
00330     template<typename T, typename U>
00331     ParameterDescriptionBase * add(U const& iLabel, T const& value,
00332                                    bool isTracked, bool isOptional, bool writeToCfi);
00333 
00334     template<typename T, typename U>
00335     ParameterDescriptionBase * add(U const& iLabel,
00336                                    bool isTracked, bool isOptional, bool writeToCfi);
00337 
00338     template<typename U>
00339     ParameterDescriptionBase * addVPSet(U const& iLabel,
00340                                         ParameterSetDescription const& validator,
00341                                         std::vector<ParameterSet> const& defaults,
00342                                         bool isTracked, bool isOptional, bool writeToCfi);
00343 
00344     template<typename U>
00345     ParameterDescriptionBase * addVPSet(U const& iLabel,
00346                                         ParameterSetDescription const& validator,
00347                                         bool isTracked, bool isOptional, bool writeToCfi);
00348 
00349     template<typename T, typename U>
00350     ParameterWildcardBase * addWildcard(U const& pattern, bool isTracked);
00351 
00352     ParameterDescriptionNode* addNode(std::auto_ptr<ParameterDescriptionNode> node, bool optional, bool writeToCfi);
00353 
00354     template <typename T>
00355     ParameterDescriptionNode*
00356     ifValue(ParameterDescription<T> const& switchParameter,
00357             std::auto_ptr<ParameterDescriptionCases<T> > cases,
00358             bool optional, bool writeToCfi);
00359 
00360     ParameterDescriptionNode*
00361     ifExists(ParameterDescriptionNode const& node1,
00362              ParameterDescriptionNode const& node2,
00363              bool optional, bool writeToCfi);
00364 
00365     template<typename T, typename U>
00366     ParameterDescriptionNode*
00367     labelsFrom(U const& iLabel, bool isTracked, bool optional, bool writeToCfi);
00368 
00369     template<typename T, typename U, typename V>
00370     ParameterDescriptionNode*
00371     labelsFrom(U const& iLabel, bool isTracked, bool optional, bool writeToCfi, V const& desc);
00372 
00373     static
00374     void
00375     validateNode(SetDescriptionEntry const& entry,
00376                  ParameterSet & pset,
00377                  std::set<std::string> & validatedNames);
00378 
00379     static void 
00380     throwIllegalParameters(std::vector<std::string> const& parameterNames,
00381                            std::set<std::string> const& validatedNames);
00382 
00383     static void
00384     writeNode(SetDescriptionEntry const& entry,
00385               std::ostream & os,
00386               bool & startWithComma,
00387               int indentation,
00388               bool & wroteSomething);
00389 
00390     static void
00391     printNode(SetDescriptionEntry const& entry,
00392               std::ostream & os,
00393               DocFormatHelper & dfh);
00394 
00395     void throwIfLabelsAlreadyUsed(std::set<std::string> const& nodeLabels);
00396     void throwIfWildcardCollision(std::set<ParameterTypes> const& nodeParameterTypes,
00397                                   std::set<ParameterTypes> const& nodeWildcardTypes);
00398 
00399     bool anythingAllowed_;
00400     bool unknown_;
00401     SetDescriptionEntries entries_;
00402 
00403     std::set<std::string> usedLabels_;
00404     std::set<ParameterTypes> typesUsedForParameters_;
00405     std::set<ParameterTypes> typesUsedForWildcards_;    
00406 
00407     std::string comment_;
00408   };
00409 }
00410 
00411 #include "FWCore/ParameterSet/interface/ParameterWildcard.h"
00412 #include "FWCore/ParameterSet/interface/ParameterSwitch.h"
00413 #include "FWCore/ParameterSet/interface/AllowedLabelsDescription.h"
00414 
00415 namespace edm {
00416 
00417   template<typename T, typename U>
00418   ParameterDescriptionBase*
00419   ParameterSetDescription::add(U const& iLabel, T const& value, bool isTracked, bool isOptional, bool writeToCfi) {
00420 
00421     std::auto_ptr<ParameterDescriptionBase> pdbase(new ParameterDescription<T>(iLabel, value, isTracked));
00422     ParameterDescriptionBase* pdReturn = pdbase.get();
00423     std::auto_ptr<ParameterDescriptionNode> node(pdbase);
00424     addNode(node, isOptional, writeToCfi);
00425 
00426     return pdReturn;
00427   }
00428 
00429   template<typename T, typename U>
00430   ParameterDescriptionBase*
00431   ParameterSetDescription::add(U const& iLabel, bool isTracked, bool isOptional, bool writeToCfi) {
00432 
00433     std::auto_ptr<ParameterDescriptionBase> pdbase(new ParameterDescription<T>(iLabel, isTracked));
00434     ParameterDescriptionBase* pdReturn = pdbase.get();
00435     std::auto_ptr<ParameterDescriptionNode> node(pdbase);
00436     addNode(node, isOptional, writeToCfi);
00437 
00438     return pdReturn;
00439   }
00440 
00441   template<typename U>
00442   ParameterDescriptionBase *
00443   ParameterSetDescription::addVPSet(U const& iLabel,
00444                                     ParameterSetDescription const& validator,
00445                                     std::vector<ParameterSet> const& defaults,
00446                                     bool isTracked, bool isOptional, bool writeToCfi) {
00447     std::auto_ptr<ParameterDescriptionBase> pdbase(
00448         new ParameterDescription<std::vector<ParameterSet> >(iLabel, validator, isTracked, defaults));
00449 
00450     ParameterDescriptionBase* pdReturn = pdbase.get();
00451     std::auto_ptr<ParameterDescriptionNode> node(pdbase);
00452     addNode(node, isOptional, writeToCfi);
00453 
00454     return pdReturn;
00455   }
00456 
00457   template<typename U>
00458   ParameterDescriptionBase *
00459   ParameterSetDescription::addVPSet(U const& iLabel,
00460                                     ParameterSetDescription const& validator,
00461                                     bool isTracked, bool isOptional, bool writeToCfi) {
00462     std::auto_ptr<ParameterDescriptionBase> pdbase(
00463         new ParameterDescription<std::vector<ParameterSet> >(iLabel, validator, isTracked));
00464 
00465     ParameterDescriptionBase* pdReturn = pdbase.get();
00466     std::auto_ptr<ParameterDescriptionNode> node(pdbase);
00467     addNode(node, isOptional, writeToCfi);
00468 
00469     return pdReturn;
00470   }
00471 
00472   template<typename T, typename U>
00473   ParameterWildcardBase*
00474   ParameterSetDescription::addWildcard(U const& pattern, bool isTracked) {
00475     
00476     std::auto_ptr<ParameterWildcardBase> pdbase(new ParameterWildcard<T>(pattern, RequireZeroOrMore, isTracked));
00477     ParameterWildcardBase * pdReturn = pdbase.get();
00478     std::auto_ptr<ParameterDescriptionNode> node(pdbase);
00479     addNode(node, true, false);
00480 
00481     return pdReturn;
00482   }
00483 
00484   template <typename T>
00485   ParameterDescriptionNode*
00486   ParameterSetDescription::ifValue(ParameterDescription<T> const& switchParameter,
00487           std::auto_ptr<ParameterDescriptionCases<T> > cases,
00488           bool optional, bool writeToCfi) {
00489     std::auto_ptr<ParameterDescriptionNode> pdswitch(new ParameterSwitch<T>(switchParameter, cases));
00490     return addNode(pdswitch, optional, writeToCfi);
00491   }
00492 
00493   template<typename T, typename U>
00494   ParameterDescriptionNode*
00495   ParameterSetDescription::labelsFrom(U const& iLabel, bool isTracked, bool optional, bool writeToCfi) {
00496     std::auto_ptr<ParameterDescriptionNode> pd(new AllowedLabelsDescription<T>(iLabel, isTracked));
00497     return addNode(pd, optional, writeToCfi);
00498   }
00499 
00500   template<typename T, typename U, typename V>
00501   ParameterDescriptionNode*
00502   ParameterSetDescription::labelsFrom(U const& iLabel, bool isTracked, bool optional, bool writeToCfi, V const& desc) {
00503     std::auto_ptr<ParameterDescriptionNode> pd(new AllowedLabelsDescription<T>(iLabel, desc, isTracked));
00504     return addNode(pd, optional, writeToCfi);
00505   }
00506 }
00507 
00508 #endif