Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:28:51

0001 #ifndef FWCore_ParameterSet_ParameterSetDescription_h
0002 #define FWCore_ParameterSet_ParameterSetDescription_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     ParameterSet
0006 // Class  :     ParameterSetDescription
0007 //
0008 /**\class ParameterSetDescription ParameterSetDescription.h FWCore/ParameterSet/interface/ParameterSetDescription.h
0009 
0010  Description: Used to describe the allowed values in a ParameterSet
0011 
0012  Usage:
0013     <usage>
0014 
0015 
0016  Implementation Details:
0017 
0018     Note that there are some comments in the file ParameterDescriptionNode.h
0019     that might be useful for someone attempting to understand the implementation
0020     details.  This class holds a container full of nodes.  One node can represent
0021     a description of a single parameter or some logical restriction on the
0022     combinations of parameters allowed in a ParameterSet.  Often these logical
0023     restrictions are implemented by the nodes themselves containing a tree
0024     structure of other nodes.
0025 */
0026 //
0027 // Original Author:  Chris Jones
0028 //         Created:  Tue Jul 31 15:18:40 EDT 2007
0029 //
0030 
0031 #include "FWCore/Utilities/interface/value_ptr.h"
0032 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
0033 
0034 #include <vector>
0035 #include <set>
0036 #include <string>
0037 #include <memory>
0038 #include <iosfwd>
0039 
0040 namespace edm {
0041 
0042   class ParameterSet;
0043   class ParameterDescriptionBase;
0044   class ParameterWildcardBase;
0045   class ParameterDescriptionNode;
0046   template <typename T>
0047   class ParameterDescription;
0048   template <typename T>
0049   class ParameterDescriptionCases;
0050   class DocFormatHelper;
0051 
0052   class ParameterSetDescription {
0053   public:
0054     class SetDescriptionEntry {
0055     public:
0056       bool optional() const { return optional_; }
0057       bool writeToCfi() const { return writeToCfi_; }
0058       edm::value_ptr<ParameterDescriptionNode> const& node() const { return node_; }
0059       void setOptional(bool value) { optional_ = value; }
0060       void setWriteToCfi(bool value) { writeToCfi_ = value; }
0061       ParameterDescriptionNode* setNode(std::unique_ptr<ParameterDescriptionNode> node) {
0062         node_ = std::move(node);
0063         return node_.operator->();
0064       }
0065 
0066     private:
0067       bool optional_;
0068       bool writeToCfi_;
0069       edm::value_ptr<ParameterDescriptionNode> node_;
0070     };
0071 
0072     typedef std::vector<SetDescriptionEntry> SetDescriptionEntries;
0073     typedef SetDescriptionEntries::const_iterator const_iterator;
0074 
0075     ParameterSetDescription();
0076     virtual ~ParameterSetDescription();
0077 
0078     std::string const& comment() const { return comment_; }
0079     void setComment(std::string const& value);
0080     void setComment(char const* value);
0081 
0082     ///allow any parameter label/value pairs
0083     void setAllowAnything();
0084 
0085     // This is set only for parameterizables which have not set their descriptions.
0086     // This should only be called to allow backwards compatibility.
0087     void setUnknown();
0088 
0089     // ***** In these next 8 functions named "add", T is the parameter type ******
0090     // Exceptions: For parameters of type ParameterSet, T should be a
0091     // ParameterSetDescription instead of a ParameterSet.  And do not
0092     // use these next 8 functions for parameters of type vector<ParameterSet>
0093 
0094     template <typename T, typename U>
0095     ParameterDescriptionBase* add(U const& iLabel, T const& value) {
0096       return add<T, U>(iLabel, value, true, false, true);
0097     }
0098 
0099     template <typename T, typename U>
0100     ParameterDescriptionBase* addUntracked(U const& iLabel, T const& value) {
0101       return add<T, U>(iLabel, value, false, false, true);
0102     }
0103 
0104     template <typename T, typename U>
0105     ParameterDescriptionBase* addOptional(U const& iLabel, T const& value) {
0106       return add<T, U>(iLabel, value, true, true, true);
0107     }
0108 
0109     template <typename T, typename U>
0110     ParameterDescriptionBase* addOptionalUntracked(U const& iLabel, T const& value) {
0111       return add<T, U>(iLabel, value, false, true, true);
0112     }
0113 
0114     // For the next 4 functions, there is no default so they will not get injected
0115     // during validation if missing and they will not get written into cfi files.
0116 
0117     template <typename T, typename U>
0118     ParameterDescriptionBase* add(U const& iLabel) {
0119       return add<T, U>(iLabel, true, false, true);
0120     }
0121 
0122     template <typename T, typename U>
0123     ParameterDescriptionBase* addUntracked(U const& iLabel) {
0124       return add<T, U>(iLabel, false, false, true);
0125     }
0126 
0127     template <typename T, typename U>
0128     ParameterDescriptionBase* addOptional(U const& iLabel) {
0129       return add<T, U>(iLabel, true, true, true);
0130     }
0131 
0132     template <typename T, typename U>
0133     ParameterDescriptionBase* addOptionalUntracked(U const& iLabel) {
0134       return add<T, U>(iLabel, false, true, true);
0135     }
0136 
0137     // ***** Use these 8 functions for parameters of type vector<ParameterSet> *****
0138     // When a vector<ParameterSet> appears in a configuration, all of its
0139     // elements will be validated using the description in the argument named
0140     // "validator" below.  The argument named "defaults" is used when the
0141     // a vector<ParameterSet> is required to be in the configuration and
0142     // is absent.  Note that these default ParameterSet's will be validated
0143     // as if they had appeared in the configuration so they must be consistent
0144     // with the description and missing parameters that have defaults in
0145     // in the description will be inserted during validation.  These defaults
0146     // are also used when writing cfi files.
0147 
0148     template <typename U>
0149     ParameterDescriptionBase* addVPSet(U const& iLabel,
0150                                        ParameterSetDescription const& validator,
0151                                        std::vector<ParameterSet> const& defaults) {
0152       return addVPSet<U>(iLabel, validator, defaults, true, false, true);
0153     }
0154 
0155     template <typename U>
0156     ParameterDescriptionBase* addVPSetUntracked(U const& iLabel,
0157                                                 ParameterSetDescription const& validator,
0158                                                 std::vector<ParameterSet> const& defaults) {
0159       return addVPSet<U>(iLabel, validator, defaults, false, false, true);
0160     }
0161 
0162     template <typename U>
0163     ParameterDescriptionBase* addVPSetOptional(U const& iLabel,
0164                                                ParameterSetDescription const& validator,
0165                                                std::vector<ParameterSet> const& defaults) {
0166       return addVPSet<U>(iLabel, validator, defaults, true, true, true);
0167     }
0168 
0169     template <typename U>
0170     ParameterDescriptionBase* addVPSetOptionalUntracked(U const& iLabel,
0171                                                         ParameterSetDescription const& validator,
0172                                                         std::vector<ParameterSet> const& defaults) {
0173       return addVPSet<U>(iLabel, validator, defaults, false, true, true);
0174     }
0175 
0176     template <typename U>
0177     ParameterDescriptionBase* addVPSet(U const& iLabel, ParameterSetDescription const& validator) {
0178       return addVPSet<U>(iLabel, validator, true, false, true);
0179     }
0180 
0181     template <typename U>
0182     ParameterDescriptionBase* addVPSetUntracked(U const& iLabel, ParameterSetDescription const& validator) {
0183       return addVPSet<U>(iLabel, validator, false, false, true);
0184     }
0185 
0186     template <typename U>
0187     ParameterDescriptionBase* addVPSetOptional(U const& iLabel, ParameterSetDescription const& validator) {
0188       return addVPSet<U>(iLabel, validator, true, true, true);
0189     }
0190 
0191     template <typename U>
0192     ParameterDescriptionBase* addVPSetOptionalUntracked(U const& iLabel, ParameterSetDescription const& validator) {
0193       return addVPSet<U>(iLabel, validator, false, true, true);
0194     }
0195 
0196     // ********* Wildcards *********
0197 
0198     template <typename T, typename U>
0199     ParameterWildcardBase* addWildcard(U const& pattern) {
0200       return addWildcard<T, U>(pattern, true);
0201     }
0202 
0203     template <typename T, typename U>
0204     ParameterWildcardBase* addWildcardUntracked(U const& pattern) {
0205       return addWildcard<T, U>(pattern, false);
0206     }
0207 
0208     // ********* Used to insert generic nodes of any type ************
0209 
0210     ParameterDescriptionNode* addNode(ParameterDescriptionNode const& node);
0211     ParameterDescriptionNode* addNode(std::unique_ptr<ParameterDescriptionNode> node);
0212     ParameterDescriptionNode* addOptionalNode(ParameterDescriptionNode const& node, bool writeToCfi);
0213     ParameterDescriptionNode* addOptionalNode(std::unique_ptr<ParameterDescriptionNode> node, bool writeToCfi);
0214 
0215     // ********* Switches ************
0216     // ifValue will only work with type T as a bool, int, or string.
0217     // T holds the value of the switch variable.
0218     // If you try using any other type, then it will not compile.
0219     template <typename T>
0220     ParameterDescriptionNode* ifValue(ParameterDescription<T> const& switchParameter,
0221                                       std::unique_ptr<ParameterDescriptionCases<T>> cases) {
0222       return ifValue<T>(switchParameter, std::move(cases), false, true);
0223     }
0224 
0225     template <typename T>
0226     ParameterDescriptionNode* ifValueOptional(ParameterDescription<T> const& switchParameter,
0227                                               std::unique_ptr<ParameterDescriptionCases<T>> cases,
0228                                               bool writeToCfi) {
0229       return ifValue<T>(switchParameter, std::move(cases), true, writeToCfi);
0230     }
0231 
0232     // ********* if exists ************
0233     ParameterDescriptionNode* ifExists(ParameterDescriptionNode const& node1, ParameterDescriptionNode const& node2) {
0234       return ifExists(node1, node2, false, true);
0235     }
0236 
0237     ParameterDescriptionNode* ifExistsOptional(ParameterDescriptionNode const& node1,
0238                                                ParameterDescriptionNode const& node2,
0239                                                bool writeToCfi) {
0240       return ifExists(node1, node2, true, writeToCfi);
0241     }
0242 
0243     // ********* for parameters that are a list of allowed labels *********
0244     template <typename T, typename U>
0245     ParameterDescriptionNode* labelsFrom(U const& iLabel) {
0246       return labelsFrom<T, U>(iLabel, true, false, true);
0247     }
0248 
0249     template <typename T, typename U>
0250     ParameterDescriptionNode* labelsFromUntracked(U const& iLabel) {
0251       return labelsFrom<T, U>(iLabel, false, false, true);
0252     }
0253 
0254     template <typename T, typename U>
0255     ParameterDescriptionNode* labelsFromOptional(U const& iLabel, bool writeToCfi) {
0256       return labelsFrom<T, U>(iLabel, true, true, writeToCfi);
0257     }
0258 
0259     template <typename T, typename U>
0260     ParameterDescriptionNode* labelsFromOptionalUntracked(U const& iLabel, bool writeToCfi) {
0261       return labelsFrom<T, U>(iLabel, false, true, writeToCfi);
0262     }
0263 
0264     // These next four functions only work when the template
0265     // parameters are:
0266     // T = ParameterSetDescription and V = ParameterSetDescription
0267     // or
0268     // T = vector<ParameterSet> and V = ParameterSetDescription
0269     // In either case U can be either a string or char*
0270     // Note the U and V can be determined from the arguments, but
0271     // T must be explicitly specified by the calling function.
0272     template <typename T, typename U, typename V>
0273     ParameterDescriptionNode* labelsFrom(U const& iLabel, V const& desc) {
0274       return labelsFrom<T, U, V>(iLabel, true, false, true, desc);
0275     }
0276 
0277     template <typename T, typename U, typename V>
0278     ParameterDescriptionNode* labelsFromUntracked(U const& iLabel, V const& desc) {
0279       return labelsFrom<T, U, V>(iLabel, false, false, true, desc);
0280     }
0281 
0282     template <typename T, typename U, typename V>
0283     ParameterDescriptionNode* labelsFromOptional(U const& iLabel, bool writeToCfi, V const& desc) {
0284       return labelsFrom<T, U, V>(iLabel, true, true, writeToCfi, desc);
0285     }
0286 
0287     template <typename T, typename U, typename V>
0288     ParameterDescriptionNode* labelsFromOptionalUntracked(U const& iLabel, bool writeToCfi, V const& desc) {
0289       return labelsFrom<T, U, V>(iLabel, false, true, writeToCfi, desc);
0290     }
0291 
0292     bool anythingAllowed() const { return anythingAllowed_; }
0293     bool isUnknown() const { return unknown_; }
0294 
0295     const_iterator begin() const { return entries_.begin(); }
0296 
0297     const_iterator end() const { return entries_.end(); }
0298 
0299     // Better performance if space is reserved for the number of
0300     // top level parameters before any are added.
0301     void reserve(SetDescriptionEntries::size_type n) { entries_.reserve(n); }
0302 
0303     void validate(ParameterSet& pset) const;
0304 
0305     void writeCfi(std::ostream& os, bool startWithComma, int indentation) const;
0306 
0307     void print(std::ostream& os, DocFormatHelper& dfh) const;
0308 
0309     bool isLabelUnused(std::string const& label) const;
0310 
0311   private:
0312     template <typename T, typename U>
0313     ParameterDescriptionBase* add(U const& iLabel, T const& value, bool isTracked, bool isOptional, bool writeToCfi);
0314 
0315     template <typename T, typename U>
0316     ParameterDescriptionBase* add(U const& iLabel, bool isTracked, bool isOptional, bool writeToCfi);
0317 
0318     template <typename U>
0319     ParameterDescriptionBase* addVPSet(U const& iLabel,
0320                                        ParameterSetDescription const& validator,
0321                                        std::vector<ParameterSet> const& defaults,
0322                                        bool isTracked,
0323                                        bool isOptional,
0324                                        bool writeToCfi);
0325 
0326     template <typename U>
0327     ParameterDescriptionBase* addVPSet(
0328         U const& iLabel, ParameterSetDescription const& validator, bool isTracked, bool isOptional, bool writeToCfi);
0329 
0330     template <typename T, typename U>
0331     ParameterWildcardBase* addWildcard(U const& pattern, bool isTracked);
0332 
0333     ParameterDescriptionNode* addNode(std::unique_ptr<ParameterDescriptionNode> node, bool optional, bool writeToCfi);
0334 
0335     template <typename T>
0336     ParameterDescriptionNode* ifValue(ParameterDescription<T> const& switchParameter,
0337                                       std::unique_ptr<ParameterDescriptionCases<T>> cases,
0338                                       bool optional,
0339                                       bool writeToCfi);
0340 
0341     ParameterDescriptionNode* ifExists(ParameterDescriptionNode const& node1,
0342                                        ParameterDescriptionNode const& node2,
0343                                        bool optional,
0344                                        bool writeToCfi);
0345 
0346     template <typename T, typename U>
0347     ParameterDescriptionNode* labelsFrom(U const& iLabel, bool isTracked, bool optional, bool writeToCfi);
0348 
0349     template <typename T, typename U, typename V>
0350     ParameterDescriptionNode* labelsFrom(U const& iLabel, bool isTracked, bool optional, bool writeToCfi, V const& desc);
0351 
0352     static void validateNode(SetDescriptionEntry const& entry,
0353                              ParameterSet& pset,
0354                              std::set<std::string>& validatedNames);
0355 
0356     static void throwIllegalParameters(std::vector<std::string> const& parameterNames,
0357                                        std::set<std::string> const& validatedNames);
0358 
0359     static void writeNode(SetDescriptionEntry const& entry,
0360                           std::ostream& os,
0361                           bool& startWithComma,
0362                           int indentation,
0363                           bool& wroteSomething);
0364 
0365     static void printNode(SetDescriptionEntry const& entry, std::ostream& os, DocFormatHelper& dfh);
0366 
0367     void throwIfLabelsAlreadyUsed(std::set<std::string> const& nodeLabels);
0368     void throwIfWildcardCollision(std::set<ParameterTypes> const& nodeParameterTypes,
0369                                   std::set<ParameterTypes> const& nodeWildcardTypes);
0370 
0371     bool anythingAllowed_;
0372     bool unknown_;
0373     SetDescriptionEntries entries_;
0374 
0375     std::set<std::string> usedLabels_;
0376     std::set<ParameterTypes> typesUsedForParameters_;
0377     std::set<ParameterTypes> typesUsedForWildcards_;
0378 
0379     std::string comment_;
0380   };
0381 }  // namespace edm
0382 
0383 #include "FWCore/ParameterSet/interface/ParameterWildcard.h"
0384 #include "FWCore/ParameterSet/interface/ParameterSwitch.h"
0385 #include "FWCore/ParameterSet/interface/AllowedLabelsDescription.h"
0386 
0387 namespace edm {
0388 
0389   template <typename T, typename U>
0390   ParameterDescriptionBase* ParameterSetDescription::add(
0391       U const& iLabel, T const& value, bool isTracked, bool isOptional, bool writeToCfi) {
0392     std::unique_ptr<ParameterDescriptionNode> node =
0393         std::make_unique<ParameterDescription<T>>(iLabel, value, isTracked);
0394     ParameterDescriptionNode* pnode = addNode(std::move(node), isOptional, writeToCfi);
0395     return static_cast<ParameterDescriptionBase*>(pnode);
0396   }
0397 
0398   template <typename T, typename U>
0399   ParameterDescriptionBase* ParameterSetDescription::add(U const& iLabel,
0400                                                          bool isTracked,
0401                                                          bool isOptional,
0402                                                          bool writeToCfi) {
0403     std::unique_ptr<ParameterDescriptionNode> node = std::make_unique<ParameterDescription<T>>(iLabel, isTracked);
0404     ParameterDescriptionNode* pnode = addNode(std::move(node), isOptional, writeToCfi);
0405     return static_cast<ParameterDescriptionBase*>(pnode);
0406   }
0407 
0408   template <typename U>
0409   ParameterDescriptionBase* ParameterSetDescription::addVPSet(U const& iLabel,
0410                                                               ParameterSetDescription const& validator,
0411                                                               std::vector<ParameterSet> const& defaults,
0412                                                               bool isTracked,
0413                                                               bool isOptional,
0414                                                               bool writeToCfi) {
0415     std::unique_ptr<ParameterDescriptionNode> node =
0416         std::make_unique<ParameterDescription<std::vector<ParameterSet>>>(iLabel, validator, isTracked, defaults);
0417     ParameterDescriptionNode* pnode = addNode(std::move(node), isOptional, writeToCfi);
0418     return static_cast<ParameterDescriptionBase*>(pnode);
0419   }
0420 
0421   template <typename U>
0422   ParameterDescriptionBase* ParameterSetDescription::addVPSet(
0423       U const& iLabel, ParameterSetDescription const& validator, bool isTracked, bool isOptional, bool writeToCfi) {
0424     std::unique_ptr<ParameterDescriptionNode> node =
0425         std::make_unique<ParameterDescription<std::vector<ParameterSet>>>(iLabel, validator, isTracked);
0426     ParameterDescriptionNode* pnode = addNode(std::move(node), isOptional, writeToCfi);
0427     return static_cast<ParameterDescriptionBase*>(pnode);
0428   }
0429 
0430   template <typename T, typename U>
0431   ParameterWildcardBase* ParameterSetDescription::addWildcard(U const& pattern, bool isTracked) {
0432     std::unique_ptr<ParameterDescriptionNode> node =
0433         std::make_unique<ParameterWildcard<T>>(pattern, RequireZeroOrMore, isTracked);
0434     ParameterDescriptionNode* pnode = addNode(std::move(node), true, false);
0435     return static_cast<ParameterWildcardBase*>(pnode);
0436   }
0437 
0438   template <typename T>
0439   ParameterDescriptionNode* ParameterSetDescription::ifValue(ParameterDescription<T> const& switchParameter,
0440                                                              std::unique_ptr<ParameterDescriptionCases<T>> cases,
0441                                                              bool optional,
0442                                                              bool writeToCfi) {
0443     std::unique_ptr<ParameterDescriptionNode> pdswitch =
0444         std::make_unique<ParameterSwitch<T>>(switchParameter, std::move(cases));
0445     return addNode(std::move(pdswitch), optional, writeToCfi);
0446   }
0447 
0448   template <typename T, typename U>
0449   ParameterDescriptionNode* ParameterSetDescription::labelsFrom(U const& iLabel,
0450                                                                 bool isTracked,
0451                                                                 bool optional,
0452                                                                 bool writeToCfi) {
0453     std::unique_ptr<ParameterDescriptionNode> pd = std::make_unique<AllowedLabelsDescription<T>>(iLabel, isTracked);
0454     return addNode(std::move(pd), optional, writeToCfi);
0455   }
0456 
0457   template <typename T, typename U, typename V>
0458   ParameterDescriptionNode* ParameterSetDescription::labelsFrom(
0459       U const& iLabel, bool isTracked, bool optional, bool writeToCfi, V const& desc) {
0460     std::unique_ptr<ParameterDescriptionNode> pd =
0461         std::make_unique<AllowedLabelsDescription<T>>(iLabel, desc, isTracked);
0462     return addNode(std::move(pd), optional, writeToCfi);
0463   }
0464 }  // namespace edm
0465 
0466 #endif