Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:54:57

0001 #include "DetectorDescription/Core/interface/DDName.h"
0002 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
0003 #include "DetectorDescription/Core/interface/DDSplit.h"
0004 #include "DetectorDescription/Core/interface/Singleton.h"
0005 
0006 #include <ext/alloc_traits.h>
0007 #include <cstdlib>
0008 #include <sstream>
0009 #include <mutex>
0010 
0011 std::ostream& operator<<(std::ostream& os, const DDName& n) {
0012   os << n.ns() << ':' << n.name();
0013   return os;
0014 }
0015 
0016 DDName::DDName(const std::string& name, const std::string& ns) : id_(registerName(std::make_pair(name, ns))->second) {}
0017 
0018 DDName::DDName(const std::string& name) : id_(0) {
0019   std::pair<std::string, std::string> result = DDSplit(name);
0020   if (result.second.empty()) {
0021     id_ = registerName(std::make_pair(result.first, DDCurrentNamespace::ns()))->second;
0022   } else {
0023     id_ = registerName(result)->second;
0024   }
0025 }
0026 
0027 DDName::DDName(const char* name) : id_(0) {
0028   std::pair<std::string, std::string> result = DDSplit(name);
0029   if (result.second.empty()) {
0030     id_ = registerName(std::make_pair(result.first, DDCurrentNamespace::ns()))->second;
0031   } else {
0032     id_ = registerName(result)->second;
0033   }
0034 }
0035 
0036 DDName::DDName(const char* name, const char* ns)
0037     : id_(registerName(std::make_pair(std::string(name), std::string(ns)))->second) {}
0038 
0039 DDName::DDName() : id_(0) {}
0040 
0041 const std::string& DDName::name() const {
0042   const static std::string ano_("anonymous");
0043   const std::string* result;
0044   if (id_ == 0) {
0045     result = &ano_;
0046   } else {
0047     result = &DDI::Singleton<IdToName>::instance()[id_]->first.first;
0048   }
0049   return *result;
0050 }
0051 
0052 const std::string& DDName::ns() const {
0053   const static std::string ano_("anonymous");
0054   const std::string* result;
0055   if (id_ == 0) {
0056     result = &ano_;
0057   } else {
0058     result = &DDI::Singleton<IdToName>::instance()[id_]->first.second;
0059   }
0060   return *result;
0061 }
0062 
0063 namespace {
0064   std::once_flag s_once;
0065 }  // namespace
0066 
0067 DDName::Registry::const_iterator DDName::registerName(const std::pair<std::string, std::string>& nm) {
0068   std::call_once(s_once, []() {
0069     Registry& reg = DDI::Singleton<Registry>::instance();
0070     IdToName& idToName = DDI::Singleton<IdToName>::instance();
0071     reg.emplace(std::make_pair(std::string(""), std::string("")), 0);
0072     idToName.emplace_back(reg.begin());
0073   });
0074   Registry& reg = DDI::Singleton<Registry>::instance();
0075 
0076   Registry::const_iterator itFound = reg.find(nm);
0077   if (itFound == reg.end()) {
0078     //If two threads are concurrently adding the same name we will get
0079     // two entries in IdToName but they will both point to the same entry
0080     // to Registry where the first emplace to Registry will set the ID number.
0081     IdToName& idToName = DDI::Singleton<IdToName>::instance();
0082     auto it = idToName.emplace_back(reg.end());
0083     *it = reg.emplace(nm, it - idToName.begin()).first;
0084     itFound = *it;
0085   }
0086   return itFound;
0087 }