File indexing completed on 2025-07-18 08:51:11
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 #if __cplusplus >= 202302L
0188 bind(std::move(obj));
0189 #else
0190 this->bind(&BasicGrammar::instance<OBJECT>());
0191 new(this->pointer) OBJECT(std::move(obj));
0192 #endif
0193 }
0194
0195
0196 template <typename T, typename... Args> inline T& OpaqueDataBlock::construct(Args... args) {
0197 this->bind(&BasicGrammar::instance<T>());
0198 return *(new(this->pointer) T(std::forward<Args>(args)...));
0199 }
0200
0201
0202 template <typename T> inline T& OpaqueDataBlock::bind() {
0203 this->bind(&BasicGrammar::instance<T>());
0204 return *(new(this->pointer) T());
0205 }
0206
0207
0208 template <typename T> inline T& OpaqueDataBlock::bind(T&& obj) {
0209 this->bind(&BasicGrammar::instance<T>());
0210 return *(new(this->pointer) T(std::move(obj)));
0211 }
0212
0213
0214 template <typename T> inline T& OpaqueDataBlock::bind(void* ptr, size_t len) {
0215 this->bind(ptr,len,&BasicGrammar::instance<T>());
0216 return *(new(this->pointer) T());
0217 }
0218
0219
0220 template <typename T> inline T& OpaqueDataBlock::bind(const std::string& value) {
0221 T& ret = this->bind<T>();
0222 if ( !value.empty() && !this->fromString(value) ) {
0223 throw std::runtime_error("OpaqueDataBlock::set> Failed to bind type "+
0224 typeName(typeid(T))+" to condition data block.");
0225 }
0226 return ret;
0227 }
0228
0229
0230 template <typename T> inline T& OpaqueDataBlock::bind(void* ptr, size_t len, const std::string& value) {
0231 T& ret = this->bind<T>(ptr, len);
0232 if ( !value.empty() && !this->fromString(value) ) {
0233 throw std::runtime_error("OpaqueDataBlock::set> Failed to bind type "+
0234 typeName(typeid(T))+" to condition data block.");
0235 }
0236 return ret;
0237 }
0238
0239 template <typename T> inline void OpaqueDataBlock::bindExtern(T* ptr) {
0240 bindExtern(ptr, &BasicGrammar::instance<T>());
0241 }
0242
0243 }
0244 #endif