File indexing completed on 2025-07-03 08:34:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DD4HEP_OPAQUEDATA_H
0014 #define DD4HEP_OPAQUEDATA_H
0015
0016
0017 #include <DD4hep/Grammar.h>
0018
0019
0020 #include <typeinfo>
0021 #include <string>
0022
0023
0024 namespace dd4hep {
0025
0026
0027 class BasicGrammar;
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 class OpaqueData {
0039 private:
0040 protected:
0041
0042 OpaqueData() = default;
0043
0044 virtual ~OpaqueData() = default;
0045
0046 OpaqueData(const OpaqueData& copy) = default;
0047
0048 OpaqueData& operator=(const OpaqueData& copy) = default;
0049
0050 public:
0051
0052 const BasicGrammar* grammar = 0;
0053
0054 protected:
0055
0056 void* pointer = 0;
0057
0058 public:
0059
0060 bool fromString(const std::string& rep);
0061
0062 std::string str() const;
0063
0064 const std::type_info& typeInfo() const;
0065
0066 const std::string& dataType() const;
0067
0068 const void* ptr() const { return pointer; }
0069
0070 bool is_bound() const { return 0 != pointer; }
0071
0072 template <typename T> T& get();
0073
0074 template <typename T> const T& get() const;
0075
0076 template <typename T> T& as();
0077
0078 template <typename T> const T& as() const;
0079 };
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 class OpaqueDataBlock : public OpaqueData {
0092
0093 public:
0094
0095 constexpr static const size_t BUFFER_SIZE = 40;
0096
0097 protected:
0098
0099
0100
0101
0102
0103
0104
0105
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
0118 unsigned int type;
0119
0120 public:
0121
0122 OpaqueDataBlock();
0123
0124 template <typename OBJECT> OpaqueDataBlock(OBJECT&& data);
0125
0126 OpaqueDataBlock(const OpaqueDataBlock& copy);
0127
0128 ~OpaqueDataBlock();
0129
0130 OpaqueDataBlock& operator=(const OpaqueDataBlock& copy);
0131
0132 void* ptr() const { return pointer; }
0133
0134 void* bind(const BasicGrammar* grammar);
0135
0136 void* bind(void* ptr, size_t len, const BasicGrammar* grammar);
0137
0138 void bindExtern(void* ptr, const BasicGrammar* grammar);
0139
0140 template <typename T, typename... Args> T& construct(Args... args);
0141
0142 template <typename T> T& bind();
0143
0144 template <typename T> T& bind(void* ptr, size_t len);
0145
0146 template <typename T> T& bind(const std::string& value);
0147
0148 template <typename T> T& bind(void* ptr, size_t len, const std::string& value);
0149
0150 template <typename T> T& bind(T&& data);
0151
0152 template <typename T> void bindExtern(T* ptr);
0153 };
0154
0155
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
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
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
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
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
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
0198 template <typename T> inline T& OpaqueDataBlock::bind() {
0199 this->bind(&BasicGrammar::instance<T>());
0200 return *(new(this->pointer) T());
0201 }
0202
0203
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
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
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
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
0235 template <typename T> inline void OpaqueDataBlock::bindExtern(T* ptr) {
0236 bindExtern(ptr, &BasicGrammar::instance<T>());
0237 }
0238
0239 }
0240 #endif