Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-05-31 03:10:34

0001 
0002 #include "FWCore/ParameterSet/interface/ParameterDescription.h"
0003 
0004 #include "DataFormats/Provenance/interface/EventID.h"
0005 #include "DataFormats/Provenance/interface/EventRange.h"
0006 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
0007 #include "DataFormats/Provenance/interface/LuminosityBlockRange.h"
0008 #include "FWCore/ParameterSet/interface/DocFormatHelper.h"
0009 #include "FWCore/Utilities/interface/FileInPath.h"
0010 #include "FWCore/ParameterSet/src/FillDescriptionFromPSet.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0012 #include "FWCore/ParameterSet/interface/VParameterSetEntry.h"
0013 #include "FWCore/Utilities/interface/Algorithms.h"
0014 #include "FWCore/Utilities/interface/EDMException.h"
0015 #include "FWCore/Utilities/interface/InputTag.h"
0016 #include "FWCore/Utilities/interface/ESInputTag.h"
0017 
0018 #include <cassert>
0019 #include <cstdlib>
0020 #include <iomanip>
0021 #include <ostream>
0022 #include <sstream>
0023 
0024 namespace edm {
0025 
0026   // =================================================================
0027 
0028   ParameterDescription<ParameterSetDescription>::ParameterDescription(std::string const& iLabel,
0029                                                                       ParameterSetDescription const& value,
0030                                                                       bool isTracked,
0031                                                                       Comment const& iComment)
0032       : ParameterDescriptionBase(iLabel, k_PSet, isTracked, true, iComment),
0033         psetDesc_(new ParameterSetDescription(value)) {}
0034 
0035   ParameterDescription<ParameterSetDescription>::ParameterDescription(char const* iLabel,
0036                                                                       ParameterSetDescription const& value,
0037                                                                       bool isTracked,
0038                                                                       Comment const& iComment)
0039       : ParameterDescriptionBase(iLabel, k_PSet, isTracked, true, iComment),
0040         psetDesc_(new ParameterSetDescription(value)) {}
0041 
0042   ParameterDescription<ParameterSetDescription>::~ParameterDescription() {}
0043 
0044   void ParameterDescription<ParameterSetDescription>::validate_(ParameterSet& pset,
0045                                                                 std::set<std::string>& validatedLabels,
0046                                                                 bool optional) const {
0047     bool exists = pset.existsAs<ParameterSet>(label(), isTracked());
0048 
0049     if (exists) {
0050       validatedLabels.insert(label());
0051     } else if (pset.existsAs<ParameterSet>(label(), !isTracked())) {
0052       throwParameterWrongTrackiness();
0053     } else if (pset.exists(label())) {
0054       throwParameterWrongType();
0055     }
0056 
0057     if (!optional && !exists) {
0058       if (isTracked()) {
0059         pset.addParameter(label(), ParameterSet());
0060       } else {
0061         pset.addUntrackedParameter(label(), ParameterSet());
0062       }
0063       validatedLabels.insert(label());
0064     }
0065 
0066     exists = pset.existsAs<ParameterSet>(label(), isTracked());
0067 
0068     if (exists) {
0069       if (pset.isRegistered()) {
0070         pset.invalidateRegistration("");
0071       }
0072       ParameterSet* containedPSet = pset.getPSetForUpdate(label());
0073       psetDesc_->validate(*containedPSet);
0074     }
0075   }
0076 
0077   void ParameterDescription<ParameterSetDescription>::printDefault_(std::ostream& os,
0078                                                                     bool writeToCfi,
0079                                                                     DocFormatHelper& dfh) const {
0080     os << "see Section " << dfh.section() << "." << dfh.counter();
0081     if (!writeToCfi)
0082       os << " (do not write to cfi)";
0083     os << "\n";
0084   }
0085 
0086   bool ParameterDescription<ParameterSetDescription>::hasNestedContent_() const { return true; }
0087 
0088   void ParameterDescription<ParameterSetDescription>::printNestedContent_(std::ostream& os,
0089                                                                           bool /*optional*/,
0090                                                                           DocFormatHelper& dfh) const {
0091     int indentation = dfh.indentation();
0092     if (dfh.parent() != DocFormatHelper::TOP) {
0093       indentation -= DocFormatHelper::offsetSectionContent();
0094     }
0095 
0096     std::stringstream ss;
0097     ss << dfh.section() << "." << dfh.counter();
0098     std::string newSection = ss.str();
0099 
0100     printSpaces(os, indentation);
0101     os << "Section " << newSection << " " << label() << " PSet description:\n";
0102     if (!dfh.brief())
0103       os << "\n";
0104 
0105     DocFormatHelper new_dfh(dfh);
0106     new_dfh.init();
0107     new_dfh.setSection(newSection);
0108     if (dfh.parent() == DocFormatHelper::TOP) {
0109       new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
0110     }
0111     psetDesc_->print(os, new_dfh);
0112   }
0113 
0114   bool ParameterDescription<ParameterSetDescription>::exists_(ParameterSet const& pset) const {
0115     return pset.existsAs<ParameterSet>(label(), isTracked());
0116   }
0117 
0118   ParameterSetDescription const* ParameterDescription<ParameterSetDescription>::parameterSetDescription() const {
0119     return psetDesc_.operator->();
0120   }
0121 
0122   ParameterSetDescription* ParameterDescription<ParameterSetDescription>::parameterSetDescription() {
0123     return psetDesc_.operator->();
0124   }
0125 
0126   void ParameterDescription<ParameterSetDescription>::writeCfi_(std::ostream& os, int indentation) const {
0127     bool startWithComma = false;
0128     indentation += 2;
0129     psetDesc_->writeCfi(os, startWithComma, indentation);
0130   }
0131 
0132   void ParameterDescription<ParameterSetDescription>::writeDoc_(std::ostream&, int /*indentation*/) const {}
0133 
0134   // These next two should not be needed for this specialization
0135   bool ParameterDescription<ParameterSetDescription>::exists_(ParameterSet const&, bool /*isTracked*/) const {
0136     throw Exception(errors::LogicError);
0137     return true;
0138   }
0139 
0140   void ParameterDescription<ParameterSetDescription>::insertDefault_(ParameterSet&) const {
0141     throw Exception(errors::LogicError);
0142     return;
0143   }
0144 
0145   // =================================================================
0146 
0147   ParameterDescription<std::vector<ParameterSet> >::ParameterDescription(std::string const& iLabel,
0148                                                                          ParameterSetDescription const& psetDesc,
0149                                                                          bool isTracked,
0150                                                                          std::vector<ParameterSet> const& vPset,
0151                                                                          Comment const& iComment)
0152       : ParameterDescriptionBase(iLabel, k_VPSet, isTracked, true, iComment),
0153         psetDesc_(new ParameterSetDescription(psetDesc)),
0154         vPset_(vPset),
0155         partOfDefaultOfVPSet_(false) {}
0156 
0157   ParameterDescription<std::vector<ParameterSet> >::ParameterDescription(char const* iLabel,
0158                                                                          ParameterSetDescription const& psetDesc,
0159                                                                          bool isTracked,
0160                                                                          std::vector<ParameterSet> const& vPset,
0161                                                                          Comment const& iComment)
0162       : ParameterDescriptionBase(iLabel, k_VPSet, isTracked, true, iComment),
0163         psetDesc_(new ParameterSetDescription(psetDesc)),
0164         vPset_(vPset),
0165         partOfDefaultOfVPSet_(false) {}
0166 
0167   ParameterDescription<std::vector<ParameterSet> >::ParameterDescription(std::string const& iLabel,
0168                                                                          ParameterSetDescription const& psetDesc,
0169                                                                          bool isTracked,
0170                                                                          Comment const& iComment)
0171       : ParameterDescriptionBase(iLabel, k_VPSet, isTracked, false, iComment),
0172         psetDesc_(new ParameterSetDescription(psetDesc)),
0173         vPset_(),
0174         partOfDefaultOfVPSet_(false) {}
0175 
0176   ParameterDescription<std::vector<ParameterSet> >::ParameterDescription(char const* iLabel,
0177                                                                          ParameterSetDescription const& psetDesc,
0178                                                                          bool isTracked,
0179                                                                          Comment const& iComment)
0180       : ParameterDescriptionBase(iLabel, k_VPSet, isTracked, false, iComment),
0181         psetDesc_(new ParameterSetDescription(psetDesc)),
0182         vPset_(),
0183         partOfDefaultOfVPSet_(false) {}
0184 
0185   ParameterDescription<std::vector<ParameterSet> >::~ParameterDescription() {}
0186 
0187   ParameterSetDescription const* ParameterDescription<std::vector<ParameterSet> >::parameterSetDescription() const {
0188     return psetDesc_.operator->();
0189   }
0190 
0191   ParameterSetDescription* ParameterDescription<std::vector<ParameterSet> >::parameterSetDescription() {
0192     return psetDesc_.operator->();
0193   }
0194 
0195   void ParameterDescription<std::vector<ParameterSet> >::validate_(ParameterSet& pset,
0196                                                                    std::set<std::string>& validatedLabels,
0197                                                                    bool optional) const {
0198     bool exists = pset.existsAs<std::vector<ParameterSet> >(label(), isTracked());
0199 
0200     if (exists) {
0201       validatedLabels.insert(label());
0202     } else if (pset.existsAs<std::vector<ParameterSet> >(label(), !isTracked())) {
0203       throwParameterWrongTrackiness();
0204     } else if (pset.exists(label())) {
0205       throwParameterWrongType();
0206     }
0207 
0208     if (!exists && !optional) {
0209       if (hasDefault()) {
0210         if (isTracked()) {
0211           pset.addParameter(label(), vPset_);
0212         } else {
0213           pset.addUntrackedParameter(label(), vPset_);
0214         }
0215         validatedLabels.insert(label());
0216       } else {
0217         throwMissingRequiredNoDefault();
0218       }
0219     }
0220 
0221     exists = pset.existsAs<std::vector<ParameterSet> >(label(), isTracked());
0222     if (exists) {
0223       VParameterSetEntry* vpsetEntry = pset.getPSetVectorForUpdate(label());
0224       assert(vpsetEntry);
0225 
0226       for (unsigned i = 0; i < vpsetEntry->size(); ++i) {
0227         psetDesc_->validate(vpsetEntry->psetInVector(i));
0228       }
0229     }
0230   }
0231 
0232   void ParameterDescription<std::vector<ParameterSet> >::printDefault_(std::ostream& os,
0233                                                                        bool writeToCfi,
0234                                                                        DocFormatHelper& dfh) const {
0235     os << "see Section " << dfh.section() << "." << dfh.counter();
0236     if (!writeToCfi)
0237       os << " (do not write to cfi)";
0238     os << "\n";
0239   }
0240 
0241   bool ParameterDescription<std::vector<ParameterSet> >::hasNestedContent_() const { return true; }
0242 
0243   void ParameterDescription<std::vector<ParameterSet> >::printNestedContent_(std::ostream& os,
0244                                                                              bool /*optional*/,
0245                                                                              DocFormatHelper& dfh) const {
0246     int indentation = dfh.indentation();
0247     if (dfh.parent() != DocFormatHelper::TOP) {
0248       indentation -= DocFormatHelper::offsetSectionContent();
0249     }
0250 
0251     if (!partOfDefaultOfVPSet_) {
0252       printSpaces(os, indentation);
0253       os << "Section " << dfh.section() << "." << dfh.counter() << " " << label() << " VPSet description:\n";
0254 
0255       printSpaces(os, indentation + DocFormatHelper::offsetSectionContent());
0256       os << "All elements will be validated using the PSet description in Section " << dfh.section() << "."
0257          << dfh.counter() << ".1.\n";
0258     } else {
0259       printSpaces(os, indentation);
0260       os << "Section " << dfh.section() << "." << dfh.counter() << " "
0261          << " VPSet description for VPSet that is part of the default of a containing VPSet:\n";
0262     }
0263 
0264     printSpaces(os, indentation + DocFormatHelper::offsetSectionContent());
0265 
0266     unsigned subsectionOffset = 2;
0267     if (partOfDefaultOfVPSet_)
0268       subsectionOffset = 1;
0269 
0270     if (hasDefault()) {
0271       if (vPset_.empty())
0272         os << "The default VPSet is empty.\n";
0273       else if (vPset_.size() == 1U)
0274         os << "The default VPSet has 1 element.\n";
0275       else
0276         os << "The default VPSet has " << vPset_.size() << " elements.\n";
0277 
0278       if (!vPset_.empty()) {
0279         for (unsigned i = 0; i < vPset_.size(); ++i) {
0280           printSpaces(os, indentation + DocFormatHelper::offsetSectionContent());
0281           os << "[" << (i) << "]: see Section " << dfh.section() << "." << dfh.counter() << "."
0282              << (i + subsectionOffset) << "\n";
0283         }
0284       }
0285     } else {
0286       os << "Does not have a default VPSet.\n";
0287     }
0288 
0289     if (!dfh.brief())
0290       os << "\n";
0291 
0292     if (!partOfDefaultOfVPSet_) {
0293       std::stringstream ss;
0294       ss << dfh.section() << "." << dfh.counter() << ".1";
0295       std::string newSection = ss.str();
0296 
0297       printSpaces(os, indentation);
0298       os << "Section " << newSection << " description of PSet used to validate elements of VPSet:\n";
0299       if (!dfh.brief())
0300         os << "\n";
0301 
0302       DocFormatHelper new_dfh(dfh);
0303       new_dfh.init();
0304       new_dfh.setSection(newSection);
0305       if (dfh.parent() == DocFormatHelper::TOP) {
0306         new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
0307       }
0308       psetDesc_->print(os, new_dfh);
0309     }
0310 
0311     if (hasDefault()) {
0312       for (unsigned i = 0; i < vPset_.size(); ++i) {
0313         std::stringstream ss;
0314         ss << dfh.section() << "." << dfh.counter() << "." << (i + subsectionOffset);
0315         std::string newSection = ss.str();
0316 
0317         printSpaces(os, indentation);
0318         os << "Section " << newSection << " PSet description of "
0319            << "default VPSet element [" << i << "]\n";
0320         if (!dfh.brief())
0321           os << "\n";
0322 
0323         DocFormatHelper new_dfh(dfh);
0324         new_dfh.init();
0325         new_dfh.setSection(newSection);
0326         if (dfh.parent() == DocFormatHelper::TOP) {
0327           new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
0328         }
0329 
0330         ParameterSetDescription defaultDescription;
0331         fillDescriptionFromPSet(vPset_[i], defaultDescription);
0332         defaultDescription.print(os, new_dfh);
0333       }
0334     }
0335   }
0336 
0337   bool ParameterDescription<std::vector<ParameterSet> >::exists_(ParameterSet const& pset) const {
0338     return pset.existsAs<std::vector<ParameterSet> >(label(), isTracked());
0339   }
0340 
0341   void ParameterDescription<std::vector<ParameterSet> >::writeOneElementToCfi(ParameterSet const& pset,
0342                                                                               std::ostream& os,
0343                                                                               int indentation,
0344                                                                               bool& nextOneStartsWithAComma) {
0345     if (nextOneStartsWithAComma)
0346       os << ",";
0347     nextOneStartsWithAComma = true;
0348     os << "\n";
0349     printSpaces(os, indentation + 2);
0350 
0351     os << "cms.PSet(";
0352 
0353     bool startWithComma = false;
0354     int indent = indentation + 4;
0355 
0356     ParameterSetDescription psetDesc;
0357     fillDescriptionFromPSet(pset, psetDesc);
0358     psetDesc.writeCfi(os, startWithComma, indent);
0359 
0360     os << ")";
0361   }
0362 
0363   void ParameterDescription<std::vector<ParameterSet> >::writeCfi_(std::ostream& os, int indentation) const {
0364     bool nextOneStartsWithAComma = false;
0365     for_all(
0366         vPset_,
0367         std::bind(
0368             &writeOneElementToCfi, std::placeholders::_1, std::ref(os), indentation, std::ref(nextOneStartsWithAComma)));
0369     os << "\n";
0370     printSpaces(os, indentation);
0371   }
0372 
0373   void ParameterDescription<std::vector<ParameterSet> >::writeDoc_(std::ostream&, int /*indentation*/) const {}
0374 
0375   // These next two should not be needed for this specialization
0376   bool ParameterDescription<std::vector<ParameterSet> >::exists_(ParameterSet const&, bool /*isTracked*/) const {
0377     throw Exception(errors::LogicError);
0378     return true;
0379   }
0380 
0381   void ParameterDescription<std::vector<ParameterSet> >::insertDefault_(ParameterSet&) const {
0382     throw Exception(errors::LogicError);
0383     return;
0384   }
0385 
0386   // =================================================================
0387 
0388   namespace writeParameterValue {
0389 
0390     template <typename T>
0391     void writeSingleValue(std::ostream& os, T const& value, ValueFormat) {
0392       os << value;
0393     }
0394 
0395     // Specialize this for cases where the operator<< does not give
0396     // the proper formatting for a configuration file.
0397 
0398     // Formatting the doubles is a little tricky.  It is a requirement
0399     // that when a value of ***type double*** is added to a ParameterSetDescription
0400     // the EXACT same value of type double will be created and passed to the
0401     // ParameterSet after the cfi files have been read.  The tricky part
0402     // is these values usually appear in the C++ code and cfi file as text
0403     // strings (in decimal form).  We do our best to force the text
0404     // string in the C++ code to be the same as the text string in the
0405     // cfi file by judiciously rounding to smaller precision when possible.
0406     // But it is not always possible to force the text strings to be the
0407     // same.  Generally, there are differences when the text string in the
0408     // C++ code has many digits (probably more than a human will ever type).
0409     // Even in cases where the text strings differ, the values stored in
0410     // memory in variables of type double will be exactly the same.
0411     // The alternative to the approach here is to store the values as strings,
0412     // but that approach was rejected because it would require the
0413     // ParameterSetDescription to know how to parse the strings.
0414     void formatDouble(double value, std::string& result) {
0415       {
0416         std::stringstream ss;
0417         ss << std::setprecision(17) << value;
0418         result = ss.str();
0419       }
0420       if (result.size() > 15 && std::string::npos != result.find('.')) {
0421         std::stringstream ss;
0422         ss << std::setprecision(15) << value;
0423         std::string resultLessPrecision = ss.str();
0424 
0425         if (resultLessPrecision.size() < result.size() - 2) {
0426           double test = std::strtod(resultLessPrecision.c_str(), nullptr);
0427           if (test == value) {
0428             result = resultLessPrecision;
0429           }
0430         }
0431       }
0432     }
0433 
0434     template <>
0435     void writeSingleValue<double>(std::ostream& os, double const& value, ValueFormat) {
0436       std::string sValue;
0437       formatDouble(value, sValue);
0438       os << sValue;
0439     }
0440 
0441     template <>
0442     void writeSingleValue<bool>(std::ostream& os, bool const& value, ValueFormat) {
0443       value ? os << "True" : os << "False";
0444     }
0445 
0446     template <>
0447     void writeSingleValue<std::string>(std::ostream& os, std::string const& value, ValueFormat) {
0448       os << "'" << value << "'";
0449     }
0450 
0451     template <>
0452     void writeSingleValue<EventID>(std::ostream& os, EventID const& value, ValueFormat format) {
0453       if (format == CFI) {
0454         os << value.run() << ", " << value.luminosityBlock() << ", " << value.event();
0455       } else {
0456         if (value.luminosityBlock() == 0U) {
0457           os << value.run() << ":" << value.event();
0458         } else {
0459           os << value.run() << ":" << value.luminosityBlock() << ":" << value.event();
0460         }
0461       }
0462     }
0463 
0464     template <>
0465     void writeSingleValue<LuminosityBlockID>(std::ostream& os, LuminosityBlockID const& value, ValueFormat format) {
0466       if (format == CFI)
0467         os << value.run() << ", " << value.luminosityBlock();
0468       else
0469         os << value.run() << ":" << value.luminosityBlock();
0470     }
0471 
0472     template <>
0473     void writeSingleValue<EventRange>(std::ostream& os, EventRange const& value, ValueFormat format) {
0474       if (value.startLumi() == 0U) {
0475         if (format == CFI)
0476           os << "'" << value.startRun() << ":" << value.startEvent() << "-" << value.endRun() << ":" << value.endEvent()
0477              << "'";
0478         else
0479           os << value.startRun() << ":" << value.startEvent() << "-" << value.endRun() << ":" << value.endEvent();
0480       } else {
0481         if (format == CFI)
0482           os << "'" << value.startRun() << ":" << value.startLumi() << ":" << value.startEvent() << "-"
0483              << value.endRun() << ":" << value.endLumi() << ":" << value.endEvent() << "'";
0484         else
0485           os << value.startRun() << ":" << value.startLumi() << ":" << value.startEvent() << "-" << value.endRun()
0486              << ":" << value.endLumi() << ":" << value.endEvent();
0487       }
0488     }
0489 
0490     template <>
0491     void writeSingleValue<LuminosityBlockRange>(std::ostream& os,
0492                                                 LuminosityBlockRange const& value,
0493                                                 ValueFormat format) {
0494       if (format == CFI)
0495         os << "'" << value.startRun() << ":" << value.startLumi() << "-" << value.endRun() << ":" << value.endLumi()
0496            << "'";
0497       else
0498         os << value.startRun() << ":" << value.startLumi() << "-" << value.endRun() << ":" << value.endLumi();
0499     }
0500 
0501     template <>
0502     void writeSingleValue<InputTag>(std::ostream& os, InputTag const& value, ValueFormat format) {
0503       if (format == CFI) {
0504         os << "'" << value.label() << "'";
0505         if (!value.instance().empty() || !value.process().empty()) {
0506           os << ", '" << value.instance() << "'";
0507         }
0508         if (!value.process().empty()) {
0509           os << ", '" << value.process() << "'";
0510         }
0511       } else {
0512         os << "'" << value.label();
0513         if (!value.instance().empty() || !value.process().empty()) {
0514           os << ":" << value.instance();
0515         }
0516         if (!value.process().empty()) {
0517           os << ":" << value.process();
0518         }
0519         os << "'";
0520       }
0521     }
0522 
0523     template <>
0524     void writeSingleValue<ESInputTag>(std::ostream& os, ESInputTag const& value, ValueFormat format) {
0525       if (format == CFI) {
0526         os << "'" << value.module() << "', '" << value.data() << "'";
0527       } else {
0528         os << "'" << value.module() << ":" << value.data() << "'";
0529       }
0530     }
0531 
0532     template <>
0533     void writeSingleValue<FileInPath>(std::ostream& os, FileInPath const& value, ValueFormat) {
0534       os << "'" << value.relativePath() << "'";
0535     }
0536 
0537     template <typename T>
0538     void writeValue(std::ostream& os, T const& value_, ValueFormat format) {
0539       std::ios_base::fmtflags ff = os.flags(std::ios_base::dec);
0540       os.width(0);
0541       writeSingleValue<T>(os, value_, format);
0542       os.flags(ff);
0543     }
0544 
0545     template <typename T>
0546     void writeValueInVector(std::ostream& os, T const& value, ValueFormat format) {
0547       writeSingleValue<T>(os, value, format);
0548     }
0549 
0550     // Specializations for cases where we write the single values into
0551     // vectors differently than when there is only one not in a vector.
0552     template <>
0553     void writeValueInVector<EventID>(std::ostream& os, EventID const& value, ValueFormat format) {
0554       if (value.luminosityBlock() == 0U) {
0555         if (format == CFI)
0556           os << "'" << value.run() << ":" << value.event() << "'";
0557         else
0558           os << value.run() << ":" << value.event();
0559       } else {
0560         if (format == CFI)
0561           os << "'" << value.run() << ":" << value.luminosityBlock() << ":" << value.event() << "'";
0562         else
0563           os << value.run() << ":" << value.luminosityBlock() << ":" << value.event();
0564       }
0565     }
0566 
0567     template <>
0568     void writeValueInVector<LuminosityBlockID>(std::ostream& os, LuminosityBlockID const& value, ValueFormat format) {
0569       if (format == CFI)
0570         os << "'" << value.run() << ":" << value.luminosityBlock() << "'";
0571       else
0572         os << value.run() << ":" << value.luminosityBlock();
0573     }
0574 
0575     template <>
0576     void writeValueInVector<InputTag>(std::ostream& os, InputTag const& value, ValueFormat) {
0577       os << "'" << value.label();
0578       if (!value.instance().empty() || !value.process().empty()) {
0579         os << ":" << value.instance();
0580       }
0581       if (!value.process().empty()) {
0582         os << ":" << value.process();
0583       }
0584       os << "'";
0585     }
0586 
0587     template <>
0588     void writeValueInVector<ESInputTag>(std::ostream& os, ESInputTag const& value, ValueFormat) {
0589       os << "'" << value.module() << ":" << value.data() << "'";
0590     }
0591 
0592     template <typename T>
0593     void writeValueInVectorWithSpace(
0594         T const& value, std::ostream& os, int indentation, bool& startWithComma, ValueFormat format, int& i) {
0595       if (startWithComma && format == CFI)
0596         os << ",";
0597       startWithComma = true;
0598       os << "\n" << std::setw(indentation) << "";
0599       if (format == DOC)
0600         os << "[" << i << "]: ";
0601       writeValueInVector<T>(os, value, format);
0602       ++i;
0603     }
0604 
0605     template <typename T>
0606     void writeVector(std::ostream& os, int indentation, std::vector<T> const& value_, ValueFormat format) {
0607       std::ios_base::fmtflags ff = os.flags(std::ios_base::dec);
0608       char oldFill = os.fill();
0609       os.width(0);
0610       if (value_.empty() && format == DOC) {
0611         os << "empty";
0612       } else if (value_.size() == 1U && format == CFI) {
0613         writeValueInVector<T>(os, value_[0], format);
0614       } else if (!value_.empty()) {
0615         if (format == DOC)
0616           os << "(vector size = " << value_.size() << ")";
0617         if (format == CFI and value_.size() > 255U)
0618           os << " *(";
0619         os.fill(' ');
0620         bool startWithComma = false;
0621         int i = 0;
0622         for_all(value_,
0623                 std::bind(&writeValueInVectorWithSpace<T>,
0624                           std::placeholders::_1,
0625                           std::ref(os),
0626                           indentation + 2,
0627                           std::ref(startWithComma),
0628                           format,
0629                           std::ref(i)));
0630         if (format == CFI)
0631           os << "\n" << std::setw(indentation) << "";
0632         if (format == CFI and value_.size() > 255U)
0633           os << ") ";
0634       }
0635       os.flags(ff);
0636       os.fill(oldFill);
0637     }
0638 
0639     void writeValue(std::ostream& os, int, int const& value_, ValueFormat format) {
0640       writeValue<int>(os, value_, format);
0641     }
0642 
0643     void writeValue(std::ostream& os, int indentation, std::vector<int> const& value_, ValueFormat format) {
0644       writeVector<int>(os, indentation, value_, format);
0645     }
0646 
0647     void writeValue(std::ostream& os, int, unsigned const& value_, ValueFormat format) {
0648       writeValue<unsigned>(os, value_, format);
0649     }
0650 
0651     void writeValue(std::ostream& os, int indentation, std::vector<unsigned> const& value_, ValueFormat format) {
0652       writeVector<unsigned>(os, indentation, value_, format);
0653     }
0654 
0655     void writeValue(std::ostream& os, int, long long const& value_, ValueFormat format) {
0656       writeValue<long long>(os, value_, format);
0657     }
0658 
0659     void writeValue(std::ostream& os, int indentation, std::vector<long long> const& value_, ValueFormat format) {
0660       writeVector<long long>(os, indentation, value_, format);
0661     }
0662 
0663     void writeValue(std::ostream& os, int, unsigned long long const& value_, ValueFormat format) {
0664       writeValue<unsigned long long>(os, value_, format);
0665     }
0666 
0667     void writeValue(std::ostream& os,
0668                     int indentation,
0669                     std::vector<unsigned long long> const& value_,
0670                     ValueFormat format) {
0671       writeVector<unsigned long long>(os, indentation, value_, format);
0672     }
0673 
0674     void writeValue(std::ostream& os, int, double const& value_, ValueFormat format) {
0675       writeValue<double>(os, value_, format);
0676     }
0677 
0678     void writeValue(std::ostream& os, int indentation, std::vector<double> const& value_, ValueFormat format) {
0679       writeVector<double>(os, indentation, value_, format);
0680     }
0681 
0682     void writeValue(std::ostream& os, int, bool const& value_, ValueFormat format) {
0683       writeValue<bool>(os, value_, format);
0684     }
0685 
0686     void writeValue(std::ostream& os, int, std::string const& value_, ValueFormat format) {
0687       writeValue<std::string>(os, value_, format);
0688     }
0689 
0690     void writeValue(std::ostream& os, int indentation, std::vector<std::string> const& value_, ValueFormat format) {
0691       writeVector<std::string>(os, indentation, value_, format);
0692     }
0693 
0694     void writeValue(std::ostream& os, int, EventID const& value_, ValueFormat format) {
0695       writeValue<EventID>(os, value_, format);
0696     }
0697 
0698     void writeValue(std::ostream& os, int indentation, std::vector<EventID> const& value_, ValueFormat format) {
0699       writeVector<EventID>(os, indentation, value_, format);
0700     }
0701 
0702     void writeValue(std::ostream& os, int, LuminosityBlockID const& value_, ValueFormat format) {
0703       writeValue<LuminosityBlockID>(os, value_, format);
0704     }
0705 
0706     void writeValue(std::ostream& os,
0707                     int indentation,
0708                     std::vector<LuminosityBlockID> const& value_,
0709                     ValueFormat format) {
0710       writeVector<LuminosityBlockID>(os, indentation, value_, format);
0711     }
0712 
0713     void writeValue(std::ostream& os, int, LuminosityBlockRange const& value_, ValueFormat format) {
0714       writeValue<LuminosityBlockRange>(os, value_, format);
0715     }
0716 
0717     void writeValue(std::ostream& os,
0718                     int indentation,
0719                     std::vector<LuminosityBlockRange> const& value_,
0720                     ValueFormat format) {
0721       writeVector<LuminosityBlockRange>(os, indentation, value_, format);
0722     }
0723 
0724     void writeValue(std::ostream& os, int, EventRange const& value_, ValueFormat format) {
0725       writeValue<EventRange>(os, value_, format);
0726     }
0727 
0728     void writeValue(std::ostream& os, int indentation, std::vector<EventRange> const& value_, ValueFormat format) {
0729       writeVector<EventRange>(os, indentation, value_, format);
0730     }
0731 
0732     void writeValue(std::ostream& os, int, InputTag const& value_, ValueFormat format) {
0733       writeValue<InputTag>(os, value_, format);
0734     }
0735 
0736     void writeValue(std::ostream& os, int indentation, std::vector<InputTag> const& value_, ValueFormat format) {
0737       writeVector<InputTag>(os, indentation, value_, format);
0738     }
0739 
0740     void writeValue(std::ostream& os, int, ESInputTag const& value_, ValueFormat format) {
0741       writeValue<ESInputTag>(os, value_, format);
0742     }
0743 
0744     void writeValue(std::ostream& os, int indentation, std::vector<ESInputTag> const& value_, ValueFormat format) {
0745       writeVector<ESInputTag>(os, indentation, value_, format);
0746     }
0747 
0748     void writeValue(std::ostream& os, int, FileInPath const& value_, ValueFormat format) {
0749       writeValue<FileInPath>(os, value_, format);
0750     }
0751 
0752     bool hasNestedContent(int const&) { return false; }
0753     bool hasNestedContent(std::vector<int> const& value) { return value.size() > 5U; }
0754     bool hasNestedContent(unsigned const&) { return false; }
0755     bool hasNestedContent(std::vector<unsigned> const& value) { return value.size() > 5U; }
0756     bool hasNestedContent(long long const&) { return false; }
0757     bool hasNestedContent(std::vector<long long> const& value) { return value.size() > 5U; }
0758     bool hasNestedContent(unsigned long long const&) { return false; }
0759     bool hasNestedContent(std::vector<unsigned long long> const& value) { return value.size() > 5U; }
0760     bool hasNestedContent(double const&) { return false; }
0761     bool hasNestedContent(std::vector<double> const& value) { return value.size() > 5U; }
0762     bool hasNestedContent(bool const&) { return false; }
0763     bool hasNestedContent(std::string const&) { return false; }
0764     bool hasNestedContent(std::vector<std::string> const& value) { return value.size() > 5U; }
0765     bool hasNestedContent(EventID const&) { return false; }
0766     bool hasNestedContent(std::vector<EventID> const& value) { return value.size() > 5U; }
0767     bool hasNestedContent(LuminosityBlockID const&) { return false; }
0768     bool hasNestedContent(std::vector<LuminosityBlockID> const& value) { return value.size() > 5U; }
0769     bool hasNestedContent(LuminosityBlockRange const&) { return false; }
0770     bool hasNestedContent(std::vector<LuminosityBlockRange> const& value) { return value.size() > 5U; }
0771     bool hasNestedContent(EventRange const&) { return false; }
0772     bool hasNestedContent(std::vector<EventRange> const& value) { return value.size() > 5U; }
0773     bool hasNestedContent(InputTag const&) { return false; }
0774     bool hasNestedContent(std::vector<InputTag> const& value) { return value.size() > 5U; }
0775     bool hasNestedContent(ESInputTag const&) { return false; }
0776     bool hasNestedContent(std::vector<ESInputTag> const& value) { return value.size() > 5U; }
0777     bool hasNestedContent(FileInPath const&) { return false; }
0778   }  // namespace writeParameterValue
0779 }  // namespace edm