Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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, CfiOptions&) 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                           CfiOptions&,
0364                           bool& wroteSomething);
0365 
0366     static void printNode(SetDescriptionEntry const& entry, std::ostream& os, DocFormatHelper& dfh);
0367 
0368     void throwIfLabelsAlreadyUsed(std::set<std::string> const& nodeLabels);
0369     void throwIfWildcardCollision(std::set<ParameterTypes> const& nodeParameterTypes,
0370                                   std::set<ParameterTypes> const& nodeWildcardTypes);
0371 
0372     bool anythingAllowed_;
0373     bool unknown_;
0374     SetDescriptionEntries entries_;
0375 
0376     std::set<std::string> usedLabels_;
0377     std::set<ParameterTypes> typesUsedForParameters_;
0378     std::set<ParameterTypes> typesUsedForWildcards_;
0379 
0380     std::string comment_;
0381   };
0382 }  // namespace edm
0383 
0384 #include "FWCore/ParameterSet/interface/ParameterWildcard.h"
0385 #include "FWCore/ParameterSet/interface/ParameterSwitch.h"
0386 #include "FWCore/ParameterSet/interface/AllowedLabelsDescription.h"
0387 
0388 namespace edm {
0389 
0390   template <typename T, typename U>
0391   ParameterDescriptionBase* ParameterSetDescription::add(
0392       U const& iLabel, T const& value, bool isTracked, bool isOptional, bool writeToCfi) {
0393     std::unique_ptr<ParameterDescriptionNode> node =
0394         std::make_unique<ParameterDescription<T>>(iLabel, value, isTracked);
0395     ParameterDescriptionNode* pnode = addNode(std::move(node), isOptional, writeToCfi);
0396     return static_cast<ParameterDescriptionBase*>(pnode);
0397   }
0398 
0399   template <typename T, typename U>
0400   ParameterDescriptionBase* ParameterSetDescription::add(U const& iLabel,
0401                                                          bool isTracked,
0402                                                          bool isOptional,
0403                                                          bool writeToCfi) {
0404     std::unique_ptr<ParameterDescriptionNode> node = std::make_unique<ParameterDescription<T>>(iLabel, isTracked);
0405     ParameterDescriptionNode* pnode = addNode(std::move(node), isOptional, writeToCfi);
0406     return static_cast<ParameterDescriptionBase*>(pnode);
0407   }
0408 
0409   template <typename U>
0410   ParameterDescriptionBase* ParameterSetDescription::addVPSet(U const& iLabel,
0411                                                               ParameterSetDescription const& validator,
0412                                                               std::vector<ParameterSet> const& defaults,
0413                                                               bool isTracked,
0414                                                               bool isOptional,
0415                                                               bool writeToCfi) {
0416     std::unique_ptr<ParameterDescriptionNode> node =
0417         std::make_unique<ParameterDescription<std::vector<ParameterSet>>>(iLabel, validator, isTracked, defaults);
0418     ParameterDescriptionNode* pnode = addNode(std::move(node), isOptional, writeToCfi);
0419     return static_cast<ParameterDescriptionBase*>(pnode);
0420   }
0421 
0422   template <typename U>
0423   ParameterDescriptionBase* ParameterSetDescription::addVPSet(
0424       U const& iLabel, ParameterSetDescription const& validator, bool isTracked, bool isOptional, bool writeToCfi) {
0425     std::unique_ptr<ParameterDescriptionNode> node =
0426         std::make_unique<ParameterDescription<std::vector<ParameterSet>>>(iLabel, validator, isTracked);
0427     ParameterDescriptionNode* pnode = addNode(std::move(node), isOptional, writeToCfi);
0428     return static_cast<ParameterDescriptionBase*>(pnode);
0429   }
0430 
0431   template <typename T, typename U>
0432   ParameterWildcardBase* ParameterSetDescription::addWildcard(U const& pattern, bool isTracked) {
0433     std::unique_ptr<ParameterDescriptionNode> node =
0434         std::make_unique<ParameterWildcard<T>>(pattern, RequireZeroOrMore, isTracked);
0435     ParameterDescriptionNode* pnode = addNode(std::move(node), true, true);
0436     return static_cast<ParameterWildcardBase*>(pnode);
0437   }
0438 
0439   template <typename T>
0440   ParameterDescriptionNode* ParameterSetDescription::ifValue(ParameterDescription<T> const& switchParameter,
0441                                                              std::unique_ptr<ParameterDescriptionCases<T>> cases,
0442                                                              bool optional,
0443                                                              bool writeToCfi) {
0444     std::unique_ptr<ParameterDescriptionNode> pdswitch =
0445         std::make_unique<ParameterSwitch<T>>(switchParameter, std::move(cases));
0446     return addNode(std::move(pdswitch), optional, writeToCfi);
0447   }
0448 
0449   template <typename T, typename U>
0450   ParameterDescriptionNode* ParameterSetDescription::labelsFrom(U const& iLabel,
0451                                                                 bool isTracked,
0452                                                                 bool optional,
0453                                                                 bool writeToCfi) {
0454     std::unique_ptr<ParameterDescriptionNode> pd = std::make_unique<AllowedLabelsDescription<T>>(iLabel, isTracked);
0455     return addNode(std::move(pd), optional, writeToCfi);
0456   }
0457 
0458   template <typename T, typename U, typename V>
0459   ParameterDescriptionNode* ParameterSetDescription::labelsFrom(
0460       U const& iLabel, bool isTracked, bool optional, bool writeToCfi, V const& desc) {
0461     std::unique_ptr<ParameterDescriptionNode> pd =
0462         std::make_unique<AllowedLabelsDescription<T>>(iLabel, desc, isTracked);
0463     return addNode(std::move(pd), optional, writeToCfi);
0464   }
0465 }  // namespace edm
0466 
0467 #endif