Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:52: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 //
0014 // NOTE:
0015 //
0016 // This is an internal include file. It should only be included to 
0017 // instantiate code. Otherwise the BasicGrammar include file should be
0018 // sufficient for all practical purposes.
0019 //
0020 //==========================================================================
0021 #ifndef DD4HEP_GRAMMAR_H
0022 #define DD4HEP_GRAMMAR_H
0023 
0024 // Framework include files
0025 #include <DD4hep/config.h>
0026 #include <DD4hep/Primitives.h>
0027 
0028 // C/C++ include files
0029 #include <string>
0030 #include <typeinfo>
0031 
0032 // Forward declarations
0033 class TClass;
0034 
0035 /// Namespace for the AIDA detector description toolkit
0036 namespace dd4hep {
0037 
0038   /// Forward declarations
0039   class GrammarRegistry;
0040   
0041   /// Base class describing string evaluation to C++ objects using boost::spirit
0042   /**
0043    *   Grammar object handle the boost::spirit conversion between strings and numeric
0044    *   values/objects. Numeric objects could be atomic (int, long, float, double, etc)
0045    *   or complex (vector<int>, vector<float>...). This way e.g. a vector<int> may
0046    *   be converted into a list<double>. The conversion though requires an intermediate
0047    *   string representation. For this reason the conversion mechanism is relatively
0048    *   slow and hence should not be used inside number-crunching algorithms.
0049    *
0050    *   \author  M.Frank
0051    *   \version 1.0
0052    *   \date    13.08.2013
0053    *   \ingroup DD4HEP
0054    */
0055   class BasicGrammar {
0056     friend class GrammarRegistry;
0057   public:
0058     typedef unsigned long long int key_type;
0059     /// Instance type name
0060     const std::string   name;
0061     /// Instance hash code
0062     const key_type      hash_value     = 0;
0063     /// Cached TClass reference for speed improvements
0064     mutable TClass*     root_class     = 0;
0065     /// Cached TDataType information for fundamental types
0066     mutable int         root_data_type = -1;
0067     /// Initialization flag
0068     mutable bool        inited         = false;
0069 
0070     /// Structure to be filled if automatic object parsing from string is supposed to be supported
0071     struct specialization_t   {
0072       /// Ponter to ABI Cast structure
0073       const Cast* cast = 0;
0074       /// Bind opaque address to object
0075       void (*bind)(void* pointer) = 0;
0076       /// Opaque copy constructor
0077       void (*copy)(void* to, const void* from) = 0;
0078       /// PropertyGrammar overload: Serialize a property to a string
0079       std::string (*str)(const BasicGrammar& gr, const void* ptr) = 0;
0080       /// PropertyGrammar overload: Retrieve value from string
0081       bool (*fromString)(const BasicGrammar& gr, void* ptr, const std::string& value) = 0;
0082       /// Evaluate string value if possible before calling boost::spirit
0083       int  (*eval)(const BasicGrammar& gr, void* ptr, const std::string& val) = 0;
0084       /// Default constructor
0085       specialization_t() = default;
0086       /// Move constructor
0087       specialization_t(specialization_t&& copy) = default;
0088       /// Copy constructor
0089       specialization_t(const specialization_t& copy) = default;
0090       /// Move assignment
0091       specialization_t& operator=(specialization_t&& copy) = default;
0092       /// Copy assignment
0093       specialization_t& operator=(const specialization_t& copy) = default;
0094       /// Equality operator
0095       bool operator==(const specialization_t& copy)  const;
0096     } specialization;
0097     
0098   protected:
0099     /// Default constructor
0100     BasicGrammar(const std::string& typ);
0101 
0102     /// Default destructor
0103     virtual ~BasicGrammar();
0104 
0105     /// Second step initialization after the virtual table is fixed
0106     void    initialize()   const;
0107     int     initialized_data_type()  const;
0108     TClass* initialized_clazz()  const;
0109 
0110     
0111     /// Instance factory
0112     static void pre_note(const std::type_info& info, const BasicGrammar& (*fcn)(), specialization_t specs);
0113     
0114   public:
0115     /// Instance factory
0116     template <typename TYPE> static const BasicGrammar& instance();
0117     /// Access grammar by type info
0118     static const BasicGrammar& get(const std::type_info& info);
0119     /// Lookup existing grammar using the grammar's hash code/hash64(type-name) (used for reading objects)
0120     static const BasicGrammar& get(unsigned long long int hash_code);
0121     /// Error callback on invalid conversion
0122     static void invalidConversion(const std::type_info& from, const std::type_info& to);
0123     /// Error callback on invalid conversion
0124     static void invalidConversion(const std::string& value, const std::type_info& to);
0125 
0126     /// Access the hash value for this grammar type
0127     key_type hash() const                 {  return hash_value;   }
0128     /// Access to the type information name
0129     const std::string& type_name() const  {  return name;         }
0130     /// Access ROOT data type for fundamentals
0131     int data_type()  const  {
0132       if ( inited ) return root_data_type;
0133       return initialized_data_type();
0134     }
0135     /// Access the ROOT class for complex objects
0136     TClass* clazz()  const   {
0137       if ( inited ) return root_class;
0138       return initialized_clazz();
0139     }
0140     /// Set cast structure
0141     virtual void setCast(const Cast* cast)  const;
0142     /// Access ABI object cast
0143     virtual const Cast& cast() const;
0144     /// Access to the type information
0145     virtual bool equals(const std::type_info& other_type) const = 0;
0146     /// Access to the type information
0147     virtual const std::type_info& type() const = 0;
0148     /// Access the object size (sizeof operator)
0149     virtual size_t sizeOf() const = 0;
0150     /// Opaque object destructor
0151     virtual void destruct(void* pointer) const = 0;
0152     /// Serialize an opaque value to a string
0153     virtual std::string str(const void* ptr) const;
0154     /// Set value from serialized string. On successful data conversion TRUE is returned.
0155     virtual bool fromString(void* ptr, const std::string& value) const;
0156     /// Evaluate string value if possible before calling boost::spirit
0157     virtual int evaluate(void* ptr, const std::string& value) const;
0158   };
0159 
0160   /// Concrete type dependent grammar definition
0161   /**
0162    *   \author  M.Frank
0163    *   \date    13.08.2013
0164    *   \ingroup DD4HEP
0165    */
0166   template <typename TYPE> class Grammar : public BasicGrammar {
0167   private:
0168     
0169     friend class BasicGrammar;
0170     /// Default destructor
0171     virtual ~Grammar();
0172     /// Standard constructor
0173     Grammar();
0174 
0175   public:
0176     typedef TYPE type_t;
0177     
0178     /** Base class overrides   */
0179     /// PropertyGrammar overload: Access to the type information
0180     virtual const std::type_info& type() const  override;
0181     /// Access to the type information
0182     virtual bool equals(const std::type_info& other_type) const  override;
0183     /// Access the object size (sizeof operator)
0184     virtual size_t sizeOf() const  override;
0185     /// Opaque object destructor
0186     virtual void destruct(void* pointer) const  override;
0187     /// Bind opaque address to object
0188     template <typename... Args> void construct(void* pointer, Args... args)  const;
0189   };
0190 
0191   /// Standarsd constructor
0192   template <typename TYPE> Grammar<TYPE>::Grammar()
0193     : BasicGrammar(typeName(typeid(TYPE)))
0194   {
0195   }
0196 
0197   /// Default destructor
0198   template <typename TYPE> Grammar<TYPE>::~Grammar() {
0199   }
0200 
0201   /// PropertyGrammar overload: Access to the type information
0202   template <typename TYPE> const std::type_info& Grammar<TYPE>::type() const {
0203     return typeid(TYPE);
0204   }
0205 
0206   /// Access to the type information
0207   template <typename TYPE> bool Grammar<TYPE>::equals(const std::type_info& other_type) const  {
0208     return other_type == typeid(TYPE);
0209   }
0210   
0211   /// Access the object size (sizeof operator)
0212   template <typename TYPE> size_t Grammar<TYPE>::sizeOf() const   {
0213     return sizeof(TYPE);
0214   }
0215 
0216   /// Opaque object destructor
0217   template <typename TYPE> void Grammar<TYPE>::destruct(void* pointer) const   {
0218     TYPE* obj = (TYPE*)pointer;
0219     obj->~TYPE();
0220   }
0221 
0222   /// Bind opaque address to object
0223   template <typename TYPE> template <typename... Args>
0224   void Grammar<TYPE>::construct(void* pointer, Args... args)  const  {
0225     new(pointer) TYPE(std::forward<Args>(args)...);
0226   }
0227 
0228   /// Grammar registry interface
0229   /**
0230    *   \author  M.Frank
0231    *   \date    13.08.2013
0232    *   \ingroup DD4HEP
0233    */
0234   class GrammarRegistry {
0235     /// Default constructor
0236     GrammarRegistry() = default;
0237     /// PropertyGrammar overload: Serialize a property to a string
0238     template <typename T> static std::string str(const BasicGrammar&, const void*)  { return ""; }
0239   public:
0240     /// Registry instance singleton
0241     static const GrammarRegistry& instance();
0242     
0243     template <typename T> static const GrammarRegistry& pre_note_specs(BasicGrammar::specialization_t specs)   {
0244       void (Grammar<T>::*destruct)(void*) const = &Grammar<T>::destruct;
0245       if ( !destruct ) {
0246         BasicGrammar::invalidConversion("Grammar",typeid(T));
0247       }
0248       BasicGrammar::pre_note(typeid(T), BasicGrammar::instance<T>, specs);
0249       return instance();
0250     }
0251     template <typename T> static const GrammarRegistry& pre_note(int)   {
0252       BasicGrammar::specialization_t spec;
0253       spec.bind = detail::constructObject<T>;
0254       spec.copy = detail::copyObject<T>;
0255       spec.str  = GrammarRegistry::str<T>;
0256       return pre_note_specs<T>(spec);
0257     }
0258     template <typename T> static const GrammarRegistry& pre_note()   {
0259       return pre_note_specs<T>({});
0260     }
0261   };
0262 }
0263 #endif // DD4HEP_GRAMMAR_H