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