CMS 3D CMS Logo

DDName.cc
Go to the documentation of this file.
5 
6 #include <ext/alloc_traits.h>
7 #include <cstdlib>
8 #include <sstream>
9 #include <mutex>
10 
11 std::ostream& operator<<(std::ostream& os, const DDName& n) {
12  os << n.ns() << ':' << n.name();
13  return os;
14 }
15 
16 DDName::DDName(const std::string& name, const std::string& ns) : id_(registerName(std::make_pair(name, ns))->second) {}
17 
18 DDName::DDName(const std::string& name) : id_(0) {
19  std::pair<std::string, std::string> result = DDSplit(name);
20  if (result.second.empty()) {
21  id_ = registerName(std::make_pair(result.first, DDCurrentNamespace::ns()))->second;
22  } else {
23  id_ = registerName(result)->second;
24  }
25 }
26 
27 DDName::DDName(const char* name) : id_(0) {
28  std::pair<std::string, std::string> result = DDSplit(name);
29  if (result.second.empty()) {
30  id_ = registerName(std::make_pair(result.first, DDCurrentNamespace::ns()))->second;
31  } else {
32  id_ = registerName(result)->second;
33  }
34 }
35 
36 DDName::DDName(const char* name, const char* ns)
37  : id_(registerName(std::make_pair(std::string(name), std::string(ns)))->second) {}
38 
39 DDName::DDName() : id_(0) {}
40 
41 const std::string& DDName::name() const {
42  const static std::string ano_("anonymous");
43  const std::string* result;
44  if (id_ == 0) {
45  result = &ano_;
46  } else {
48  }
49  return *result;
50 }
51 
52 const std::string& DDName::ns() const {
53  const static std::string ano_("anonymous");
54  const std::string* result;
55  if (id_ == 0) {
56  result = &ano_;
57  } else {
58  result = &DDI::Singleton<IdToName>::instance()[id_]->first.second;
59  }
60  return *result;
61 }
62 
63 namespace {
64  std::once_flag s_once;
65 } // namespace
66 
67 DDName::Registry::const_iterator DDName::registerName(const std::pair<std::string, std::string>& nm) {
68  std::call_once(s_once, []() {
71  reg.emplace(std::make_pair(std::string(""), std::string("")), 0);
72  idToName.emplace_back(reg.begin());
73  });
75 
76  Registry::const_iterator itFound = reg.find(nm);
77  if (itFound == reg.end()) {
78  //If two threads are concurrently adding the same name we will get
79  // two entries in IdToName but they will both point to the same entry
80  // to Registry where the first emplace to Registry will set the ID number.
82  auto it = idToName.emplace_back(reg.end());
83  *it = reg.emplace(nm, it - idToName.begin()).first;
84  itFound = *it;
85  }
86  return itFound;
87 }
std::ostream & operator<<(std::ostream &os, const DDName &n)
Definition: DDName.cc:11
tbb::concurrent_unordered_map< key_type, id_type, edm::StdPairHasher > Registry
Definition: DDName.h:21
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:17
static std::string & ns()
DDName()
Definition: DDName.cc:39
U second(std::pair< T, U > const &p)
static value_type & instance()
const std::string & name() const
Returns the name.
Definition: DDName.cc:41
static Registry::const_iterator registerName(const std::pair< std::string, std::string > &s)
Definition: DDName.cc:67
id_type id_
Definition: DDName.h:51
tbb::concurrent_vector< Registry::const_iterator > IdToName
Definition: DDName.h:22
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:3
const std::string & ns() const
Returns the namespace.
Definition: DDName.cc:52