File indexing completed on 2025-07-11 07:52:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef PARSERS_PRIMITIVES_H
0014 #define PARSERS_PRIMITIVES_H
0015
0016
0017 #include <Parsers/config.h>
0018
0019
0020 #include <map>
0021 #include <vector>
0022 #include <string>
0023 #include <limits>
0024 #include <cstdint>
0025
0026 #include <typeinfo>
0027 #include <algorithm>
0028 #include <stdexcept>
0029
0030
0031 namespace dd4hep {
0032
0033 class DetElement;
0034
0035
0036 namespace DDSegmentation {
0037 class BitFieldCoder;
0038 class BitFieldElement;
0039
0040 typedef uint64_t CellID;
0041 typedef uint64_t VolumeID;
0042 typedef int64_t FieldID;
0043 }
0044
0045
0046
0047 #ifdef __CINT__
0048 typedef DDSegmentation::CellID CellID;
0049 typedef DDSegmentation::VolumeID VolumeID;
0050 typedef DDSegmentation::BitFieldCoder BitFieldCoder;
0051 typedef DDSegmentation::BitFieldElement BitFieldElement;
0052 #else
0053 using DDSegmentation::CellID;
0054 using DDSegmentation::FieldID;
0055 using DDSegmentation::VolumeID;
0056 using DDSegmentation::BitFieldCoder;
0057 using DDSegmentation::BitFieldElement;
0058 #endif
0059
0060
0061 class invalid_handle_exception : public std::runtime_error {
0062 public:
0063
0064 invalid_handle_exception(const char* msg) : std::runtime_error(msg) {}
0065
0066 invalid_handle_exception(const std::string& msg) : std::runtime_error(msg) {}
0067
0068 invalid_handle_exception(const std::exception& e) : std::runtime_error(e.what()) {}
0069
0070 invalid_handle_exception(const invalid_handle_exception& e) : std::runtime_error(e.what()) {}
0071
0072 virtual ~invalid_handle_exception() = default;
0073 };
0074
0075
0076 #define DD4HEP_DEPRECATED_CALL(tag,replacement,func) \
0077 { static bool __dd4hep_first=true; \
0078 if ( __dd4hep_first ) { __dd4hep_first=false; \
0079 dd4hep::printout(dd4hep::WARNING,tag, \
0080 "Deprecated function: '%s' use '%s' instead.", \
0081 func,replacement); \
0082 }}
0083
0084
0085 std::string typeName(const std::type_info& type);
0086
0087 void typeinfoCheck(const std::type_info& typ1, const std::type_info& typ2, const std::string& text = "");
0088
0089 void invalidHandleError(const std::type_info& type);
0090
0091 void invalidHandleAssignmentError(const std::type_info& from, const std::type_info& to);
0092
0093
0094 template <typename T> void invalidHandleError() {
0095 invalidHandleError(typeid(T));
0096 }
0097
0098
0099 void notImplemented(const std::string& msg);
0100
0101
0102 std::string volumeID(VolumeID vid);
0103
0104
0105 namespace detail {
0106
0107
0108 unsigned long long int hash64(const void* key, std::size_t len);
0109
0110 unsigned long long int hash64(const char* key);
0111
0112 unsigned long long int hash64(const std::string& key);
0113
0114 unsigned long long int update_hash64(unsigned long long int hash, const void* key, std::size_t len);
0115
0116 unsigned long long int update_hash64(unsigned long long int hash, const std::string& key);
0117
0118 unsigned long long int update_hash64(unsigned long long int hash, const char* key);
0119
0120
0121 inline unsigned int hash32(const void* key, std::size_t len) {
0122 unsigned int hash = 0;
0123 const unsigned char* k = (const unsigned char*)key;
0124 for (; --len; k++) {
0125 hash += *k;
0126 hash += (hash << 10);
0127 hash ^= (hash >> 6);
0128 }
0129 hash += (hash << 3);
0130 hash ^= (hash >> 11);
0131 hash += (hash << 15);
0132 return hash;
0133 }
0134
0135 inline unsigned int hash32(const char* key) {
0136 unsigned int hash = 0;
0137 const char* k = key;
0138 for (; *k; k++) {
0139 hash += *k;
0140 hash += (hash << 10);
0141 hash ^= (hash >> 6);
0142 }
0143 hash += (hash << 3);
0144 hash ^= (hash >> 11);
0145 hash += (hash << 15);
0146 return hash;
0147 }
0148
0149 inline unsigned int hash32(const std::string& key) {
0150 return hash32(key.c_str());
0151 }
0152
0153
0154 unsigned short hash16(const void* key, std::size_t len);
0155
0156 inline unsigned short hash16(const std::string& key) {
0157 return hash16(key.c_str(), key.length());
0158 }
0159
0160
0161 unsigned char hash8(const char* key);
0162
0163 unsigned char hash8(const void* key, std::size_t len);
0164
0165 inline unsigned short hash8(const std::string& key) {
0166 return hash8(key.c_str(), key.length());
0167 }
0168
0169
0170 template <typename T> unsigned long long int typeHash64() {
0171 static unsigned long long int code = hash64(typeid(T).name());
0172 return code;
0173 }
0174
0175 template <typename T> T reverseBits(T num) {
0176 static constexpr size_t NO_OF_BITS = sizeof(num) * 8 - 1;
0177 static constexpr T _zero = 0;
0178 static constexpr T _one = 1;
0179 T reverse_num = _zero;
0180 for (size_t i = 0; i <= NO_OF_BITS; i++) {
0181 if( (num & (_one << i)) )
0182 reverse_num |= (_one << (NO_OF_BITS - i));
0183 }
0184 return reverse_num;
0185 }
0186
0187
0188 std::string str_lower(const std::string& str);
0189
0190 std::string str_upper(const std::string& str);
0191
0192 std::string str_replace(const std::string& source, const std::string& pattern, const std::string& replacement);
0193
0194 std::string str_replace(const std::string& source, char pattern, const std::string& replacement);
0195
0196 std::string str_replace(const std::string& source, char pattern, char replacement);
0197
0198
0199 long int makeTime(int year, int month, int day,
0200 int hour=0, int minutes=0, int seconds=0);
0201
0202
0203 long int makeTime(const std::string& date, const char* fmt="%d-%m-%Y %H:%M:%S");
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 template<typename T> struct Primitive {
0214 public:
0215
0216 typedef T value_t;
0217
0218 typedef std::vector<value_t> vector_t;
0219
0220
0221 typedef std::pair<bool,value_t> bool_pair_t;
0222
0223 typedef std::pair<char,value_t> char_pair_t;
0224
0225 typedef std::pair<unsigned char,value_t> uchar_pair_t;
0226
0227 typedef std::pair<short,value_t> short_pair_t;
0228
0229 typedef std::pair<unsigned short,value_t> ushort_pair_t;
0230
0231 typedef std::pair<int,value_t> int_pair_t;
0232
0233 typedef std::pair<unsigned int,value_t> uint_pair_t;
0234
0235 typedef std::pair<long,value_t> long_pair_t;
0236
0237 typedef std::pair<unsigned long,value_t> ulong_pair_t;
0238
0239 typedef std::pair<float,value_t> float_pair_t;
0240
0241 typedef std::pair<double,value_t> double_pair_t;
0242
0243 typedef std::pair<size_t,value_t> size_pair_t;
0244
0245 typedef std::pair<std::string,value_t> string_pair_t;
0246
0247
0248 typedef std::map<short,value_t> short_map_t;
0249
0250 typedef std::map<unsigned short,value_t> ushort_map_t;
0251
0252 typedef std::map<int,value_t> int_map_t;
0253
0254 typedef std::map<unsigned int,value_t> uint_map_t;
0255
0256 typedef std::map<long,value_t> long_map_t;
0257
0258 typedef std::map<unsigned long,value_t> ulong_map_t;
0259
0260 typedef std::map<size_t,value_t> size_map_t;
0261
0262 typedef std::map<std::string,value_t> string_map_t;
0263
0264 typedef std::numeric_limits<value_t> limits;
0265
0266
0267 static const char* default_format();
0268
0269 static const char* format() { return default_format(); }
0270
0271 static const std::type_info& type() { return typeid(value_t); }
0272
0273 static std::string type_name() { return typeName(type()); }
0274
0275 static std::string toString(T value);
0276
0277 static const value_t* null_pointer() { return (value_t*)0; }
0278 };
0279
0280
0281
0282
0283
0284
0285
0286
0287 #ifdef DD4HEP_USE_SAFE_CAST
0288 template <typename TO> class safe_cast {
0289 public:
0290 template <typename FROM> static TO* cast(FROM* from);
0291 template <typename FROM> static TO* cast(const FROM* from);
0292 template <typename FROM> static TO* cast_non_null(FROM* from);
0293 template <typename FROM> static TO* cast_non_null(const FROM* from);
0294 };
0295 #else
0296 template <typename TO> class safe_cast {
0297 public:
0298 static TO* cast(TO* from);
0299 static TO* cast_non_null(TO* from);
0300 template <typename FROM> static TO* cast(FROM* from) { return cast((TO*)from); }
0301 template <typename FROM> static TO* cast(const FROM* from) { return cast((TO*)from); }
0302 template <typename FROM> static TO* cast_non_null(FROM* from) { return cast_non_null((TO*)from); }
0303 template <typename FROM> static TO* cast_non_null(const FROM* from) { return cast_non_null((TO*)from); }
0304 };
0305 #endif
0306
0307
0308
0309
0310
0311
0312
0313 template<typename C> struct ClearOnReturn {
0314 C& container;
0315 ClearOnReturn(C& c) : container(c) { }
0316 ~ClearOnReturn() { container.clear(); }
0317 };
0318
0319
0320 template <typename T> inline void copyObject(void* target,const void* source) {
0321 const T* src = (const T*)source;
0322 ::new(target) T(*src);
0323 }
0324
0325 template <typename T> inline void constructObject(void* target) {
0326 ::new(target) T();
0327 }
0328
0329 template <typename T> inline void destructObject(T* ptr) {
0330 ptr->~T();
0331 }
0332
0333 template <typename T> inline void deletePtr(T*& ptr) {
0334 if (0 != ptr)
0335 delete ptr;
0336 ptr = 0;
0337 }
0338
0339 template <typename T> inline void deleteObject(T* ptr) {
0340 if (0 != ptr)
0341 delete ptr;
0342 }
0343
0344 template <typename T> inline void destroyObject(T*& ptr) {
0345 deletePtr(ptr);
0346 }
0347
0348 template <typename T> class DestroyObject {
0349 public:
0350 void operator()(T& ptr) const {
0351 destroyObject(ptr);
0352 }
0353 };
0354
0355
0356 template <typename T> class Select2nd {
0357 public:
0358 typedef T arg_t;
0359 typedef typename T::second_type result_t;
0360
0361 const result_t& operator()(const arg_t &arg) const { return arg.second; }
0362 };
0363
0364 template <typename T> Select2nd<typename T::value_type> select2nd(const T&)
0365 { return Select2nd<typename T::value_type>(); }
0366
0367
0368 template <typename T> class Select1st {
0369 public:
0370 typedef T arg_t;
0371 typedef typename T::first_type result_t;
0372
0373 const result_t& operator()(const arg_t &arg) const { return arg.first; }
0374 };
0375
0376 template <typename T> Select1st<typename T::value_type> select1st(const T&)
0377 { return Select1st<typename T::value_type>(); }
0378
0379
0380
0381 template <typename M> class DestroyObjects {
0382 public:
0383 M& object;
0384 DestroyObjects(M& obj) : object(obj) { }
0385 void operator()(std::pair<typename M::key_type, typename M::mapped_type> arg) const
0386 { DestroyObject<typename M::mapped_type>()(arg.second); }
0387 void operator()() const {
0388 if ( !object.empty() ) for_each(object.begin(),object.end(),(*this));
0389 object.clear();
0390 }
0391 };
0392 template <typename M> void destroyObjects(M& obj)
0393 { DestroyObjects<M> del(obj); del(); }
0394 template <typename M> DestroyObjects<M> destroy2nd(M& obj)
0395 { DestroyObjects<M> del(obj); del(); }
0396
0397
0398 template <typename M> class DestroyFirst {
0399 public:
0400 M& object;
0401 DestroyFirst(M& obj) : object(obj) { }
0402 void operator()(std::pair<typename M::key_type, typename M::mapped_type> arg) const
0403 { DestroyObject<typename M::key_type>()(arg.first); }
0404 void operator()() const {
0405 if ( !object.empty() ) for_each(object.begin(),object.end(),(*this));
0406 object.clear();
0407 }
0408 };
0409 template <typename M> void destroyFirst(M& arg)
0410 { DestroyFirst<M> del(arg); del(); }
0411 template <typename M> void destroy1st(M& arg)
0412 { DestroyFirst<M> del(arg); del(); }
0413
0414
0415 template <typename T> inline void releasePtr(T& arg) {
0416 if (0 != arg)
0417 arg->release();
0418 arg = 0;
0419 }
0420
0421
0422 template <typename T> class ReleaseObject {
0423 public:
0424 void operator()(T& arg) const {
0425 releasePtr(arg);
0426 }
0427 };
0428
0429 template <typename M> class ReleaseObjects {
0430 public:
0431 M& object;
0432 ReleaseObjects(M& arg) : object(arg) { }
0433 void operator()(std::pair<typename M::key_type, typename M::mapped_type> arg) const
0434 { ReleaseObject<typename M::mapped_type>()(arg.second); }
0435 void operator()() const {
0436 if ( !object.empty() ) for_each(object.begin(),object.end(),(*this));
0437 object.clear();
0438 }
0439 };
0440 template <typename M> ReleaseObject<typename M::value_type> releaseObject(M&) {
0441 return ReleaseObject<typename M::value_type>();
0442 }
0443 template <typename M> void releaseObjects(M& arg) {
0444 ReleaseObjects<M> rel(arg); rel();
0445 }
0446 template <typename M> void release2nd(M& arg) {
0447 ReleaseObjects<M> rel(arg); rel();
0448 }
0449
0450
0451 template <typename T> class ReferenceObject {
0452 public:
0453 typedef T arg_t;
0454 T operator()(T arg) const {
0455 if ( arg ) arg->addRef();
0456 return arg;
0457 }
0458 };
0459
0460 template <typename M> class ReferenceObjects {
0461 public:
0462 typedef typename M::second_type result_t;
0463 result_t operator()(const M& arg) const {
0464 return ReferenceObject<result_t>()(arg.second);
0465 }
0466 };
0467 template <typename M> ReferenceObject<M> referenceObject(M&) {
0468 return ReferenceObject<typename M::value_type>();
0469 }
0470 template <typename M> ReferenceObjects<typename M::value_type> reference2nd(M&) {
0471 return ReferenceObjects<typename M::value_type>();
0472 }
0473
0474 template <typename T> class RefCountHandle {
0475 public:
0476 T* ptr;
0477 RefCountHandle() : ptr(0) {}
0478 RefCountHandle(T* p) : ptr(p) { if ( ptr ) ptr->addRef(); }
0479 RefCountHandle(const RefCountHandle& c) : ptr(c.ptr) { if ( ptr ) ptr->addRef(); }
0480 RefCountHandle(const RefCountHandle& c, const DetElement& ) : ptr(c.ptr) { if ( ptr ) ptr->addRef(); }
0481 virtual ~RefCountHandle() { if ( ptr ) ptr->release(); }
0482 RefCountHandle& operator=(const RefCountHandle& c) {
0483 if ( &c != this ) {
0484 if ( ptr ) ptr->release();
0485 ptr = c.ptr;
0486 if ( ptr ) ptr->addRef();
0487 }
0488 return *this;
0489 }
0490 };
0491
0492
0493 template <typename R, typename T> struct ApplyMemFunc {
0494 typedef R (T::*memfunc_t)();
0495 memfunc_t func;
0496 ApplyMemFunc(memfunc_t f) : func(f) {}
0497 void operator()(T* arg) const { if (arg) { (arg->*func)(); } }
0498 };
0499
0500
0501 template <typename R, typename T, typename A1> struct ApplyMemFunc1 {
0502 typedef R (T::*memfunc_t)(A1 a1);
0503 memfunc_t func;
0504 A1& arg1;
0505 ApplyMemFunc1(memfunc_t f, A1& a1) : func(f), arg1(a1) {}
0506 void operator()(T* arg) const { if ( arg ) { (arg->*func)(arg1); } }
0507 };
0508
0509
0510 template <typename R, typename T, typename A1, typename A2> struct ApplyMemFunc2 {
0511 typedef R (T::*memfunc_t)(A1 a1, A2 a2);
0512 memfunc_t func;
0513 A1& arg1;
0514 A2& arg2;
0515 ApplyMemFunc2(memfunc_t f, A1& a1, A2& a2) : func(f), arg1(a1), arg2(a2) {}
0516 void operator()( T* arg) const { if ( arg ) { (arg->*func)(arg1, arg2); } }
0517 };
0518
0519
0520 template <typename R, typename T> struct ApplyMemFuncConst {
0521 typedef R (T::*memfunc_t)() const;
0522 memfunc_t func;
0523 ApplyMemFuncConst(memfunc_t f) : func(f) {}
0524 void operator()(const T* arg) const { if ( arg ) { (arg->*func)(); } }
0525 };
0526
0527
0528 template <typename R, typename T, typename A1> struct ApplyMemFuncConst1 {
0529 typedef R (T::*memfunc_t)(A1 a1) const;
0530 memfunc_t func;
0531 A1& arg1;
0532 ApplyMemFuncConst1(memfunc_t f, A1& a1) : func(f), arg1(a1) {}
0533 void operator()(const T* arg) const { if ( arg ) { (arg->*func)(arg1); } }
0534 };
0535
0536
0537 template <typename R, typename T, typename A1, typename A2> struct ApplyMemFuncConst2 {
0538 typedef R (T::*memfunc_t)(A1 a1, A2 a2) const;
0539 memfunc_t func;
0540 A1& arg1;
0541 A2& arg2;
0542 ApplyMemFuncConst2(memfunc_t f, A1& a1, A2& a2) : func(f), arg1(a1), arg2(a2) {}
0543 void operator()(const T* arg) const { if ( arg ) { (arg->*func)(arg1, arg2); } }
0544 };
0545
0546 template <typename C, typename R, typename T>
0547 void call_member_func(C& object, R (T::*pmf)())
0548 { std::for_each(object.begin(),object.end(),ApplyMemFunc<R,T>(pmf)); }
0549
0550 template <typename C, typename R, typename T>
0551 void call_member_func(C& object, R (T::*pmf)() const)
0552 { std::for_each(object.begin(),object.end(),ApplyMemFuncConst<R,T>(pmf)); }
0553
0554 template <typename C, typename R, typename T, typename A1>
0555 void call_member_func(C& object, R (T::*pmf)(A1 a1), A1 a1)
0556 { std::for_each(object.begin(),object.end(),ApplyMemFunc1<R,T,A1>(pmf,a1)); }
0557
0558 template <typename C, typename R, typename T, typename A1>
0559 void call_member_func(C& object, R (T::*pmf)(A1 a1) const, A1 a1)
0560 { std::for_each(object.begin(),object.end(),ApplyMemFuncConst1<R,T,A1>(pmf,a1)); }
0561
0562
0563 template <typename C, typename R, typename T, typename A1, typename A2>
0564 void call_member_func(C& object, R (T::*pmf)(A1 a1,A2 a2), A1 a1, A2 a2)
0565 { std::for_each(object.begin(),object.end(),ApplyMemFunc2<R,T,A1,A2>(pmf,a1,a2)); }
0566
0567 template <typename C, typename R, typename T, typename A1, typename A2>
0568 void call_member_func(C& object, R (T::*pmf)(A1 a1,A2 a2) const, A1 a1, A2 a2)
0569 { std::for_each(object.begin(),object.end(),ApplyMemFuncConst2<R,T,A1,A2>(pmf,a1,a2)); }
0570
0571
0572
0573 template <typename M, typename FCN> class Apply1rst {
0574 public:
0575 const FCN& func;
0576 Apply1rst(const FCN& f) : func(f) { }
0577 void operator()(std::pair<typename M::key_type const, typename M::mapped_type>& arg) const
0578 { (func)(arg.first); }
0579 void operator()(const std::pair<typename M::key_type const, typename M::mapped_type>& arg) const
0580 { (func)(arg.first); }
0581 };
0582
0583 template <typename C, typename FCN> Apply1rst<C,FCN> apply__1rst_value(C&,const FCN& func)
0584 { return Apply1rst<C,FCN>(func); }
0585
0586 template <typename C, typename FCN> void apply1rst(C& object,const FCN& func)
0587 { std::for_each(object.begin(),object.end(),apply__1rst_value(object,func)); }
0588
0589 template <typename C, typename R, typename T>
0590 void apply1rst(C& object, R (T::*pmf)())
0591 { std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFunc<R,T>(pmf))); }
0592
0593 template <typename C, typename R, typename T, typename A1>
0594 void apply1rst(C object, R (T::*pmf)(A1 a1), A1 a1)
0595 { std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFunc1<R,T,A1>(pmf,a1))); }
0596
0597 template <typename C, typename R, typename T>
0598 void apply1rst(C& object, R (T::*pmf)() const)
0599 { std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFuncConst<R,T>(pmf))); }
0600
0601 template <typename C, typename R, typename T, typename A1>
0602 void apply1rst(C object, R (T::*pmf)(A1 a1) const, A1 a1)
0603 { std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFuncConst1<R,T,A1>(pmf,a1))); }
0604
0605
0606 template <typename M, typename FCN> class Apply2nd {
0607 public:
0608 const FCN& func;
0609 Apply2nd(const FCN& f) : func(f) { }
0610 void operator()(std::pair<typename M::key_type const, typename M::mapped_type>& arg) const
0611 { (func)(arg.second); }
0612 void operator()(const std::pair<typename M::key_type const, typename M::mapped_type>& arg) const
0613 { (func)(arg.second); }
0614 };
0615
0616 template <typename C, typename FCN> Apply2nd<C,FCN> apply__2nd_value(C&,const FCN& func)
0617 { return Apply2nd<C,FCN>(func); }
0618
0619 template <typename C, typename FCN> void apply2nd(C& object,const FCN& func)
0620 { std::for_each(object.begin(),object.end(),apply__2nd_value(object,func)); }
0621
0622 template <typename C, typename R, typename T>
0623 void apply2nd(C& object, R (T::*pmf)())
0624 { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFunc<R,T>(pmf))); }
0625
0626 template <typename C, typename R, typename T, typename A1>
0627 void apply2nd(C object, R (T::*pmf)(A1 a1), A1 a1)
0628 { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFunc1<R,T,A1>(pmf,a1))); }
0629
0630 template <typename C, typename R, typename T>
0631 void apply2nd(C& object, R (T::*pmf)() const)
0632 { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFuncConst<R,T>(pmf))); }
0633
0634 template <typename C, typename R, typename T, typename A1>
0635 void apply2nd(C object, R (T::*pmf)(A1 a1) const, A1 a1)
0636 { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFuncConst1<R,T,A1>(pmf,a1))); }
0637
0638
0639
0640
0641
0642
0643 template <typename C> struct get_2nd {
0644 const typename C::mapped_type& operator()( const typename C::value_type& v) const
0645 { return v.second; }
0646 };
0647
0648
0649
0650
0651
0652
0653 template <typename T> class ReferenceBitMask {
0654 public:
0655
0656 T& mask;
0657
0658 ReferenceBitMask(T& arg);
0659 T value() const {
0660 return mask;
0661 }
0662 void set(const T& arg) {
0663 mask |= arg;
0664 }
0665 void clear(const T& arg) {
0666 mask &= ~arg;
0667 }
0668 void clear() {
0669 mask = 0;
0670 }
0671 bool isSet(const T& arg) const {
0672 return (mask&arg) == arg;
0673 }
0674 bool anySet(const T& arg) const {
0675 return (mask&arg) != 0;
0676 }
0677 bool testBit(int bit) const {
0678 T arg = T(1)<<bit;
0679 return isSet(arg);
0680 }
0681 bool isNull() const {
0682 return mask == 0;
0683 }
0684 };
0685
0686 template <typename T> ReferenceBitMask<T>::ReferenceBitMask(T& arg) : mask(arg) {}
0687
0688 }
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700 class Cast {
0701 public:
0702 #ifdef __CINT__
0703 const std::type_info* type;
0704 #else
0705 const std::type_info& type;
0706 #endif
0707 #ifdef __APPLE__
0708 typedef void* (*cast_t)(const void*);
0709 cast_t cast;
0710 protected:
0711
0712 Cast(const std::type_info& t, cast_t c);
0713 public:
0714 template <typename TYPE> static void* _cast(const void* arg) {
0715 TYPE* ptr = (TYPE*)arg;
0716 ptr = dynamic_cast<TYPE*>(ptr);
0717 return (void*)ptr;
0718 }
0719
0720 template <typename TYPE> static const Cast& instance() {
0721 static Cast c(typeid(TYPE),_cast<TYPE>);
0722 return c;
0723 }
0724 #else
0725 const void* abi_class;
0726 protected:
0727
0728 Cast(const std::type_info& t);
0729 public:
0730
0731 template <typename TYPE> static const Cast& instance() {
0732 static Cast c(typeid(TYPE));
0733 return c;
0734 }
0735 #endif
0736 protected:
0737
0738 virtual ~Cast();
0739
0740 public:
0741
0742 void* apply_dynCast(const Cast& to, const void* ptr) const;
0743
0744 void* apply_upCast(const Cast& to, const void* ptr) const;
0745
0746 void* apply_downCast(const Cast& to, const void* ptr) const;
0747 };
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759 class ComponentCast {
0760 public:
0761
0762 typedef void (*destroy_t)(void*);
0763 destroy_t destroy;
0764 private:
0765 const Cast& cast;
0766
0767 private:
0768
0769 ComponentCast(const Cast& c, destroy_t d) : destroy(d), cast(c) {}
0770
0771 virtual ~ComponentCast() = default;
0772
0773 template <typename TYPE> static void _destroy(void* arg) {
0774 TYPE* ptr = (TYPE*)arg;
0775 if (ptr) delete ptr;
0776 }
0777 public:
0778 template <typename TYPE> static ComponentCast& instance() {
0779 static ComponentCast c(Cast::instance<TYPE>(),_destroy<TYPE>);
0780 return c;
0781 }
0782 const std::type_info& type() const {
0783 return cast.type;
0784 }
0785
0786 void* apply_dynCast(const ComponentCast& to, const void* ptr) const {
0787 return cast.apply_dynCast(to.cast, ptr);
0788 }
0789
0790 void* apply_upCast(const ComponentCast& to, const void* ptr) const {
0791 return cast.apply_upCast(to.cast, ptr);
0792 }
0793
0794 void* apply_downCast(const ComponentCast& to, const void* ptr) const {
0795 return cast.apply_downCast(to.cast, ptr);
0796 }
0797 };
0798 }
0799 #endif