Back to home page

EIC code displayed by LXR

 
 

    


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

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