Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:38

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