CMS 3D CMS Logo

DDValue.cc
Go to the documentation of this file.
2 
6 
7 #include <cassert>
8 
11 
12 static std::atomic<unsigned int> lastIndex{0};
13 
15  auto result = indexer().insert({name, 0});
16 
17  auto& indexToUse = result.first->second;
18 
19  //A 0 index means either
20  // 1) this result was just added or
21  // 2) another thread just added this but has not yet assigned an index
22  if (0 == indexToUse.value_) {
23  auto newIndex = ++lastIndex;
24  unsigned int previous = 0;
25  indexToUse.value_.compare_exchange_strong(previous, newIndex);
26  }
27  id_ = indexToUse.value_.load();
28 
29  //Make sure the name is recorded at the proper index
30  auto& allNames = names();
31  allNames.grow_to_at_least(id_ + 1);
32  auto& storedName = allNames[id_];
33  if (not storedName.string_) {
34  std::unique_ptr<std::string> newName(new std::string{name});
35  std::string* previous = nullptr;
36  if (storedName.string_.compare_exchange_strong(previous, newName.get())) {
37  newName.release();
38  }
39  }
40 }
41 
42 DDValue::DDValue(const std::string& name) : id_(0), vecPair_() { init(name); }
43 
44 DDValue::DDValue(const char* name) : id_(0), vecPair_() { init(name); }
45 
46 DDValue::DDValue(const std::string& name, const std::vector<DDValuePair>& v) : id_(0) {
47  init(name);
48 
49  auto it = v.begin();
50  std::vector<std::string> svec;
51  std::vector<double> dvec;
52  vecPair_.reset(new vecpair_type(false, std::make_pair(svec, dvec)));
53  for (; it != v.end(); ++it) {
54  vecPair_->second.first.emplace_back(it->first);
55  vecPair_->second.second.emplace_back(it->second);
56  }
57 }
58 
59 DDValue::DDValue(const std::string& name, double val) : id_(0) {
60  init(name);
61 
62  std::vector<std::string> svec(1, "");
63  std::vector<double> dvec(1, val);
64 
65  vecPair_.reset(new vecpair_type(false, std::make_pair(svec, dvec)));
66  setEvalState(true);
67 }
68 
69 DDValue::DDValue(const std::string& name, const std::string& sval, double dval) : id_(0) {
70  init(name);
71 
72  std::vector<std::string> svec(1, sval);
73  std::vector<double> dvec(1, dval);
74  vecPair_.reset(new vecpair_type(false, std::make_pair(svec, dvec)));
75  setEvalState(true);
76 }
77 
78 DDValue::DDValue(const std::string& name, const std::string& sval) : id_(0) {
79  init(name);
80 
81  std::vector<std::string> svec(1, sval);
82  std::vector<double> dvec(1, 0);
83  vecPair_.reset(new vecpair_type(false, std::make_pair(svec, dvec)));
84  setEvalState(false);
85 }
86 
87 DDValue::DDValue(unsigned int i) : id_(0), vecPair_() {
88  if (lastIndex >= i)
89  id_ = i;
90 }
91 
93  static NamesToIndicies indexer_;
94  return indexer_;
95 }
96 
98  //Make sure memory is zeroed before allocating StringHolder
99  // this allows us to check the value of the held std::atomic
100  // as the object is being added to the container
102  names.emplace_back(StringHolder(std::string{}));
103  return names;
104 }
105 
107  static Names names_{initializeNames()};
108  return names_;
109 }
110 
111 const std::vector<double>& DDValue::doubles(void) const {
112  if (vecPair_->first) {
113  return vecPair_->second.second;
114  } else {
115  std::string message = "DDValue " + name() + " is not numerically evaluated! Use DDValue::std::strings()!";
116  edm::LogError("DDValue") << message << std::endl;
117  throw cms::Exception("DDException") << message;
118  }
119 }
120 
121 std::ostream& operator<<(std::ostream& o, const DDValue& v) {
122  o << v.name() << " = ";
123  unsigned int i = 0;
124  if (v.isEvaluated()) {
125  for (; i < v.size(); ++i) {
126  o << '(' << v[i].first << ',' << v[i].second << ") ";
127  }
128  } else {
129  const std::vector<std::string>& s = v.strings();
130  for (; i < v.size(); ++i) {
131  o << s[i] << ' ';
132  }
133  }
134  return o;
135 }
136 
137 //FIXME move it elsewhere; DO NOT put out the name for now... need to fix DDCoreToDDXMLOutput
138 std::ostream& operator<<(std::ostream& o, const DDValuePair& v) { return o << v.second; }
139 
140 DDValuePair DDValue::operator[](unsigned int i) const {
141  if (vecPair_->first) {
142  return DDValuePair(vecPair_->second.first[i], vecPair_->second.second[i]);
143  } else {
144  std::string message = "DDValue " + name() + " is not numerically evaluated! Use DDValue::std::strings()!";
145  edm::LogError("DDValue") << message;
146  throw cms::Exception("DDException") << message;
147  }
148 }
149 
150 void DDValue::setEvalState(bool newState) { vecPair_->first = newState; }
151 
152 bool DDValue::isEvaluated(void) const { return vecPair_->first; }
153 
154 bool DDValue::operator==(const DDValue& v) const {
155  bool result(false);
156  if (id() == v.id()) {
157  assert(vecPair_);
158  assert(v.vecPair_);
159  if (vecPair_->first) { // numerical values
160  result = (vecPair_->second.second == v.vecPair_->second.second);
161  } else { // std::string values
162  result = (vecPair_->second.first == v.vecPair_->second.first);
163  }
164  }
165  return result;
166 }
167 
168 bool DDValue::operator<(const DDValue& v) const {
169  bool result(false);
170  if (id() < v.id()) {
171  result = true;
172  } else {
173  if (id() == v.id()) {
174  assert(vecPair_);
175  assert(v.vecPair_);
176  if (vecPair_->first && v.vecPair_->first) { // numerical values
177  result = (vecPair_->second.second < v.vecPair_->second.second);
178  } else { // std::string values
179  result = (vecPair_->second.first < v.vecPair_->second.first);
180  }
181  }
182  }
183  return result;
184 }
std::pair< bool, std::pair< std::vector< std::string >, std::vector< double > >> vecpair_type
Definition: DDValue.h:119
bool operator<(const DDValue &) const
A DDValue a is smaller than a DDValue b if (a.id()<b.id()) OR (a.id()==b.id() and value(a)<value(b)) ...
Definition: DDValue.cc:168
DDValue(void)
create a unnamed emtpy value. One can assing a named DDValue to it.
Definition: DDValue.h:25
bool isEvaluated(void) const
true, if values are numerical evaluated; else false.
Definition: DDValue.cc:152
Only used internally.
Definition: DDValue.h:88
static Names & names()
Definition: DDValue.cc:106
const std::vector< double > & doubles() const
a reference to the double-valued values stored in the given instance of DDValue
Definition: DDValue.cc:111
tbb::concurrent_vector< StringHolder, edm::zero_allocator< StringHolder > > Names
Definition: DDValue.h:111
void setEvalState(bool newState)
set to true, if the double-values (method DDValue::doubles()) make sense
Definition: DDValue.cc:150
string newName
Definition: mps_merge.py:86
Log< level::Error, false > LogError
assert(be >=bs)
DDValuePair operator[](unsigned int i) const
Definition: DDValue.cc:140
tbb::concurrent_unordered_map< std::string, AtomicUInt > NamesToIndicies
Definition: DDValue.h:115
static Names initializeNames()
Definition: DDValue.cc:97
unsigned int id_
Definition: DDValue.h:118
static NamesToIndicies & indexer()
Definition: DDValue.cc:92
void init(const std::string &)
Definition: DDValue.cc:14
static std::atomic< unsigned int > lastIndex
Definition: DDValue.cc:12
std::shared_ptr< vecpair_type > vecPair_
Definition: DDValue.h:120
const std::string & name(void) const
the name of the DDValue
Definition: DDValue.h:54
std::ostream & operator<<(std::ostream &o, const DDValue &v)
Definition: DDValue.cc:121
bool operator==(const DDValue &v) const
Two DDValues are equal only if their id() is equal AND their values are equal.
Definition: DDValue.cc:154