Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:05:26

0001 #include "DetectorDescription/Core/interface/DDValue.h"
0002 
0003 #include "DetectorDescription/Core/interface/DDPosData.h"
0004 #include "DetectorDescription/Core/interface/DDFilteredView.h"
0005 #include "DetectorDescription/Core/interface/DDComparator.h"
0006 
0007 #include <cassert>
0008 
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "FWCore/Utilities/interface/Exception.h"
0011 
0012 static std::atomic<unsigned int> lastIndex{0};
0013 
0014 void DDValue::init(const std::string& name) {
0015   auto result = indexer().insert({name, 0});
0016 
0017   auto& indexToUse = result.first->second;
0018 
0019   //A 0 index means either
0020   // 1) this result was just added or
0021   // 2) another thread just added this but has not yet assigned an index
0022   if (0 == indexToUse.value_) {
0023     auto newIndex = ++lastIndex;
0024     unsigned int previous = 0;
0025     indexToUse.value_.compare_exchange_strong(previous, newIndex);
0026   }
0027   id_ = indexToUse.value_.load();
0028 
0029   //Make sure the name is recorded at the proper index
0030   auto& allNames = names();
0031   allNames.grow_to_at_least(id_ + 1);
0032   auto& storedName = allNames[id_];
0033   if (not storedName.string_) {
0034     std::unique_ptr<std::string> newName(new std::string{name});
0035     std::string* previous = nullptr;
0036     if (storedName.string_.compare_exchange_strong(previous, newName.get())) {
0037       newName.release();
0038     }
0039   }
0040 }
0041 
0042 DDValue::DDValue(const std::string& name) : id_(0), vecPair_() { init(name); }
0043 
0044 DDValue::DDValue(const char* name) : id_(0), vecPair_() { init(name); }
0045 
0046 DDValue::DDValue(const std::string& name, const std::vector<DDValuePair>& v) : id_(0) {
0047   init(name);
0048 
0049   auto it = v.begin();
0050   std::vector<std::string> svec;
0051   std::vector<double> dvec;
0052   vecPair_.reset(new vecpair_type(false, std::make_pair(svec, dvec)));
0053   for (; it != v.end(); ++it) {
0054     vecPair_->second.first.emplace_back(it->first);
0055     vecPair_->second.second.emplace_back(it->second);
0056   }
0057 }
0058 
0059 DDValue::DDValue(const std::string& name, double val) : id_(0) {
0060   init(name);
0061 
0062   std::vector<std::string> svec(1, "");
0063   std::vector<double> dvec(1, val);
0064 
0065   vecPair_.reset(new vecpair_type(false, std::make_pair(svec, dvec)));
0066   setEvalState(true);
0067 }
0068 
0069 DDValue::DDValue(const std::string& name, const std::string& sval, double dval) : id_(0) {
0070   init(name);
0071 
0072   std::vector<std::string> svec(1, sval);
0073   std::vector<double> dvec(1, dval);
0074   vecPair_.reset(new vecpair_type(false, std::make_pair(svec, dvec)));
0075   setEvalState(true);
0076 }
0077 
0078 DDValue::DDValue(const std::string& name, const std::string& sval) : id_(0) {
0079   init(name);
0080 
0081   std::vector<std::string> svec(1, sval);
0082   std::vector<double> dvec(1, 0);
0083   vecPair_.reset(new vecpair_type(false, std::make_pair(svec, dvec)));
0084   setEvalState(false);
0085 }
0086 
0087 DDValue::DDValue(unsigned int i) : id_(0), vecPair_() {
0088   if (lastIndex >= i)
0089     id_ = i;
0090 }
0091 
0092 DDValue::NamesToIndicies& DDValue::indexer(void) {
0093   static NamesToIndicies indexer_;
0094   return indexer_;
0095 }
0096 
0097 DDValue::Names DDValue::initializeNames() {
0098   //Make sure memory is zeroed before allocating StringHolder
0099   // this allows us to check the value of the held std::atomic
0100   // as the object is being added to the container
0101   DDValue::Names names{};
0102   names.emplace_back(StringHolder(std::string{}));
0103   return names;
0104 }
0105 
0106 DDValue::Names& DDValue::names(void) {
0107   static Names names_{initializeNames()};
0108   return names_;
0109 }
0110 
0111 const std::vector<double>& DDValue::doubles(void) const {
0112   if (vecPair_->first) {
0113     return vecPair_->second.second;
0114   } else {
0115     std::string message = "DDValue " + name() + " is not numerically evaluated! Use DDValue::std::strings()!";
0116     edm::LogError("DDValue") << message << std::endl;
0117     throw cms::Exception("DDException") << message;
0118   }
0119 }
0120 
0121 std::ostream& operator<<(std::ostream& o, const DDValue& v) {
0122   o << v.name() << " = ";
0123   unsigned int i = 0;
0124   if (v.isEvaluated()) {
0125     for (; i < v.size(); ++i) {
0126       o << '(' << v[i].first << ',' << v[i].second << ") ";
0127     }
0128   } else {
0129     const std::vector<std::string>& s = v.strings();
0130     for (; i < v.size(); ++i) {
0131       o << s[i] << ' ';
0132     }
0133   }
0134   return o;
0135 }
0136 
0137 //FIXME move it elsewhere; DO NOT put out the name for now... need to fix DDCoreToDDXMLOutput
0138 std::ostream& operator<<(std::ostream& o, const DDValuePair& v) { return o << v.second; }
0139 
0140 DDValuePair DDValue::operator[](unsigned int i) const {
0141   if (vecPair_->first) {
0142     return DDValuePair(vecPair_->second.first[i], vecPair_->second.second[i]);
0143   } else {
0144     std::string message = "DDValue " + name() + " is not numerically evaluated! Use DDValue::std::strings()!";
0145     edm::LogError("DDValue") << message;
0146     throw cms::Exception("DDException") << message;
0147   }
0148 }
0149 
0150 void DDValue::setEvalState(bool newState) { vecPair_->first = newState; }
0151 
0152 bool DDValue::isEvaluated(void) const { return vecPair_->first; }
0153 
0154 bool DDValue::operator==(const DDValue& v) const {
0155   bool result(false);
0156   if (id() == v.id()) {
0157     assert(vecPair_);
0158     assert(v.vecPair_);
0159     if (vecPair_->first) {  // numerical values
0160       result = (vecPair_->second.second == v.vecPair_->second.second);
0161     } else {  // std::string values
0162       result = (vecPair_->second.first == v.vecPair_->second.first);
0163     }
0164   }
0165   return result;
0166 }
0167 
0168 bool DDValue::operator<(const DDValue& v) const {
0169   bool result(false);
0170   if (id() < v.id()) {
0171     result = true;
0172   } else {
0173     if (id() == v.id()) {
0174       assert(vecPair_);
0175       assert(v.vecPair_);
0176       if (vecPair_->first && v.vecPair_->first) {  // numerical values
0177         result = (vecPair_->second.second < v.vecPair_->second.second);
0178       } else {  // std::string values
0179         result = (vecPair_->second.first < v.vecPair_->second.first);
0180       }
0181     }
0182   }
0183   return result;
0184 }