Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-03 08:34:19

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_OPAQUEDATA_H
0014 #define DD4HEP_OPAQUEDATA_H
0015 
0016 // Framework include files
0017 #include <DD4hep/Grammar.h>
0018 
0019 // C/C++ include files
0020 #include <typeinfo>
0021 #include <string>
0022 
0023 /// Namespace for the AIDA detector description toolkit
0024 namespace dd4hep {
0025 
0026   // Forward declarations
0027   class BasicGrammar;
0028 
0029   /// Class describing an opaque data block
0030   /**
0031    *  Access methods are templated. Once the access is fixed
0032    *  on the first call, the data type may not be changed anymore.
0033    *
0034    *  \author  M.Frank
0035    *  \version 1.0
0036    *  \ingroup DD4HEP_CONDITIONS
0037    */
0038   class OpaqueData   {
0039   private:
0040   protected:
0041     /// Standard initializing constructor
0042     OpaqueData() = default;
0043     /// Standard Destructor
0044     virtual ~OpaqueData() = default;
0045     /// Copy constructor
0046     OpaqueData(const OpaqueData& copy) = default;
0047     /// Assignment operator
0048     OpaqueData& operator=(const OpaqueData& copy) = default;
0049 
0050   public:
0051     /// Data type
0052     const BasicGrammar* grammar = 0;  //! No ROOT persistency
0053 
0054   protected:
0055     /// Pointer to object data
0056     void* pointer = 0;                //! No ROOT persistency
0057 
0058   public:
0059     /// Create data block from string representation
0060     bool fromString(const std::string& rep);
0061     /// Create string representation of the data block
0062     std::string str()  const;
0063     /// Access type id of the condition
0064     const std::type_info& typeInfo() const;
0065     /// Access type name of the condition data block
0066     const std::string& dataType() const;
0067     /// Access to the data buffer (read only!). Is only valid after call to bind<T>()
0068     const void* ptr()  const {  return pointer;      }
0069     /// Check if object is already bound....
0070     bool is_bound()  const   {  return 0 != pointer; }
0071     /// Generic getter. Specify the exact type, not a polymorph type
0072     template <typename T> T& get();
0073     /// Generic getter (const version). Specify the exact type, not a polymorph type
0074     template <typename T> const T& get() const;
0075     /// Generic getter. Resolves polymorph types. It is mandatory that the datatype is polymorph!
0076     template <typename T> T& as();
0077     /// Generic getter (const version). Resolves polymorph types. It is mandatory that the datatype is polymorph!
0078     template <typename T> const T& as() const;
0079   };
0080 
0081   
0082   /// Class describing an opaque conditions data block
0083   /**
0084    *  This class is used to handle the actual data IO.
0085    *  Hence, we have write access to the data in abstract form.
0086    *
0087    *  \author  M.Frank
0088    *  \version 1.0
0089    *  \ingroup DD4HEP_CONDITIONS
0090    */
0091   class OpaqueDataBlock : public OpaqueData   {
0092 
0093   public:
0094     /// Buffer size of the in-place data buffer
0095     constexpr static const size_t BUFFER_SIZE = 40;
0096 
0097   protected:
0098     /// Data buffer: plain data are allocated directly on this buffer
0099     /** This internal data buffer is sufficient to store any 
0100      *  STL vector, list, map, etc. and hence should be sufficient to
0101      *  probably store normal relatively primitive basic objects.
0102      *
0103      *  It appears that on clang the size of std::any is 32 bytes (16 bytes on g++_,
0104      *  whereas the size of std::vector is 24. Lets take 40 bytes and check it in the 
0105      *  Conditions_any_basic example...
0106      */
0107     unsigned char data[BUFFER_SIZE];
0108 
0109   public:
0110     enum _DataTypes  {
0111       PLAIN_DATA  =  1<<0,
0112       ALLOC_DATA  =  1<<1,
0113       STACK_DATA  =  1<<2,
0114       BOUND_DATA  =  1<<3,
0115       EXTERN_DATA =  1<<4
0116     };
0117     /// Data buffer type: Must be a bitmap of enum _DataTypes!
0118     unsigned int type;
0119 
0120   public:
0121     /// Standard initializing constructor
0122     OpaqueDataBlock();
0123     /// Initializing constructor binding data to buffer with move
0124     template <typename OBJECT> OpaqueDataBlock(OBJECT&& data);
0125     /// Copy constructor (Required by ROOT dictionaries)
0126     OpaqueDataBlock(const OpaqueDataBlock& copy);
0127     /// Standard Destructor
0128     ~OpaqueDataBlock();
0129     /// Assignment operator (Required by ROOT dictionaries)
0130     OpaqueDataBlock& operator=(const OpaqueDataBlock& copy);
0131     /// Write access to the data buffer. Is only valid after call to bind<T>()
0132     void* ptr()  const {  return pointer;      }
0133     /// Bind data value
0134     void* bind(const BasicGrammar* grammar);
0135     /// Bind data value in place
0136     void* bind(void* ptr, size_t len, const BasicGrammar* grammar);
0137     /// Bind external data value to the pointer
0138     void bindExtern(void* ptr, const BasicGrammar* grammar);
0139     /// Construct conditions object and bind the data
0140     template <typename T, typename... Args> T& construct(Args... args);
0141     /// Bind data value
0142     template <typename T> T& bind();
0143     /// Bind data value
0144     template <typename T> T& bind(void* ptr, size_t len);
0145     /// Bind data value
0146     template <typename T> T& bind(const std::string& value);
0147     /// Bind data value
0148     template <typename T> T& bind(void* ptr, size_t len, const std::string& value);
0149     /// Bind data value
0150     template <typename T> T& bind(T&& data);
0151     /// Bind external data value to the pointer
0152     template <typename T> void bindExtern(T* ptr);
0153   };
0154 
0155   /// Generic getter. Specify the exact type, not a polymorph type
0156   template <typename T> inline T& OpaqueData::get() {
0157     if (!grammar || !grammar->equals(typeid(T))) { throw std::bad_cast(); }
0158     return *(T*)pointer;
0159   }
0160 
0161   /// Generic getter (const version). Specify the exact type, not a polymorph type
0162   template <typename T> inline const T& OpaqueData::get() const {
0163     if (!grammar || !grammar->equals(typeid(T))) { throw std::bad_cast(); }
0164     return *(T*)pointer;
0165   }
0166 
0167   /// Generic getter. Specify the exact type, not a polymorph type
0168   template <typename T> inline T& OpaqueData::as() {
0169     if ( grammar )   {
0170       T* obj = (T*)(grammar->cast().apply_dynCast(Cast::instance<T>(), this->pointer));
0171       if ( obj ) return *obj;
0172     }
0173     throw std::bad_cast();
0174   }
0175 
0176   /// Generic getter (const version). Specify the exact type, not a polymorph type
0177   template <typename T> inline const T& OpaqueData::as() const {
0178     if ( grammar )   {
0179       const T* obj = (const T*)(grammar->cast().apply_dynCast(Cast::instance<T>(), this->pointer));
0180       if ( obj ) return *obj;
0181     }
0182     throw std::bad_cast();
0183   }
0184 
0185   /// Initializing constructor binding data to buffer with move
0186   template <typename OBJECT> OpaqueDataBlock::OpaqueDataBlock(OBJECT&& obj)    {
0187     this->bind(&BasicGrammar::instance<OBJECT>());
0188     new(this->pointer) OBJECT(std::move(obj));
0189   }
0190 
0191   /// Construct conditions object and bind the data
0192   template <typename T, typename... Args> inline T& OpaqueDataBlock::construct(Args... args)   {
0193     this->bind(&BasicGrammar::instance<T>());
0194     return *(new(this->pointer) T(std::forward<Args>(args)...));
0195   }
0196 
0197   /// Bind data value
0198   template <typename T> inline T& OpaqueDataBlock::bind()  {
0199     this->bind(&BasicGrammar::instance<T>());
0200     return *(new(this->pointer) T());
0201   }
0202 
0203   /// Bind data value
0204   template <typename T> inline T& OpaqueDataBlock::bind(T&& obj)   {
0205     this->bind(&BasicGrammar::instance<T>());
0206     new(this->pointer) T(std::move(obj));
0207   }
0208 
0209   /// Bind data value
0210   template <typename T> inline T& OpaqueDataBlock::bind(void* ptr, size_t len)  {
0211     this->bind(ptr,len,&BasicGrammar::instance<T>());
0212     return *(new(this->pointer) T());
0213   }
0214 
0215   /// Bind grammar and assign value
0216   template <typename T> inline T& OpaqueDataBlock::bind(const std::string& value)   {
0217     T& ret = this->bind<T>();
0218     if ( !value.empty() && !this->fromString(value) )  {
0219       throw std::runtime_error("OpaqueDataBlock::set> Failed to bind type "+
0220                                typeName(typeid(T))+" to condition data block.");
0221     }
0222     return ret;
0223   }
0224 
0225   /// Bind grammar and assign value
0226   template <typename T> inline T& OpaqueDataBlock::bind(void* ptr, size_t len, const std::string& value)   {
0227     T& ret = this->bind<T>(ptr, len);
0228     if ( !value.empty() && !this->fromString(value) )  {
0229       throw std::runtime_error("OpaqueDataBlock::set> Failed to bind type "+
0230                                typeName(typeid(T))+" to condition data block.");
0231     }
0232     return ret;
0233   }
0234   /// Bind external data value to the pointer
0235   template <typename T> inline void OpaqueDataBlock::bindExtern(T* ptr)    {
0236     bindExtern(ptr, &BasicGrammar::instance<T>());
0237   }
0238 
0239 }      /* End namespace dd4hep */
0240 #endif // DD4HEP_OPAQUEDATA_H