Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 07:52:03

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 <vector>
0022 #include <string>
0023 #include <limits>
0024 #include <cstdint>
0025 
0026 #include <typeinfo>
0027 #include <algorithm>
0028 #include <stdexcept>
0029 
0030 /// Namespace for the AIDA detector description toolkit
0031 namespace dd4hep {
0032 
0033   class DetElement;
0034 
0035   /// Namespace describing generic detector segmentations
0036   namespace DDSegmentation  {
0037     class BitFieldCoder;
0038     class BitFieldElement;
0039     /// Useful typedefs to differentiate cell IDs and volume IDs
0040     typedef uint64_t CellID;
0041     typedef uint64_t VolumeID;
0042     typedef int64_t  FieldID;
0043   }
0044 
0045 
0046   // Put here global basic type definitions derived from primitive types of the dd4hep namespace
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   /// Specialized exception to be thrown if invalid handles are accessed
0061   class invalid_handle_exception : public std::runtime_error  {
0062   public:
0063     /// Initializing constructor
0064     invalid_handle_exception(const char* msg) : std::runtime_error(msg) {}
0065     /// Initializing constructor
0066     invalid_handle_exception(const std::string& msg) : std::runtime_error(msg) {}
0067     /// Generic copy constructor
0068     invalid_handle_exception(const std::exception& e) : std::runtime_error(e.what()) {}
0069     /// Generic copy constructor
0070     invalid_handle_exception(const invalid_handle_exception& e) : std::runtime_error(e.what()) {}
0071     /// Default destructor of specialized exception
0072     virtual ~invalid_handle_exception() = default;
0073   };
0074 
0075   /// Macro for deprecated functions. Prints once only. useage: deprecatedCall(__PRETTY_FUNCTION__);
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   /// ABI information about type names
0085   std::string typeName(const std::type_info& type);
0086   /// Check type infos for equivalence (dynamic casts) using ABI information
0087   void typeinfoCheck(const std::type_info& typ1, const std::type_info& typ2, const std::string& text = "");
0088   /// Throw exception when handles are check for validity
0089   void invalidHandleError(const std::type_info& type);
0090   /// Throw exception when handles are badly assigned
0091   void invalidHandleAssignmentError(const std::type_info& from, const std::type_info& to);
0092 
0093   /// Throw exception when handles are check for validity
0094   template <typename T> void invalidHandleError()  {
0095     invalidHandleError(typeid(T));
0096   }
0097 
0098   /// Throw exception when handles are check for validity
0099   void notImplemented(const std::string& msg);
0100 
0101   /// Convert volumeID to string format (016X)
0102   std::string volumeID(VolumeID vid);
0103 
0104   /// DD4hep internal namespace declaration for utilities and implementation details
0105   namespace detail  {
0106     
0107     /// 64 bit hash function
0108     unsigned long long int hash64(const void* key, std::size_t len);
0109     /// 64 bit hash function
0110     unsigned long long int hash64(const char* key);
0111     /// 64 bit hash function
0112     unsigned long long int hash64(const std::string& key);
0113     /// 64 bit hash update function
0114     unsigned long long int update_hash64(unsigned long long int hash, const void* key, std::size_t len);
0115     /// 64 bit hash update function
0116     unsigned long long int update_hash64(unsigned long long int hash, const std::string& key);
0117     /// 64 bit hash update function
0118     unsigned long long int update_hash64(unsigned long long int hash, const char* key);
0119   
0120     /// 32 bit hash function
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     /// 32 bit hash function
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     /// 32 bit hash function
0149     inline unsigned int hash32(const std::string& key) {
0150       return hash32(key.c_str());
0151     }
0152 
0153     /// 16 bit hash function
0154     unsigned short hash16(const void* key, std::size_t len);
0155     /// 16 bit hash function
0156     inline unsigned short hash16(const std::string& key) {
0157       return hash16(key.c_str(), key.length());
0158     }
0159 
0160     /// 8 bit hash function
0161     unsigned char hash8(const char* key);
0162     /// 8 bit hash function
0163     unsigned char hash8(const void* key, std::size_t len);
0164     /// 8 bit hash function
0165     inline unsigned short hash8(const std::string& key) {
0166       return hash8(key.c_str(), key.length());
0167     }
0168 
0169     /// 64 bit type hash function
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     /// C++ version to convert a string to lower case
0188     std::string str_lower(const std::string& str);
0189     /// C++ version to convert a string to upper case
0190     std::string str_upper(const std::string& str);
0191     /// Replace all occurrencies of a string
0192     std::string str_replace(const std::string& source, const std::string& pattern, const std::string& replacement);
0193     /// Replace all occurrencies of a string
0194     std::string str_replace(const std::string& source, char pattern, const std::string& replacement);
0195     /// Replace all occurrencies of a string
0196     std::string str_replace(const std::string& source, char pattern, char replacement);
0197 
0198     /// Convert date into epoch time (seconds since 1970)
0199     long int makeTime(int year, int month, int day,
0200                       int hour=0, int minutes=0, int seconds=0);
0201   
0202     /// Convert date into epoch time (seconds since 1970)
0203     long int makeTime(const std::string& date, const char* fmt="%d-%m-%Y %H:%M:%S");
0204   
0205 
0206     /// A bit of support for handling and printing primitives
0207     /**
0208      *
0209      * \author  M.Frank
0210      * \version 1.0
0211      * \ingroup DD4HEP
0212      */
0213     template<typename T> struct Primitive {
0214     public:
0215       /// Type decribed by th class
0216       typedef T value_t;
0217       /// Definition of the vector type
0218       typedef std::vector<value_t>              vector_t;
0219 
0220       /// Definition of the bool mapped type
0221       typedef std::pair<bool,value_t>           bool_pair_t;
0222       /// Definition of the char mapped type
0223       typedef std::pair<char,value_t>           char_pair_t;
0224       /// Definition of the unsigned char mapped type
0225       typedef std::pair<unsigned char,value_t>  uchar_pair_t;
0226       /// Definition of the short integer mapped type
0227       typedef std::pair<short,value_t>          short_pair_t;
0228       /// Definition of the unsigned short integer mapped type
0229       typedef std::pair<unsigned short,value_t> ushort_pair_t;
0230       /// Definition of the integer mapped type
0231       typedef std::pair<int,value_t>            int_pair_t;
0232       /// Definition of the unsigned integer mapped type
0233       typedef std::pair<unsigned int,value_t>   uint_pair_t;
0234       /// Definition of the long integer mapped type
0235       typedef std::pair<long,value_t>           long_pair_t;
0236       /// Definition of the unsigned long integer mapped type
0237       typedef std::pair<unsigned long,value_t>  ulong_pair_t;
0238       /// Definition of the size_t mapped type
0239       typedef std::pair<float,value_t>          float_pair_t;
0240       /// Definition of the size_t mapped type
0241       typedef std::pair<double,value_t>         double_pair_t;
0242       /// Definition of the size_t mapped type
0243       typedef std::pair<size_t,value_t>         size_pair_t;
0244       /// Definition of the string mapped type
0245       typedef std::pair<std::string,value_t>    string_pair_t;
0246 
0247       /// Definition of the short integer mapped type
0248       typedef std::map<short,value_t>           short_map_t;
0249       /// Definition of the unsigned short integer mapped type
0250       typedef std::map<unsigned short,value_t>  ushort_map_t;
0251       /// Definition of the integer mapped type
0252       typedef std::map<int,value_t>             int_map_t;
0253       /// Definition of the unsigned integer mapped type
0254       typedef std::map<unsigned int,value_t>    uint_map_t;
0255       /// Definition of the long integer mapped type
0256       typedef std::map<long,value_t>            long_map_t;
0257       /// Definition of the unsigned long integer mapped type
0258       typedef std::map<unsigned long,value_t>   ulong_map_t;
0259       /// Definition of the size_t mapped type
0260       typedef std::map<size_t,value_t>          size_map_t;
0261       /// Definition of the string mapped type
0262       typedef std::map<std::string,value_t>     string_map_t;
0263       /// Definition of the limits
0264       typedef std::numeric_limits<value_t>      limits;
0265 
0266       /// Access to default printf format
0267       static const char* default_format(); 
0268       /// Access to the specific printf format. May be overloaded by users
0269       static const char* format()          { return default_format();     }
0270       /// Access to the RTTI data type
0271       static const std::type_info& type()  { return typeid(value_t);      }
0272       /// Access to the RTTI data type
0273       static std::string type_name()       { return typeName(type());     }
0274       /// Auto conversion to string using the default format
0275       static std::string toString(T value);
0276       /// Get typed null pointer (for template selctions)
0277       static const value_t* null_pointer() { return (value_t*)0;          }
0278     };
0279 
0280     /// Safe cast mechanism using pre-linked conversions.
0281     /**
0282      *
0283      * \author  M.Frank
0284      * \version 1.0
0285      * \ingroup DD4HEP
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     /// Operator to clear containers when out of scope
0308     /**
0309      *  \author  M.Frank
0310      *  \version 1.0
0311      *  \ingroup DD4HEP_CORE
0312      */
0313     template<typename C> struct ClearOnReturn {
0314       C& container;
0315       ClearOnReturn(C& c) : container(c) {  }
0316       ~ClearOnReturn() { container.clear(); }
0317     };
0318 
0319     /// Helper to copy objects.
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     /// Helper to copy objects.
0325     template <typename T> inline void constructObject(void* target)  {
0326       ::new(target) T();
0327     }
0328     /// Helper to destruct objects. Note: The memory is NOT released!
0329     template <typename T> inline void destructObject(T* ptr) {
0330       ptr->~T();
0331     }
0332     /// Helper to delete objects from heap and reset the pointer. Saves many many lines of code
0333     template <typename T> inline void deletePtr(T*& ptr) {
0334       if (0 != ptr)
0335         delete ptr;
0336       ptr = 0;
0337     }
0338     /// Helper to delete objects from heap and reset the pointer. Saves many many lines of code
0339     template <typename T> inline void deleteObject(T* ptr) {
0340       if (0 != ptr)
0341         delete ptr;
0342     }
0343     /// Helper to delete objects from heap and reset the pointer
0344     template <typename T> inline void destroyObject(T*& ptr) {
0345       deletePtr(ptr);
0346     }
0347     /// Functor to delete objects from heap and reset the pointer
0348     template <typename T> class DestroyObject {
0349     public:
0350       void operator()(T& ptr) const {
0351         destroyObject(ptr);
0352       }
0353     };
0354 
0355     /// Operator to select second element of a pair
0356     template <typename T> class Select2nd  {
0357     public:
0358       typedef T arg_t;
0359       typedef typename T::second_type result_t;
0360       /// Operator function
0361       const result_t& operator()(const arg_t &arg) const { return arg.second; }
0362     };
0363     /// Generator to create Operator to select value elements of a map
0364     template <typename T> Select2nd<typename T::value_type> select2nd(const T&)
0365     { return Select2nd<typename T::value_type>(); }
0366 
0367     /// Operator to select the first element of a pair
0368     template <typename T> class Select1st  {
0369     public:
0370       typedef T arg_t;
0371       typedef typename T::first_type result_t;
0372       /// Operator function
0373       const result_t& operator()(const arg_t &arg) const { return arg.first; }
0374     };
0375     /// Generator to create Operator to select key values of a map
0376     template <typename T> Select1st<typename T::value_type> select1st(const T&)
0377     { return Select1st<typename T::value_type>(); }
0378 
0379 
0380     /// map Functor to delete objects from heap
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     /// map Functor to delete objects from heap
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     /// Helper to delete objects from heap and reset the pointer. Saves many many lines of code
0415     template <typename T> inline void releasePtr(T& arg) {
0416       if (0 != arg)
0417         arg->release();
0418       arg = 0;
0419     }
0420 
0421     /// Functor to release objects from heap and reset the pointer
0422     template <typename T> class ReleaseObject {
0423     public:
0424       void operator()(T& arg) const {
0425         releasePtr(arg);
0426       }
0427     };
0428     /// Map Functor to release objects from heap
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     /// Functor to delete objects from heap and reset the pointer
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     /// Functor to delete objects from heap and reset the pointer
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     /// Helper to pass reference counted objects
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     /// Member function call-functor with no arguments
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     /// Member function call-functor with 1 argument
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     /// Member function call-functor with 2 arguments
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     /// Member function call-functor with no arguments (const version)
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     /// Member function call-functor with 1 argument (const version)
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     /// Member function call-functor with 2 arguments (const version)
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     /// Generic map Functor to act on first element (key)
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     /// Generic map Functor to act on second element (mapped type)
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     /// Helper class to select the value from a mapped type
0639     /** 
0640      *  \author  M.Frank
0641      *  \version 1.0
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     /// Data structure to manipulate a bitmask held by reference and represented by an integer
0649     /**
0650      * @author  M.Frank
0651      * @version 1.0
0652      */
0653     template <typename T> class ReferenceBitMask  {
0654     public:
0655       /// Reference to the data
0656       T& mask;
0657       /// Standard constructor
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     /// Standard constructor
0686     template <typename T>  ReferenceBitMask<T>::ReferenceBitMask(T& arg) : mask(arg) {}
0687 
0688   }    // End namespace detail
0689 
0690   /// Class to perform dynamic casts using unknown pointers.
0691   /** @class Cast Primitives.h dd4hep/Primitives.h
0692    *
0693    *  It is mandatory that the pointers referred do actually
0694    *  support the asked functionalty.
0695    *  Miracles also I cannot do.....
0696    *
0697    *   @author  M.Frank
0698    *   @date    13.08.2013
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     /// Initializing Constructor
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     /// Instantiation method    
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     /// Initializing Constructor
0728     Cast(const std::type_info& t);
0729   public:
0730     /// Instantiation method
0731     template <typename TYPE> static const Cast& instance() {
0732       static Cast c(typeid(TYPE));
0733       return c;
0734     }
0735 #endif
0736   protected:
0737     /// Defautl destructor
0738     virtual ~Cast();
0739 
0740   public:
0741     /// Apply cast using typeinfo instead of dynamic_cast
0742     void* apply_dynCast(const Cast& to, const void* ptr) const;
0743     /// Apply cast using typeinfo instead of dynamic_cast
0744     void* apply_upCast(const Cast& to, const void* ptr) const;
0745     /// Apply cast using typeinfo instead of dynamic_cast
0746     void* apply_downCast(const Cast& to, const void* ptr) const;
0747   };
0748 
0749   /// Class to perform dynamic casts using unknown pointers.
0750   /** @class ComponentCast Primitives.h dd4hep/Primitives.h
0751    *
0752    *  It is mandatory that the pointers referred do actually
0753    *  support the asked functionalty.
0754    *  Miracles also I cannot do.....
0755    *
0756    *   @author  M.Frank
0757    *   @date    13.08.2013
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     /// Initializing Constructor
0769     ComponentCast(const Cast& c, destroy_t d) : destroy(d), cast(c)  {}
0770     /// Defautl destructor
0771     virtual ~ComponentCast() = default;
0772     /// Function template to create destructor
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     /// Apply cast using typeinfo instead of dynamic_cast
0786     void* apply_dynCast(const ComponentCast& to, const void* ptr) const  {
0787       return cast.apply_dynCast(to.cast, ptr);
0788     }
0789     /// Apply cast using typeinfo instead of dynamic_cast
0790     void* apply_upCast(const ComponentCast& to, const void* ptr) const   {
0791       return cast.apply_upCast(to.cast, ptr);
0792     }
0793     /// Apply cast using typeinfo instead of dynamic_cast
0794     void* apply_downCast(const ComponentCast& to, const void* ptr) const   {
0795       return cast.apply_downCast(to.cast, ptr);
0796     }
0797   };
0798 }      // End namespace dd4hep
0799 #endif // PARSERS_PRIMITIVES_H