Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-20 03:13:31

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