Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 09:58:02

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