Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DetectorDescription_Core_DDValue_h
0002 #define DetectorDescription_Core_DDValue_h
0003 
0004 #include <atomic>
0005 #include <iostream>
0006 #include <memory>
0007 #include <string>
0008 #include <utility>
0009 #include <vector>
0010 
0011 #include "DetectorDescription/Core/interface/DDValuePair.h"
0012 #include "oneapi/tbb/concurrent_unordered_map.h"
0013 #include "oneapi/tbb/concurrent_vector.h"
0014 #include "FWCore/Utilities/interface/zero_allocator.h"
0015 
0016 /** A DDValue std::maps a std::vector of DDValuePair (std::string,double) to a name. Names of DDValues are stored
0017  transiently. Furthermore, an ID is assigned std::mapping to the name.
0018  Use DDValue::setEvalState(true) to indicate whether the double numbers stored in
0019  the DDValuePair make sense, otherwise an exception will be thrown when trying to get access
0020  to these values via DDValue::doubles() or DDValue::operator[].
0021 */
0022 class DDValue {
0023 public:
0024   //! create a unnamed emtpy value. One can assing a named DDValue to it.
0025   DDValue(void) : id_(0), vecPair_() {}
0026 
0027   //! create a named empty value
0028   explicit DDValue(const std::string&);
0029 
0030   //! create a named empty value
0031   explicit DDValue(const char*);
0032 
0033   //! creates a named DDValue initialized with a std::vector of values
0034   explicit DDValue(const std::string&, const std::vector<DDValuePair>&);
0035 
0036   //! creates a single double valued named DDValue. The corresponding std::string-value is an empty std::string
0037   explicit DDValue(const std::string&, double);
0038 
0039   /** creates a single std::string & numerical-valued named DDValue.  */
0040   explicit DDValue(const std::string&, const std::string&, double);
0041 
0042   /** creates a single std::string-valued named DDValue */
0043   explicit DDValue(const std::string& name, const std::string& val);
0044 
0045   explicit DDValue(unsigned int);
0046 
0047   //! returns the ID of the DDValue
0048   unsigned int id(void) const { return id_; }
0049 
0050   //! converts a DDValue object into its ID
0051   operator unsigned int(void) const { return id_; }
0052 
0053   //! the name of the DDValue
0054   const std::string& name(void) const { return *(names()[id_].string_); }
0055 
0056   /** access to the values stored in DDValue by an index. Note, that
0057    the index is not checked for bounds excess! */
0058   DDValuePair operator[](unsigned int i) const;
0059 
0060   //! a reference to the std::string-valued values stored in the given instance of DDValue
0061   const std::vector<std::string>& strings() const { return vecPair_->second.first; }
0062 
0063   //! a reference to the double-valued values stored in the given instance of DDValue
0064   const std::vector<double>& doubles() const;
0065   //const DDValuePair & operator[](unsigned int i) const { return (*valPairs_)[i]  ; }
0066 
0067   //! the size of the stored value-pairs (std::string,double)
0068   unsigned int size() const { return vecPair_ ? vecPair_->second.first.size() : 0; }
0069 
0070   //! set to true, if the double-values (method DDValue::doubles()) make sense
0071   void setEvalState(bool newState);
0072 
0073   //! true, if values are numerical evaluated; else false.
0074   /** in case of a 'true' return value, the method DDValue::doubles() and the operator
0075      DDValue::operator[] can be used */
0076   bool isEvaluated(void) const;
0077 
0078   //! Two DDValues are equal only if their id() is equal AND their values are equal
0079   /** If the DDValue::isEvalued() == true, the numerical representation is taken for comparison,
0080       else the std::string representation */
0081   bool operator==(const DDValue& v) const;
0082 
0083   //! A DDValue a is smaller than a DDValue b if (a.id()<b.id()) OR (a.id()==b.id() and value(a)<value(b))
0084   bool operator<(const DDValue&) const;
0085 
0086 private:
0087   ///Only used internally
0088   struct StringHolder {
0089     StringHolder() {}
0090     explicit StringHolder(std::string iString) : string_(new std::string{std::move(iString)}) {}
0091     explicit StringHolder(StringHolder const& iOther) : string_(new std::string{*(iOther.string_)}) {}
0092     StringHolder& operator=(const StringHolder&) = delete;
0093     ~StringHolder() { delete string_.load(); }
0094 
0095     std::atomic<std::string*> string_;
0096   };
0097   struct AtomicUInt {
0098     AtomicUInt(unsigned int iValue) : value_(iValue) {}
0099     AtomicUInt() {}
0100     AtomicUInt(const AtomicUInt& iOther) : value_(iOther.value_.load()) {}
0101     AtomicUInt& operator=(const AtomicUInt& iOther) {
0102       value_ = iOther.value_.load();
0103       return *this;
0104     }
0105 
0106     std::atomic<unsigned int> value_;
0107   };
0108 
0109   void init(const std::string&);
0110 
0111   using Names = tbb::concurrent_vector<StringHolder, edm::zero_allocator<StringHolder>>;
0112   static Names& names();
0113   static Names initializeNames();
0114 
0115   using NamesToIndicies = tbb::concurrent_unordered_map<std::string, AtomicUInt>;
0116   static NamesToIndicies& indexer();
0117 
0118   unsigned int id_;
0119   using vecpair_type = std::pair<bool, std::pair<std::vector<std::string>, std::vector<double>>>;
0120   std::shared_ptr<vecpair_type> vecPair_;
0121 };
0122 
0123 std::ostream& operator<<(std::ostream& o, const DDValue& v);
0124 
0125 #endif  // DetectorDescription_Core_DDValue_h