Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:14

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 #ifndef DD4HEP_COMPONENTPROPERTIES_H
0014 #define DD4HEP_COMPONENTPROPERTIES_H
0015 
0016 // Framework include files
0017 #include <DD4hep/Grammar.h>
0018 
0019 // C/C++ include files
0020 #include <algorithm>
0021 #include <stdexcept>
0022 #include <typeinfo>
0023 #include <iostream>
0024 #include <sstream>
0025 #include <string>
0026 #include <map>
0027 
0028 /// Namespace for the AIDA detector description toolkit
0029 namespace dd4hep {
0030 
0031   class Property;
0032   class BasicGrammar;
0033 
0034   /// The property class to assign options to actions.
0035   /**
0036    *   Standard implementation of a property mechanism.
0037    *   The data conversion mechanism between various properties
0038    *   uses internally boost::spirit to allow also conversions
0039    *   between types, which are initially unrelated such as
0040    *   e.g. vector<int> and list<short>.
0041    *
0042    *  Note: This class cannot be saved to a ROOT file!
0043    *
0044    *  \author  M.Frank
0045    *  \version 1.0
0046    *  \ingroup DD4HEP_CORE
0047    */
0048   class Property {
0049   protected:
0050     /// Pointer to the data location
0051     void* m_par                { nullptr };
0052     /// Reference to the grammar of this property (extended type description)
0053     const BasicGrammar* m_hdl  { nullptr };
0054 
0055   public:
0056     /// Default constructor
0057     Property() = default;
0058     /// Copy constructor
0059     Property(const Property& p) = default;
0060     /// User constructor
0061     template <typename TYPE> Property(TYPE& val);
0062     /// Property type name
0063     static std::string type(const Property& proptery);
0064     /// Property type name
0065     static std::string type(const std::type_info& proptery);
0066     /// Access void data pointer
0067     void* ptr() const {      return m_par;    }
0068     /// Property type name
0069     std::string type() const;
0070     /// Access grammar object
0071     const BasicGrammar& grammar() const;
0072     /// Conversion to string value
0073     std::string str() const;
0074     /// Conversion from string value
0075     Property& str(const std::string& input);
0076     /// Conversion from string value
0077     const Property& str(const std::string& input)  const;
0078     /// Assignment operator
0079     Property& operator=(const Property& p) = default;
0080     /// Assignment operator / set new balue
0081     Property& operator=(const char* val);
0082     /// Assignment operator / set new balue
0083     //Property& operator=(const std::string& val);
0084     /// Assignment operator / set new balue
0085     template <typename TYPE> Property& operator=(const TYPE& val);
0086     /// Retrieve value
0087     template <typename TYPE> TYPE value() const;
0088     /// Retrieve value from stack (large values e.g. vectors etc.)
0089     template <typename TYPE> void value(TYPE& value) const;
0090     /// Set value of this property
0091     template <typename TYPE> void set(const TYPE& value);
0092   };
0093 
0094   /// User constructor
0095   template <typename TYPE> Property::Property(TYPE& val)
0096     : m_par(&val), m_hdl(0)
0097     {
0098       m_hdl = &BasicGrammar::get(typeid(TYPE));
0099     }
0100 
0101   /// Set value of this property
0102   template <typename TYPE> void Property::set(const TYPE& val) {
0103     const auto& grm = grammar();
0104     if (grm.type() == typeid(TYPE))
0105       *(TYPE*) m_par = val;
0106     else if (!grm.fromString(m_par, BasicGrammar::instance< TYPE >().str(&val)))
0107       BasicGrammar::invalidConversion(typeid(TYPE), grm.type());
0108   }
0109 
0110   /// Assignment operator / set new balue
0111   template <typename TYPE> Property& Property::operator=(const TYPE& val) {
0112     this->set(val);
0113     return *this;
0114   }
0115 
0116   /// Retrieve value from stack (large values e.g. vectors etc.)
0117   template <typename TYPE> void Property::value(TYPE& val) const {
0118     const auto& grm = grammar();
0119     if (grm.type() == typeid(TYPE))
0120       val = *(TYPE*) m_par;
0121     else if (!BasicGrammar::instance< TYPE >().fromString(&val, this->str()))
0122       BasicGrammar::invalidConversion(grm.type(), typeid(TYPE));
0123   }
0124 
0125   /// Retrieve value
0126   template <typename TYPE> TYPE Property::value() const {
0127     TYPE temp;
0128     this->value(temp);
0129     return temp;
0130   }
0131 
0132   /// Concrete template instantiation of a combined property value pair.
0133   /**
0134    *  Note: This class cannot be saved to a ROOT file!
0135    *
0136    *  \author  M.Frank
0137    *  \version 1.0
0138    *  \ingroup DD4HEP_CORE
0139    */
0140   template <class TYPE> class PropertyValue : private Property {
0141   public:
0142     TYPE data  {};
0143     /// Default constructor
0144     PropertyValue() : Property(data) {}
0145     /// Copy constructor
0146     PropertyValue(const PropertyValue& c) = default;
0147     /// Assignment operator
0148     PropertyValue& operator=(const PropertyValue& c) = default;
0149     /// Assignment operator
0150     PropertyValue& operator=(const TYPE& val) { data = val; return *this;      }
0151     /// Equality operator
0152     bool operator==(const TYPE& val) const { return val == data;               }
0153     /// Access grammar object
0154     const BasicGrammar& grammar() const    { return this->Property::grammar(); }
0155     /// Conversion to string value
0156     std::string str() const                { return this->Property::str();     }
0157     /// Retrieve value with data conversion
0158     template <typename T> T value() const  { return this->Property::value<T>();}
0159     /// Retrieve value from stack with data conversion (large values e.g. vectors etc.)
0160     template <typename T>
0161     void value(TYPE& val) const            { this->Property::value(val);       }
0162     /// Set value of this property with data conversion
0163     template <typename T> void set(const T& val)  { this->Property::set(val);  }
0164   };
0165 
0166   /// Manager to ease the handling of groups of properties.
0167   /**
0168    *  Note: This class cannot be saved to a ROOT file!
0169    *
0170    *  \author  M.Frank
0171    *  \version 1.0
0172    *  \ingroup DD4HEP_CORE
0173    */
0174   class PropertyManager {
0175   public:
0176     /// Property array definition
0177     typedef std::map<std::string, Property> Properties;
0178   protected:
0179     /// Property array/map
0180     Properties m_properties;
0181 
0182     /// Verify that this property does not exist (throw exception if the name was found)
0183     void verifyNonExistence(const std::string& name) const;
0184     /// Verify that this property exists (throw exception if the name was not found)
0185     Properties::iterator verifyExistence(const std::string& name);
0186     /// Verify that this property exists (throw exception if the name was not found)
0187     Properties::const_iterator verifyExistence(const std::string& name) const;
0188 
0189   public:
0190     /// Default constructor
0191     PropertyManager();
0192     /// Default destructor
0193     virtual ~PropertyManager();
0194     /// Access total number of properties
0195     size_t size()  const;
0196     /// Check for existence
0197     bool exists(const std::string& name) const;
0198     /// Access to the property container
0199     Properties& properties()  {  return m_properties;  }
0200     /// Access to the property container
0201     const Properties& properties()  const  {  return m_properties;  }
0202     /// Access property by name (CONST)
0203     const Property& property(const std::string& name) const;
0204     /// Access property by name
0205     Property& property(const std::string& name);
0206     /// Access property by name
0207     Property& operator[](const std::string& name);
0208     /// Access property by name
0209     const Property& operator[](const std::string& name) const;
0210     /// Add a new property
0211     void add(const std::string& name, const Property& property);
0212     /// Add a new property
0213     template <typename T> void add(const std::string& name, T& value)   {
0214       add(name, Property(value));
0215     }
0216     /// Apply functor on properties
0217     template <typename FUNCTOR> void for_each(FUNCTOR& func)   {
0218       std::for_each(m_properties.begin(), m_properties.end(), func);
0219     }
0220     /// Apply functor on properties
0221     template <typename FUNCTOR> void for_each(const FUNCTOR& func)   {
0222       std::for_each(m_properties.begin(), m_properties.end(), func);
0223     }
0224     /// Import properties of another instance
0225     void adopt(const PropertyManager& copy);
0226     /// Dump string values
0227     void dump() const;
0228   };
0229 
0230   /// Property object as base class for all objects supporting properties
0231   /** 
0232    *  Note: This class cannot be saved to a ROOT file!
0233    *
0234    *  \author  M.Frank
0235    *  \version 1.0
0236    */
0237   class PropertyInterface  {
0238   public:
0239     /// Default destructor
0240     virtual ~PropertyInterface() = default;
0241     /// Access to the properties of the object
0242     virtual PropertyManager& properties() = 0;
0243     /// Access to the properties of the object
0244     virtual const PropertyManager& properties() const = 0;
0245     /// Check property for existence
0246     virtual bool hasProperty(const std::string& name) const = 0;
0247     /// Access single property
0248     virtual Property& property(const std::string& name) = 0;
0249   };
0250   
0251   /// Property object as base class for all objects supporting properties
0252   /** 
0253    *  Note: This class cannot be saved to a ROOT file!
0254    *
0255    *  \author  M.Frank
0256    *  \version 1.0
0257    */
0258   class PropertyConfigurable : virtual public PropertyInterface {
0259   protected:
0260     /// Property pool
0261     PropertyManager m_properties;
0262 
0263   public:
0264     /// Standard constructor
0265     PropertyConfigurable();
0266     /// Default destructor
0267     virtual ~PropertyConfigurable();
0268     /// Access to the properties of the object
0269     virtual PropertyManager& properties() override {
0270       return m_properties;
0271     }
0272     /// Access to the properties of the object
0273     virtual const PropertyManager& properties() const override {
0274       return m_properties;
0275     }
0276     /// Check property for existence
0277     virtual bool hasProperty(const std::string& name) const override;
0278     /// Access single property
0279     virtual Property& property(const std::string& name) override;
0280     /// Declare property
0281     template <typename T> void declareProperty(const std::string& nam, T& val);
0282     /// Declare property
0283     template <typename T> void declareProperty(const char* nam, T& val);
0284   };
0285 
0286   /// Declare property
0287   template <typename T> 
0288   void PropertyConfigurable::declareProperty(const std::string& nam, T& val) {
0289     m_properties.add(nam, val);
0290   }
0291 
0292   /// Declare property
0293   template <typename T> 
0294   void PropertyConfigurable::declareProperty(const char* nam, T& val) {
0295     m_properties.add(nam, val);
0296   }
0297 
0298 }      // End namespace dd4hep
0299 #endif // DD4HEP_COMPONENTPROPERTIES_H