Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-21 08:23:34

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       delete ptr;
0335       ptr = 0;
0336     }
0337     /// Helper to delete objects from heap and reset the pointer. Saves many many lines of code
0338     template <typename T> inline void deleteObject(T* ptr) {
0339       delete ptr;
0340     }
0341     /// Helper to delete objects from heap and reset the pointer
0342     template <typename T> inline void destroyObject(T*& ptr) {
0343       deletePtr(ptr);
0344     }
0345     /// Functor to delete objects from heap and reset the pointer
0346     template <typename T> class DestroyObject {
0347     public:
0348       void operator()(T& ptr) const {
0349         destroyObject(ptr);
0350       }
0351     };
0352 
0353     /// Operator to select second element of a pair
0354     template <typename T> class Select2nd  {
0355     public:
0356       typedef T arg_t;
0357       typedef typename T::second_type result_t;
0358       /// Operator function
0359       const result_t& operator()(const arg_t &arg) const { return arg.second; }
0360     };
0361     /// Generator to create Operator to select value elements of a map
0362     template <typename T> Select2nd<typename T::value_type> select2nd(const T&)
0363     { return Select2nd<typename T::value_type>(); }
0364 
0365     /// Operator to select the first element of a pair
0366     template <typename T> class Select1st  {
0367     public:
0368       typedef T arg_t;
0369       typedef typename T::first_type result_t;
0370       /// Operator function
0371       const result_t& operator()(const arg_t &arg) const { return arg.first; }
0372     };
0373     /// Generator to create Operator to select key values of a map
0374     template <typename T> Select1st<typename T::value_type> select1st(const T&)
0375     { return Select1st<typename T::value_type>(); }
0376 
0377 
0378     /// map Functor to delete objects from heap
0379     template <typename M> class DestroyObjects {
0380     public:
0381       M& object;
0382       DestroyObjects(M& obj) : object(obj) {                    }
0383       void operator()(std::pair<typename M::key_type, typename M::mapped_type> arg) const
0384       {  DestroyObject<typename M::mapped_type>()(arg.second);    }
0385       void operator()() const {
0386         if ( !object.empty() ) for_each(object.begin(),object.end(),(*this));
0387         object.clear();
0388       }
0389     };
0390     template <typename M> void destroyObjects(M& obj)
0391     {  DestroyObjects<M> del(obj); del();                      }
0392     template <typename M> DestroyObjects<M> destroy2nd(M& obj)
0393     {  DestroyObjects<M> del(obj); del();                      }
0394 
0395     /// map Functor to delete objects from heap
0396     template <typename M> class DestroyFirst {
0397     public:
0398       M& object;
0399       DestroyFirst(M& obj) : object(obj) {   }
0400       void operator()(std::pair<typename M::key_type, typename M::mapped_type> arg) const
0401       {  DestroyObject<typename M::key_type>()(arg.first);     }
0402       void operator()() const {
0403         if ( !object.empty() ) for_each(object.begin(),object.end(),(*this));
0404         object.clear();
0405       }
0406     };
0407     template <typename M> void destroyFirst(M& arg)
0408     {   DestroyFirst<M> del(arg); del();           }
0409     template <typename M> void destroy1st(M& arg)
0410     {   DestroyFirst<M> del(arg); del();           }
0411 
0412     /// Helper to delete objects from heap and reset the pointer. Saves many many lines of code
0413     template <typename T> inline void releasePtr(T& arg) {
0414       if (0 != arg)
0415         arg->release();
0416       arg = 0;
0417     }
0418 
0419     /// Functor to release objects from heap and reset the pointer
0420     template <typename T> class ReleaseObject {
0421     public:
0422       void operator()(T& arg) const {
0423         releasePtr(arg);
0424       }
0425     };
0426     /// Map Functor to release objects from heap
0427     template <typename M> class ReleaseObjects {
0428     public:
0429       M& object;
0430       ReleaseObjects(M& arg) : object(arg) {    }
0431       void operator()(std::pair<typename M::key_type, typename M::mapped_type> arg) const
0432       {  ReleaseObject<typename M::mapped_type>()(arg.second);    }
0433       void operator()() const {
0434         if ( !object.empty() ) for_each(object.begin(),object.end(),(*this));
0435         object.clear();
0436       }
0437     };
0438     template <typename M> ReleaseObject<typename M::value_type> releaseObject(M&) {
0439       return ReleaseObject<typename M::value_type>();
0440     }
0441     template <typename M> void releaseObjects(M& arg) {
0442       ReleaseObjects<M> rel(arg); rel();
0443     }
0444     template <typename M> void release2nd(M& arg) {
0445       ReleaseObjects<M> rel(arg); rel();
0446     }
0447 
0448     /// Functor to delete objects from heap and reset the pointer
0449     template <typename T> class ReferenceObject {
0450     public:
0451       typedef T arg_t;
0452       T operator()(T arg) const {
0453         if ( arg ) arg->addRef();
0454         return arg;
0455       }
0456     };
0457     /// Functor to delete objects from heap and reset the pointer
0458     template <typename M> class ReferenceObjects {
0459     public:
0460       typedef typename M::second_type result_t;
0461       result_t operator()(const M& arg) const {
0462         return ReferenceObject<result_t>()(arg.second);
0463       }
0464     };
0465     template <typename M> ReferenceObject<M> referenceObject(M&) {
0466       return ReferenceObject<typename M::value_type>();
0467     }
0468     template <typename M> ReferenceObjects<typename M::value_type> reference2nd(M&) {
0469       return ReferenceObjects<typename M::value_type>();
0470     }
0471     /// Helper to pass reference counted objects
0472     template <typename T> class RefCountHandle {
0473     public:
0474       T* ptr;
0475       RefCountHandle() : ptr(0) {}
0476       RefCountHandle(T* p) : ptr(p)     { if ( ptr ) ptr->addRef(); }
0477       RefCountHandle(const RefCountHandle& c) : ptr(c.ptr) { if ( ptr ) ptr->addRef(); }
0478       RefCountHandle(const RefCountHandle& c, const DetElement& ) : ptr(c.ptr) { if ( ptr ) ptr->addRef(); }
0479       virtual ~RefCountHandle()     { if ( ptr ) ptr->release(); }
0480       RefCountHandle& operator=(const RefCountHandle& c) {
0481         if ( &c != this )   {
0482           if ( ptr ) ptr->release();
0483           ptr = c.ptr;
0484           if ( ptr ) ptr->addRef();
0485         }
0486         return *this;
0487       }
0488     };
0489     
0490     /// Member function call-functor with no arguments
0491     template <typename R, typename T> struct ApplyMemFunc {
0492       typedef R (T::*memfunc_t)();
0493       memfunc_t func;
0494       ApplyMemFunc(memfunc_t f) : func(f)  {}
0495       void operator()(T* arg)  const {  if (arg) { (arg->*func)(); } }
0496     };
0497 
0498     /// Member function call-functor with 1 argument
0499     template <typename R, typename T, typename A1> struct ApplyMemFunc1 {
0500       typedef R (T::*memfunc_t)(A1 a1);
0501       memfunc_t func;
0502       A1& arg1;
0503       ApplyMemFunc1(memfunc_t f, A1& a1) : func(f), arg1(a1)  {}
0504       void operator()(T* arg)  const {  if ( arg ) { (arg->*func)(arg1); } }
0505     };
0506 
0507     /// Member function call-functor with 2 arguments
0508     template <typename R, typename T, typename A1, typename A2> struct ApplyMemFunc2 {
0509       typedef R (T::*memfunc_t)(A1 a1, A2 a2);
0510       memfunc_t func;
0511       A1& arg1;
0512       A2& arg2;
0513       ApplyMemFunc2(memfunc_t f, A1& a1, A2& a2) : func(f), arg1(a1), arg2(a2)  {}
0514       void operator()( T* arg)  const {  if ( arg ) { (arg->*func)(arg1, arg2); } }
0515     };
0516 
0517     /// Member function call-functor with no arguments (const version)
0518     template <typename R, typename T> struct ApplyMemFuncConst {
0519       typedef R (T::*memfunc_t)() const;
0520       memfunc_t func;
0521       ApplyMemFuncConst(memfunc_t f) : func(f)  {}
0522       void operator()(const T* arg)  const {  if ( arg ) { (arg->*func)(); } }
0523     };
0524 
0525     /// Member function call-functor with 1 argument (const version)
0526     template <typename R, typename T, typename A1> struct ApplyMemFuncConst1 {
0527       typedef R (T::*memfunc_t)(A1 a1) const;
0528       memfunc_t func;
0529       A1& arg1;
0530       ApplyMemFuncConst1(memfunc_t f, A1& a1) : func(f), arg1(a1)  {}
0531       void operator()(const T* arg)  const {  if ( arg ) { (arg->*func)(arg1); } }
0532     };
0533 
0534     /// Member function call-functor with 2 arguments (const version)
0535     template <typename R, typename T, typename A1, typename A2> struct ApplyMemFuncConst2 {
0536       typedef R (T::*memfunc_t)(A1 a1, A2 a2) const;
0537       memfunc_t func;
0538       A1& arg1;
0539       A2& arg2;
0540       ApplyMemFuncConst2(memfunc_t f, A1& a1, A2& a2) : func(f), arg1(a1), arg2(a2)  {}
0541       void operator()(const T* arg)  const {  if ( arg ) { (arg->*func)(arg1, arg2); } }
0542     };
0543 
0544     template <typename C, typename R, typename T>
0545     void call_member_func(C& object, R (T::*pmf)())
0546     {   std::for_each(object.begin(),object.end(),ApplyMemFunc<R,T>(pmf));    }
0547 
0548     template <typename C, typename R, typename T>
0549     void call_member_func(C& object, R (T::*pmf)() const)
0550     {   std::for_each(object.begin(),object.end(),ApplyMemFuncConst<R,T>(pmf));    }
0551 
0552     template <typename C, typename R, typename T, typename A1>
0553     void call_member_func(C& object, R (T::*pmf)(A1 a1), A1 a1)
0554     {   std::for_each(object.begin(),object.end(),ApplyMemFunc1<R,T,A1>(pmf,a1));    }
0555   
0556     template <typename C, typename R, typename T, typename A1>
0557     void call_member_func(C& object, R (T::*pmf)(A1 a1) const, A1 a1)
0558     {   std::for_each(object.begin(),object.end(),ApplyMemFuncConst1<R,T,A1>(pmf,a1));    }
0559   
0560   
0561     template <typename C, typename R, typename T, typename A1, typename A2>
0562     void call_member_func(C& object, R (T::*pmf)(A1 a1,A2 a2), A1 a1, A2 a2)
0563     {   std::for_each(object.begin(),object.end(),ApplyMemFunc2<R,T,A1,A2>(pmf,a1,a2));    }
0564   
0565     template <typename C, typename R, typename T, typename A1, typename A2>
0566     void call_member_func(C& object, R (T::*pmf)(A1 a1,A2 a2) const, A1 a1, A2 a2)
0567     {   std::for_each(object.begin(),object.end(),ApplyMemFuncConst2<R,T,A1,A2>(pmf,a1,a2));    }
0568   
0569 
0570     /// Generic map Functor to act on first element (key)
0571     template <typename M, typename FCN> class Apply1rst {
0572     public:
0573       const FCN& func;
0574       Apply1rst(const FCN& f) : func(f) {    }
0575       void operator()(std::pair<typename M::key_type const, typename M::mapped_type>& arg) const
0576       {   (func)(arg.first);    }
0577       void operator()(const std::pair<typename M::key_type const, typename M::mapped_type>& arg) const
0578       {   (func)(arg.first);    }
0579     };
0580 
0581     template <typename C, typename FCN> Apply1rst<C,FCN> apply__1rst_value(C&,const FCN& func)
0582     {  return Apply1rst<C,FCN>(func);  }
0583 
0584     template <typename C, typename FCN> void apply1rst(C& object,const FCN& func)
0585     {  std::for_each(object.begin(),object.end(),apply__1rst_value(object,func));  }
0586 
0587     template <typename C, typename R, typename T>
0588     void apply1rst(C& object, R (T::*pmf)())  
0589     {  std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFunc<R,T>(pmf)));  }
0590 
0591     template <typename C, typename R, typename T, typename A1>
0592     void apply1rst(C object, R (T::*pmf)(A1 a1), A1 a1)
0593     {  std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFunc1<R,T,A1>(pmf,a1)));  }
0594 
0595     template <typename C, typename R, typename T>
0596     void apply1rst(C& object, R (T::*pmf)() const)  
0597     {  std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFuncConst<R,T>(pmf)));  }
0598 
0599     template <typename C, typename R, typename T, typename A1>
0600     void apply1rst(C object, R (T::*pmf)(A1 a1) const, A1 a1)
0601     {  std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFuncConst1<R,T,A1>(pmf,a1)));  }
0602 
0603     /// Generic map Functor to act on second element (mapped type)
0604     template <typename M, typename FCN> class Apply2nd {
0605     public:
0606       const FCN& func;
0607       Apply2nd(const FCN& f) : func(f) {    }
0608       void operator()(std::pair<typename M::key_type const, typename M::mapped_type>& arg) const
0609       {   (func)(arg.second);    }
0610       void operator()(const std::pair<typename M::key_type const, typename M::mapped_type>& arg) const
0611       {   (func)(arg.second);    }
0612     };
0613 
0614     template <typename C, typename FCN> Apply2nd<C,FCN> apply__2nd_value(C&,const FCN& func)
0615     {  return Apply2nd<C,FCN>(func);  }
0616 
0617     template <typename C, typename FCN> void apply2nd(C& object,const FCN& func)
0618     {  std::for_each(object.begin(),object.end(),apply__2nd_value(object,func));  }
0619 
0620     template <typename C, typename R, typename T>
0621     void apply2nd(C& object, R (T::*pmf)())  
0622     {  std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFunc<R,T>(pmf)));  }
0623 
0624     template <typename C, typename R, typename T, typename A1>
0625     void apply2nd(C object, R (T::*pmf)(A1 a1), A1 a1)
0626     {  std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFunc1<R,T,A1>(pmf,a1)));  }
0627 
0628     template <typename C, typename R, typename T>
0629     void apply2nd(C& object, R (T::*pmf)() const)  
0630     {  std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFuncConst<R,T>(pmf)));  }
0631 
0632     template <typename C, typename R, typename T, typename A1>
0633     void apply2nd(C object, R (T::*pmf)(A1 a1) const, A1 a1)
0634     {  std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFuncConst1<R,T,A1>(pmf,a1)));  }
0635 
0636     /// Helper class to select the value from a mapped type
0637     /** 
0638      *  \author  M.Frank
0639      *  \version 1.0
0640      */
0641     template <typename C> struct get_2nd {
0642       const typename C::mapped_type& operator()( const typename C::value_type& v) const
0643       { return v.second; }
0644     };
0645 
0646     /// Data structure to manipulate a bitmask held by reference and represented by an integer
0647     /**
0648      * @author  M.Frank
0649      * @version 1.0
0650      */
0651     template <typename T> class ReferenceBitMask  {
0652     public:
0653       /// Reference to the data
0654       T& mask;
0655       /// Standard constructor
0656       ReferenceBitMask(T& arg);
0657       T value() const  {
0658         return mask;
0659       }
0660       void set(const T& arg)   {
0661         mask |= arg;
0662       }
0663       void clear(const T& arg)   {
0664         mask &= ~arg;
0665       }
0666       void clear()   {
0667         mask = 0;
0668       }
0669       bool isSet(const T& arg)  const {
0670         return (mask&arg) == arg;
0671       }
0672       bool anySet(const T& arg)  const {
0673         return (mask&arg) != 0;
0674       }
0675       bool testBit(int bit) const  {
0676         T arg = T(1)<<bit;
0677         return isSet(arg);
0678       }
0679       bool isNull() const {
0680         return mask == 0;
0681       }
0682     };
0683     /// Standard constructor
0684     template <typename T>  ReferenceBitMask<T>::ReferenceBitMask(T& arg) : mask(arg) {}
0685 
0686   }    // End namespace detail
0687 
0688   /// Class to perform dynamic casts using unknown pointers.
0689   /** @class Cast Primitives.h dd4hep/Primitives.h
0690    *
0691    *  It is mandatory that the pointers referred do actually
0692    *  support the asked functionalty.
0693    *  Miracles also I cannot do.....
0694    *
0695    *   @author  M.Frank
0696    *   @date    13.08.2013
0697    */
0698   class Cast {
0699   public:
0700 #ifdef __CINT__
0701     const std::type_info* type;
0702 #else
0703     const std::type_info& type;
0704 #endif
0705 #ifdef __APPLE__
0706     typedef void* (*cast_t)(const void*);
0707     cast_t      cast;
0708   protected:
0709     /// Initializing Constructor
0710     Cast(const std::type_info& t, cast_t c);
0711   public:
0712     template <typename TYPE> static void* _cast(const void* arg)  {
0713       TYPE* ptr = (TYPE*)arg;
0714       ptr = dynamic_cast<TYPE*>(ptr);
0715       return (void*)ptr;
0716     }
0717     /// Instantiation method    
0718     template <typename TYPE> static const Cast& instance() {
0719       static Cast c(typeid(TYPE),_cast<TYPE>);
0720       return c;
0721     }
0722 #else
0723     const void* abi_class;
0724   protected:
0725     /// Initializing Constructor
0726     Cast(const std::type_info& t);
0727   public:
0728     /// Instantiation method
0729     template <typename TYPE> static const Cast& instance() {
0730       static Cast c(typeid(TYPE));
0731       return c;
0732     }
0733 #endif
0734   protected:
0735     /// Default destructor
0736     virtual ~Cast();
0737 
0738   public:
0739     /// Apply cast using typeinfo instead of dynamic_cast
0740     void* apply_dynCast(const Cast& to, const void* ptr) const;
0741     /// Apply cast using typeinfo instead of dynamic_cast
0742     void* apply_upCast(const Cast& to, const void* ptr) const;
0743     /// Apply cast using typeinfo instead of dynamic_cast
0744     void* apply_downCast(const Cast& to, const void* ptr) const;
0745   };
0746 
0747   /// Class to perform dynamic casts using unknown pointers.
0748   /** @class ComponentCast Primitives.h dd4hep/Primitives.h
0749    *
0750    *  It is mandatory that the pointers referred do actually
0751    *  support the asked functionalty.
0752    *  Miracles also I cannot do.....
0753    *
0754    *   @author  M.Frank
0755    *   @date    13.08.2013
0756    */
0757   class ComponentCast {
0758   public:
0759 
0760     typedef void  (*destroy_t)(void*);
0761     destroy_t   destroy;
0762   private:
0763     const Cast& cast;
0764     
0765   private:
0766     /// Initializing Constructor
0767     ComponentCast(const Cast& c, destroy_t d) : destroy(d), cast(c)  {}
0768     /// Default destructor
0769     virtual ~ComponentCast() = default;
0770     /// Function template to create destructor
0771     template <typename TYPE> static void _destroy(void* arg)  {
0772       TYPE* ptr = (TYPE*)arg;
0773       if (ptr)    delete ptr;
0774     }
0775   public:
0776     template <typename TYPE> static ComponentCast& instance() {
0777       static ComponentCast c(Cast::instance<TYPE>(),_destroy<TYPE>);
0778       return c;
0779     }
0780     const std::type_info& type()  const   {
0781       return cast.type;
0782     }
0783     /// Apply cast using typeinfo instead of dynamic_cast
0784     void* apply_dynCast(const ComponentCast& to, const void* ptr) const  {
0785       return cast.apply_dynCast(to.cast, ptr);
0786     }
0787     /// Apply cast using typeinfo instead of dynamic_cast
0788     void* apply_upCast(const ComponentCast& to, const void* ptr) const   {
0789       return cast.apply_upCast(to.cast, ptr);
0790     }
0791     /// Apply cast using typeinfo instead of dynamic_cast
0792     void* apply_downCast(const ComponentCast& to, const void* ptr) const   {
0793       return cast.apply_downCast(to.cast, ptr);
0794     }
0795   };
0796 }      // End namespace dd4hep
0797 #endif // PARSERS_PRIMITIVES_H