Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-14 08:15: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 
0014 // Framework include files
0015 #ifdef DD4HEP_USE_TINYXML
0016 #include <XML/tinyxml.h>
0017 #else
0018 #include <xercesc/util/Xerces_autoconf_config.hpp>
0019 #include <xercesc/util/XMLString.hpp>
0020 #include <xercesc/dom/DOMElement.hpp>
0021 #include <xercesc/dom/DOMDocument.hpp>
0022 #include <xercesc/dom/DOMNodeList.hpp>
0023 #include <xercesc/dom/DOM.hpp>
0024 #include <XML/config.h>
0025 #endif
0026 
0027 #include <XML/XMLElements.h>
0028 #include <XML/Printout.h>
0029 #include <XML/XMLTags.h>
0030 
0031 // C/C++ include files
0032 #include <iostream>
0033 #include <stdexcept>
0034 #include <cstdio>
0035 #include <map>
0036 
0037 using namespace dd4hep::xml;
0038 static const size_t INVALID_NODE = ~0U;
0039 static int          s_float_precision = -1;
0040 
0041 // Forward declarations
0042 namespace dd4hep {
0043   std::pair<int, double> _toInteger(const std::string& value);
0044   std::pair<int, double> _toFloatingPoint(const std::string& value);
0045   void   _toDictionary(const std::string& name, const std::string& value, const std::string& typ);
0046   std::string _getEnviron(const std::string& env);
0047 }
0048 
0049 // Static storage
0050 namespace {
0051   bool s_resolve_environment = true;
0052   std::string _checkEnviron(const std::string& env)  {
0053     if ( s_resolve_environment )  {
0054       std::string r = dd4hep::_getEnviron(env);
0055       return r.empty() ? env : r;
0056     }
0057     return env;
0058   }
0059 }
0060 
0061 // Shortcuts
0062 #define _D(x)   Xml(x).d
0063 #define _E(x)   Xml(x).e
0064 #define _N(x)   Xml(x).n
0065 #define _L(x)   Xml(x).l
0066 #define _XE(x)  Xml(x).xe
0067 
0068 #ifdef DD4HEP_USE_TINYXML
0069 #define ELEMENT_NODE_TYPE TiXmlNode::ELEMENT
0070 #define getTagName          Value
0071 #define getTextContent      GetText
0072 #define getName             Name
0073 #define getValue            Value
0074 #define getNodeValue        Value
0075 #define getNodeType         Type
0076 #define setNodeValue        SetValue
0077 #define getParentNode       Parent()->ToElement
0078 #define getAttributeNode(x) AttributeNode(x)
0079 #define appendChild         LinkEndChild
0080 #define getOwnerDocument    GetDocument
0081 #define getDocumentElement  RootElement
0082 #define getDocumentURI      Value
0083 
0084 /// Union to ease castless object access in TinyXML
0085 union Xml {
0086   Xml(const void* ptr) : p(ptr) {}
0087   const void* p;
0088   TiXmlNode* n;
0089   TiXmlElement* e;
0090   TiXmlAttribute* a;
0091   TiXmlDocument* d;
0092   XmlElement* xe;
0093 };
0094 
0095 namespace {
0096   XmlElement* node_first(XmlElement* e, const Tag_t& t) {
0097     if ( t.str()=="*" ) return e ? (XmlElement*)_E(e)->FirstChildElement() : 0;
0098     return e ? (XmlElement*)_E(e)->FirstChildElement(t.str()) : 0;
0099   }
0100   size_t node_count(XmlElement* elt, const Tag_t& t) {
0101     size_t cnt = 0;
0102     TiXmlElement* e = Xml(elt).e;
0103     if ( t.str()=="*" )
0104       for(e=e->FirstChildElement();e; e=e->NextSiblingElement()) ++cnt;
0105     else
0106       for(e=e->FirstChildElement(t.str());e; e=e->NextSiblingElement(t.str())) ++cnt;
0107     return cnt;
0108   }
0109 }
0110 XmlChar* dd4hep::xml::XmlString::replicate(const XmlChar* c) {
0111   return c ? ::strdup(c) : 0;
0112 }
0113 XmlChar* dd4hep::xml::XmlString::transcode(const char* c)    {return c ? ::strdup(c) : 0;
0114 }
0115 void dd4hep::xml::XmlString::release(char** p) {
0116   if(p && *p)  {::free(*p); *p=0;}
0117 }
0118 size_t dd4hep::xml::XmlString::length(const char* p)  {
0119   return p ? ::strlen(p) : 0;
0120 }
0121 
0122 #else
0123 #define ELEMENT_NODE_TYPE xercesc::DOMNode::ELEMENT_NODE
0124 
0125 /// Union to ease castless object access when using XercesC
0126 union Xml {
0127   Xml(const void* ptr)
0128     : p(ptr) {
0129   }
0130   const void* p;
0131   xercesc::DOMNode* n;
0132   xercesc::DOMAttr* a;
0133   xercesc::DOMElement* e;
0134   xercesc::DOMDocument* d;
0135   xercesc::DOMNodeList* l;
0136   XmlElement* xe;
0137 };
0138 
0139 XmlChar* dd4hep::xml::XmlString::replicate(const XmlChar* c) {
0140   return xercesc::XMLString::replicate(c);
0141 }
0142 char* dd4hep::xml::XmlString::transcode(const XmlChar* c) {
0143   return xercesc::XMLString::transcode(c);
0144 }
0145 XmlChar* dd4hep::xml::XmlString::transcode(const char* c) {
0146   return xercesc::XMLString::transcode(c);
0147 }
0148 void dd4hep::xml::XmlString::release(XmlChar** p) {
0149   return xercesc::XMLString::release(p);
0150 }
0151 void dd4hep::xml::XmlString::release(char** p) {
0152   return xercesc::XMLString::release(p);
0153 }
0154 size_t dd4hep::xml::XmlString::length(const char* p)  {
0155   return p ? xercesc::XMLString::stringLen(p) : 0;
0156 }
0157 size_t dd4hep::xml::XmlString::length(const XmlChar* p)  {
0158   return p ? xercesc::XMLString::stringLen(p) : 0;
0159 }
0160 
0161 namespace {
0162   size_t node_count(XmlElement* e, const Tag_t& t) {
0163     size_t cnt = 0;
0164     if ( e )  {
0165       const std::string& tag = t;
0166       xercesc::DOMElement *ee = Xml(e).e;
0167       if ( ee )  {
0168         for(xercesc::DOMElement* elt=ee->getFirstElementChild(); elt; elt=elt->getNextElementSibling()) {
0169           if ( elt->getParentNode() == ee )   {
0170             std::string child_tag = _toString(elt->getTagName());
0171             if ( tag == "*" || child_tag == tag ) ++cnt;
0172           }
0173         }
0174       }
0175     }
0176     return cnt;
0177   }
0178   XmlElement* node_first(XmlElement* e, const Tag_t& t) {
0179     if ( e )  {
0180       const std::string& tag = t;
0181       xercesc::DOMElement* ee = Xml(e).e;
0182       if ( ee )  {
0183         for(xercesc::DOMElement* elt=ee->getFirstElementChild(); elt; elt=elt->getNextElementSibling()) {
0184           if ( elt->getParentNode() == ee )   {
0185             if ( tag == "*" ) return _XE(elt);
0186             std::string child_tag = _toString(elt->getTagName());
0187             if ( child_tag == tag ) return _XE(elt);
0188           }
0189         }
0190       }
0191     }
0192     return 0;
0193   }
0194 }
0195 
0196 /// Convert XML char to std::string
0197 std::string dd4hep::xml::_toString(const XmlChar *toTranscode) {
0198   char *buff = XmlString::transcode(toTranscode);
0199   std::string tmp(buff == 0 ? "" : buff);
0200   XmlString::release(&buff);
0201   if ( tmp.length()<3 ) return tmp;
0202   if ( !(tmp[0] == '$' && tmp[1] == '{') ) return tmp;
0203   tmp = _checkEnviron(tmp);
0204   return tmp;
0205 }
0206 #endif
0207 
0208 namespace {
0209   Attribute attribute_node(XmlElement* n, const XmlChar* t) {
0210     return Attribute(_E(n)->getAttributeNode(t));
0211   }
0212   const XmlChar* attribute_value(Attribute a) {
0213     return Xml(a).a->getValue();
0214   }
0215 #if 0
0216   int node_type(XmlNode* n) {return Xml(n).n->getNodeType();}
0217   int node_type(Handle_t n) {return Xml(n.ptr()).n->getNodeType();}
0218 #endif
0219 }
0220 
0221 /// Change floating point precision on conversion to string
0222 int dd4hep::xml::set_float_precision(int precision)    {
0223   int tmp = s_float_precision;
0224   s_float_precision = precision;
0225   return tmp;
0226 }
0227 
0228 /// Access floating point precision on conversion to string
0229 int dd4hep::xml::get_float_precision()    {
0230   return s_float_precision;
0231 }
0232 
0233 /// Convert attribute value to string
0234 std::string dd4hep::xml::_toString(Attribute attr) {
0235   if (attr)
0236     return _toString(attribute_value(attr));
0237   return "";
0238 }
0239 
0240 template <typename T> static inline std::string __to_string(T value, const char* fmt) {
0241   char text[128];
0242   ::snprintf(text, sizeof(text), fmt, value);
0243   return text;
0244 }
0245 
0246 /// Do-nothing version. Present for completeness and argument interchangeability
0247 std::string dd4hep::xml::_toString(const char* s) {
0248   if ( !s || *s == 0 ) return "";
0249   else if ( !(*s == '$' && *(s+1) == '{') ) return s;
0250   return _checkEnviron(s);
0251 }
0252 
0253 /// Do-nothing version. Present for completeness and argument interchangeability
0254 std::string dd4hep::xml::_toString(const std::string& s) {
0255   if ( s.length() < 3 || s[0] != '$' ) return s;
0256   else if ( !(s[0] == '$' && s[1] == '{') ) return s;
0257   return _checkEnviron(s);
0258 }
0259 
0260 /// Format unsigned long integer to string with arbitrary format
0261 std::string dd4hep::xml::_toString(unsigned long v, const char* fmt) {
0262   return __to_string(v, fmt);
0263 }
0264 
0265 /// Format unsigned integer (32 bits) to string with arbitrary format
0266 std::string dd4hep::xml::_toString(unsigned int v, const char* fmt) {
0267   return __to_string(v, fmt);
0268 }
0269 
0270 /// Format signed integer (32 bits) to string with arbitrary format
0271 std::string dd4hep::xml::_toString(int v, const char* fmt) {
0272   return __to_string(v, fmt);
0273 }
0274 
0275 /// Format signed long integer to string with arbitrary format
0276 std::string dd4hep::xml::_toString(long v, const char* fmt)   {
0277   return __to_string(v, fmt);
0278 }
0279 
0280 /// Format single procision float number (32 bits) to string with arbitrary format
0281 std::string dd4hep::xml::_toString(float v, const char* fmt) {
0282   if ( s_float_precision >= 0 )   {
0283     char format[32];
0284     ::snprintf(format, sizeof(format), "%%.%de", s_float_precision);
0285     return __to_string(v, format);
0286   }
0287   return __to_string(v, fmt);
0288 }
0289 
0290 /// Format double procision float number (64 bits) to string with arbitrary format
0291 std::string dd4hep::xml::_toString(double v, const char* fmt) {
0292   if ( s_float_precision >= 0 )   {
0293     char format[32];
0294     ::snprintf(format, sizeof(format), "%%.%de", s_float_precision);
0295     return __to_string(v, format);
0296   }
0297   return __to_string(v, fmt);
0298 }
0299 
0300 /// Convert Strng_t to std::string
0301 std::string dd4hep::xml::_toString(const Strng_t& s)   {
0302   return _toString(Tag_t(s));
0303 }
0304 
0305 /// Convert Tag_t to std::string
0306 std::string dd4hep::xml::_toString(const Tag_t& s)     {
0307   return s.str();
0308 }
0309 
0310 /// Format pointer to string with arbitrary format
0311 std::string dd4hep::xml::_ptrToString(const void* v, const char* fmt) {
0312   return __to_string(v, fmt);
0313 }
0314 
0315 long dd4hep::xml::_toLong(const XmlChar* value) {
0316   if (value) {
0317     std::string s = _toString(value);
0318     return dd4hep::_toInteger(s).second;
0319   }
0320   return -1;
0321 }
0322 
0323 unsigned long dd4hep::xml::_toULong(const XmlChar* value) {
0324   long val = _toLong(value);
0325   if ( val >= 0 ) return (unsigned long) val;
0326   std::string s = _toString(value);
0327   throw std::runtime_error("dd4hep: Severe error during expression evaluation of " + s);
0328 }
0329 
0330 int dd4hep::xml::_toInt(const XmlChar* value)   {
0331   return (int)_toLong(value);
0332 }
0333 
0334 unsigned int dd4hep::xml::_toUInt(const XmlChar* value) {
0335   return (unsigned int)_toULong(value);
0336 }
0337 
0338 bool dd4hep::xml::_toBool(const XmlChar* value) {
0339   if (value)   {
0340     std::string s = _toString(value);
0341     char   c = ::toupper(s[0]);
0342     if ( c == 'T' || c == '1' ) return true;
0343     if ( c == 'F' || c == '0' ) return false;
0344     return _toInt(value) != 0;
0345   }
0346   return false;
0347 }
0348 
0349 float dd4hep::xml::_toFloat(const XmlChar* value) {
0350   if (value)   {
0351     std::string s = _toString(value);
0352     return (float) dd4hep::_toFloatingPoint(s).second;
0353   }
0354   return 0.0;
0355 }
0356 
0357 double dd4hep::xml::_toDouble(const XmlChar* value) {
0358   if (value)   {
0359     std::string s = _toString(value);
0360     return dd4hep::_toFloatingPoint(s).second;
0361   }
0362   return 0.0;
0363 }
0364 
0365 void dd4hep::xml::_toDictionary(const XmlChar* name, const XmlChar* value) {
0366   std::string n = _toString(name).c_str(), v = _toString(value);
0367   dd4hep::_toDictionary(n, v, "number");
0368 }
0369 
0370 /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0371 void dd4hep::xml::_toDictionary(const XmlChar* name, const Strng_t& s)   {
0372   return _toDictionary(name, s.ptr());
0373 }
0374 
0375 /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0376 void dd4hep::xml::_toDictionary(const XmlChar* name, const Tag_t& t)   {
0377   return _toDictionary(name, t.ptr());
0378 }
0379 
0380 template <typename T>
0381 void dd4hep::xml::_toDictionary(const XmlChar* name, T value)   {
0382   Strng_t item = _toString(value);
0383   const XmlChar* item_value = item;
0384   _toDictionary(name, item_value);
0385 }
0386 
0387 #ifndef DD4HEP_USE_TINYXML
0388 template void dd4hep::xml::_toDictionary(const XmlChar* name, const char* value);
0389 #endif
0390 template void dd4hep::xml::_toDictionary(const XmlChar* name, const Tag_t& value);
0391 template void dd4hep::xml::_toDictionary(const XmlChar* name, const Strng_t& value);
0392 template void dd4hep::xml::_toDictionary(const XmlChar* name, const std::string& value);
0393 template void dd4hep::xml::_toDictionary(const XmlChar* name, unsigned long value);
0394 template void dd4hep::xml::_toDictionary(const XmlChar* name, unsigned int value);
0395 template void dd4hep::xml::_toDictionary(const XmlChar* name, unsigned short value);
0396 template void dd4hep::xml::_toDictionary(const XmlChar* name, int value);
0397 template void dd4hep::xml::_toDictionary(const XmlChar* name, long value);
0398 template void dd4hep::xml::_toDictionary(const XmlChar* name, short value);
0399 template void dd4hep::xml::_toDictionary(const XmlChar* name, float value);
0400 template void dd4hep::xml::_toDictionary(const XmlChar* name, double value);
0401 
0402 /// Evaluate string constant using environment stored in the evaluator
0403 std::string dd4hep::xml::getEnviron(const std::string& env)   {
0404   return dd4hep::_getEnviron(env);
0405 }
0406 
0407 /// Enable/disable environment resolution when parsing strings
0408 bool dd4hep::xml::enableEnvironResolution(bool new_value)   {
0409   bool tmp = s_resolve_environment;
0410   s_resolve_environment = new_value;
0411   return tmp;
0412 }
0413 
0414 template <typename B>
0415 static inline std::string i_add(const std::string& a, B b) {
0416   std::string r = a;
0417   r += b;
0418   return r;
0419 }
0420 
0421 Strng_t dd4hep::xml::operator+(const Strng_t& a, const std::string& b) {
0422   return _toString(a.ptr()) + b;
0423 }
0424 
0425 Strng_t dd4hep::xml::operator+(const std::string& a, const Strng_t& b) {
0426   return a + _toString(b.ptr());
0427 }
0428 
0429 Strng_t dd4hep::xml::operator+(const Strng_t& a, const char* b) {
0430   return _toString(a.ptr()) + b;
0431 }
0432 
0433 Strng_t dd4hep::xml::operator+(const char* a, const Strng_t& b) {
0434   return std::string(a) + _toString(b.ptr());
0435 }
0436 
0437 Strng_t dd4hep::xml::operator+(const Strng_t& a, const Strng_t& b) {
0438   return _toString(a.ptr()) + _toString(b.ptr());
0439 }
0440 
0441 Tag_t dd4hep::xml::operator+(const Tag_t& a, const char* b) {
0442   std::string res = a.str() + b;
0443   return Tag_t(res);
0444 }
0445 
0446 Tag_t dd4hep::xml::operator+(const char* a, const Tag_t& b) {
0447   std::string res = a + b.str();
0448   return Tag_t(res);
0449 }
0450 
0451 Tag_t dd4hep::xml::operator+(const Tag_t& a, const Strng_t& b) {
0452   std::string res = a.str() + _toString(b);
0453   return Tag_t(res);
0454 }
0455 
0456 Tag_t dd4hep::xml::operator+(const Tag_t& a, const std::string& b) {
0457   std::string res = a.str() + b;
0458   return Tag_t(res);
0459 }
0460 
0461 #ifndef DD4HEP_USE_TINYXML
0462 Strng_t dd4hep::xml::operator+(const Strng_t& a, const XmlChar* b) {
0463   std::string res = _toString(a.ptr()) + _toString(b);
0464   return Tag_t(res);
0465 }
0466 
0467 Strng_t dd4hep::xml::operator+(const XmlChar* a, const Strng_t& b) {
0468   std::string res = _toString(a) + _toString(b.ptr());
0469   return Tag_t(res);
0470 }
0471 
0472 Strng_t dd4hep::xml::operator+(const XmlChar* a, const std::string& b) {
0473   std::string res = _toString(a) + b;
0474   return Tag_t(res);
0475 }
0476 
0477 Strng_t dd4hep::xml::operator+(const std::string& a, const XmlChar* b) {
0478   std::string res = a + _toString(b);
0479   return Tag_t(res);
0480 }
0481 
0482 Tag_t dd4hep::xml::operator+(const Tag_t& a, const XmlChar* b) {
0483   std::string res = a.str() + _toString(b);
0484   return Tag_t(res);
0485 }
0486 
0487 Strng_t& Strng_t::operator=(const XmlChar* s) {
0488   if (m_xml)
0489     XmlString::release (&m_xml);
0490   m_xml = s ? XmlString::replicate(s) : 0;
0491   return *this;
0492 }
0493 #endif
0494 
0495 Strng_t& Strng_t::operator=(const char* s) {
0496   if (m_xml)
0497     XmlString::release (&m_xml);
0498   m_xml = s ? XmlString::transcode(s) : 0;
0499   return *this;
0500 }
0501 
0502 Strng_t& Strng_t::operator=(const Strng_t& s) {
0503   if (this != &s) {
0504     if (m_xml)
0505       XmlString::release (&m_xml);
0506     m_xml = XmlString::replicate(s.m_xml);
0507   }
0508   return *this;
0509 }
0510 
0511 Strng_t& Strng_t::operator=(const std::string& s) {
0512   if (m_xml)
0513     XmlString::release (&m_xml);
0514   m_xml = XmlString::transcode(s.c_str());
0515   return *this;
0516 }
0517 
0518 Tag_t& Tag_t::operator=(const Tag_t& s) {
0519   if (this != &s) {
0520     m_str = s.m_str;
0521     if (m_xml)
0522       XmlString::release (&m_xml);
0523     m_xml = XmlString::transcode(m_str.c_str());
0524   }
0525   return *this;
0526 }
0527 
0528 Tag_t& Tag_t::operator=(const char* s) {
0529   if (m_xml)
0530     XmlString::release (&m_xml);
0531   if (s) {
0532     m_xml = XmlString::transcode(s);
0533     m_str = s;
0534   }
0535   else {
0536     m_xml = 0;
0537     m_str = "";
0538   }
0539   return *this;
0540 }
0541 
0542 Tag_t& Tag_t::operator=(const Strng_t& s) {
0543   if (m_xml)  {
0544     XmlString::release (&m_xml);
0545   }
0546   char* ns = s.m_xml ? XmlString::transcode(s.m_xml) : 0;
0547   m_str = ns ? ns : "";
0548   m_xml = XmlString::transcode(m_str.c_str());
0549   if (ns)  {
0550     XmlString::release(&ns);
0551   }
0552   return *this;
0553 }
0554 
0555 Tag_t& Tag_t::operator=(const std::string& s) {
0556   if (m_xml)
0557     XmlString::release (&m_xml);
0558   m_xml = XmlString::transcode(s.c_str());
0559   m_str = s;
0560   return *this;
0561 }
0562 
0563 /// Copy constructor
0564 NodeList::NodeList(const NodeList& copy)
0565   : m_tag(copy.m_tag), m_node(copy.m_node), m_ptr(0)
0566 {
0567   reset();
0568 }
0569 
0570 /// Initializing constructor
0571 NodeList::NodeList(XmlElement* node, const XmlChar* tag_value)
0572   : m_tag(tag_value), m_node(node), m_ptr(0)
0573 {
0574   reset();
0575 }
0576 
0577 /// Default destructor
0578 NodeList::~NodeList() {
0579 }
0580 
0581 /// Reset the nodelist
0582 XmlElement* NodeList::reset() {
0583   return m_ptr=node_first(m_node,m_tag);
0584 }
0585 
0586 /// Advance to next element
0587 XmlElement* NodeList::next() const {
0588 #ifdef DD4HEP_USE_TINYXML
0589   if ( m_tag.str()=="*" )
0590     return m_ptr =_XE(m_ptr ? _E(m_ptr)->NextSiblingElement() : 0);
0591   return m_ptr = _XE(m_ptr ? _E(m_ptr)->NextSiblingElement(m_tag.str()) : 0);
0592 #else
0593   xercesc::DOMElement *elt = Xml(m_ptr).e;
0594   for(elt=elt->getNextElementSibling(); elt; elt=elt->getNextElementSibling()) {
0595     if ( m_tag.str() == "*" ) return m_ptr=Xml(elt).xe;
0596     std::string child_tag = _toString(elt->getTagName());
0597     if ( child_tag == m_tag ) return m_ptr=Xml(elt).xe;
0598   }
0599   return m_ptr=0;
0600 #endif
0601 }
0602 
0603 /// Go back to previous element
0604 XmlElement* NodeList::previous() const {
0605 #ifdef DD4HEP_USE_TINYXML
0606   if ( m_tag.str()=="*" )
0607     return m_ptr = _XE(m_ptr ? _E(m_ptr)->PreviousSiblingElement() : 0);
0608   return m_ptr = _XE(m_ptr ? _E(m_ptr)->PreviousSiblingElement(m_tag) : 0);
0609 #else
0610   xercesc::DOMElement *elt = Xml(m_ptr).e;
0611   for(elt=elt->getPreviousElementSibling(); elt; elt=elt->getPreviousElementSibling()) {
0612     if ( m_tag.str()=="*" ) return m_ptr=Xml(elt).xe;
0613     std::string child_tag = _toString(elt->getTagName());
0614     if ( child_tag == m_tag ) return m_ptr=Xml(elt).xe;
0615   }
0616   return m_ptr=0;
0617 #endif
0618 }
0619 
0620 /// Assignment operator
0621 NodeList& NodeList::operator=(const NodeList& l) {
0622   if (this != &l) {
0623     m_tag = l.m_tag;
0624     m_node = l.m_node;
0625     reset();
0626   }
0627   return *this;
0628 }
0629 
0630 /// Unicode text access to the element's tag. Tis must be wrong ....
0631 const XmlChar* Handle_t::rawTag() const {
0632   return _E(m_node)->getTagName();
0633 }
0634 
0635 /// Unicode text access to the element's text
0636 const XmlChar* Handle_t::rawText() const {
0637   return _E(m_node)->getTextContent();
0638 }
0639 
0640 /// Unicode text access to the element's value
0641 const XmlChar* Handle_t::rawValue() const {
0642   return _N(m_node)->getNodeValue();
0643 }
0644 
0645 /// Clone the DOMelement - with the option of a deep copy
0646 Handle_t Handle_t::clone(XmlDocument* new_doc) const {
0647   if (m_node) {
0648 #ifdef DD4HEP_USE_TINYXML
0649     if ( new_doc ) {}
0650     if ( _N(m_node)->Type() == ELEMENT_NODE_TYPE ) {
0651       XmlElement* e = _XE(_N(m_node)->Clone()->ToElement());
0652       if ( e ) return e;
0653     }
0654     throw std::runtime_error("TiXml: Handle_t::clone: Invalid source handle type [No element type].");
0655 #else
0656     return Elt_t(_D(new_doc)->importNode(_E(m_node), true));
0657 #endif
0658   }
0659   throw std::runtime_error("Xml: Handle_t::clone: Invalid source handle.");
0660 }
0661 
0662 /// Access the element's parent element
0663 Handle_t Handle_t::parent() const {
0664   return Elt_t(m_node ? _N(m_node)->getParentNode() : 0);
0665 }
0666 
0667 /// Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
0668 Attribute Handle_t::attr_nothrow(const XmlChar* tag_value) const {
0669   return attribute_node(m_node, tag_value);
0670 }
0671 
0672 /// Check for the existence of a named attribute
0673 bool Handle_t::hasAttr(const XmlChar* tag_value) const {
0674   return m_node && 0 != _E(m_node)->getAttributeNode(tag_value);
0675 }
0676 
0677 /// Retrieve a collection of all attributes of this DOM element
0678 std::vector<Attribute> Handle_t::attributes() const {
0679   std::vector < Attribute > attrs;
0680   if (m_node) {
0681 #ifdef DD4HEP_USE_TINYXML
0682     for(TiXmlAttribute* a=_E(m_node)->FirstAttribute(); a; a=a->Next())
0683       attrs.emplace_back(Attribute(a));
0684 #else
0685     xercesc::DOMNamedNodeMap* l = _E(m_node)->getAttributes();
0686     for (XmlSize_t i = 0, n = l->getLength(); i < n; ++i) {
0687       xercesc::DOMNode* attr_node = l->item(i);
0688       attrs.emplace_back(Attribute(attr_node));
0689     }
0690 #endif
0691   }
0692   return attrs;
0693 }
0694 
0695 size_t Handle_t::numChildren(const XmlChar* t, bool throw_exception) const {
0696   size_t n = node_count(m_node, t);
0697   if (n == INVALID_NODE && !throw_exception)
0698     return 0;
0699   else if (n != INVALID_NODE)
0700     return n;
0701   std::string msg = "Handle_t::numChildren: ";
0702   if (m_node)
0703     msg += "Element [" + tag() + "] has no children of type '" + _toString(t) + "'";
0704   else
0705     msg += "Element [INVALID] has no children of type '" + _toString(t) + "'";
0706   throw std::runtime_error(msg);
0707 }
0708 
0709 /// Remove a single child node identified by its handle from the tree of the element
0710 Handle_t Handle_t::child(const XmlChar* t, bool throw_exception) const {
0711   Elt_t e = node_first(m_node, t);
0712   if (e || !throw_exception)
0713     return e;
0714   std::string msg = "Handle_t::child: ";
0715   if (m_node)
0716     msg += "Element [" + tag() + "] has no child of type '" + _toString(t) + "'";
0717   else
0718     msg += "Element [INVALID]. Cannot remove child of type: '" + _toString(t) + "'";
0719   throw std::runtime_error(msg);
0720 }
0721 
0722 NodeList Handle_t::children(const XmlChar* tag_value) const {
0723   return NodeList(m_node, tag_value);
0724 }
0725 
0726 /// Append a DOM element to the current node
0727 void Handle_t::append(Handle_t e) const {
0728   _N(m_node)->appendChild(_N(e.ptr()));
0729 }
0730 
0731 /// Remove a single child node identified by its handle from the tree of the element
0732 Handle_t Handle_t::remove(Handle_t node) const {
0733 #ifdef DD4HEP_USE_TINYXML
0734   bool e = (m_node && node.ptr() ? _N(m_node)->RemoveChild(_N(node.ptr())) : false);
0735 #else
0736   Elt_t e = Elt_t(m_node && node.ptr() ? _N(m_node)->removeChild(_N(node.ptr())) : 0);
0737 #endif
0738   if (e)
0739     return node.ptr();
0740   std::string msg = "Handle_t::remove: ";
0741   if (m_node && node.ptr())
0742     msg += "Element [" + tag() + "] has no child of type '" + node.tag() + "'";
0743   else if (node)
0744     msg += "Element [INVALID]. Cannot remove child of type: '" + node.tag() + "'";
0745   else if (!node)
0746     msg += "Element [INVALID]. Cannot remove [INVALID] child. Big Shit!!!!";
0747 
0748   throw std::runtime_error(msg);
0749 }
0750 
0751 /// Remove children with a given tag name from the DOM node
0752 void Handle_t::removeChildren(const XmlChar* tag_value) const {
0753 #ifdef DD4HEP_USE_TINYXML
0754   for(TiXmlNode* n=_E(m_node)->FirstChildElement(tag_value);n;n=_E(m_node)->FirstChildElement(tag_value))
0755     n->RemoveChild(n);
0756 #else
0757   xercesc::DOMElement* e = _E(m_node);
0758   xercesc::DOMNodeList* l = e->getElementsByTagName(tag_value);
0759   for (XmlSize_t i = 0, n = l->getLength(); i < n; ++i)
0760     e->removeChild(l->item(i));
0761 #endif
0762 }
0763 
0764 bool Handle_t::hasChild(const XmlChar* tag_value) const {
0765   return node_first(m_node, tag_value) != 0;
0766 }
0767 
0768 /// Set the element's value
0769 void Handle_t::setValue(const XmlChar* text_value) const {
0770   _N(m_node)->setNodeValue(text_value);
0771 }
0772 
0773 /// Set the element's value
0774 void Handle_t::setValue(const std::string& text_value) const {
0775 #ifdef DD4HEP_USE_TINYXML
0776   _N(m_node)->setNodeValue(text_value.c_str());
0777 #else
0778   _N(m_node)->setNodeValue(Strng_t(text_value));
0779 #endif
0780 }
0781 
0782 /// Set the element's text
0783 void Handle_t::setText(const XmlChar* text_value) const {
0784 #ifdef DD4HEP_USE_TINYXML
0785   _N(m_node)->LinkEndChild(new TiXmlText(text_value));
0786 #else
0787   _N(m_node)->setTextContent(text_value);
0788 #endif
0789 }
0790 
0791 /// Set the element's text
0792 void Handle_t::setText(const std::string& text_value) const {
0793 #ifdef DD4HEP_USE_TINYXML
0794   _N(m_node)->LinkEndChild(new TiXmlText(text_value.c_str()));
0795 #else
0796   _N(m_node)->setTextContent(Strng_t(text_value));
0797 #endif
0798 }
0799 
0800 /// Remove all attributes of this element
0801 void Handle_t::removeAttrs() const {
0802 #ifdef DD4HEP_USE_TINYXML
0803   _E(m_node)->ClearAttributes();
0804 #else
0805   xercesc::DOMElement* e = _E(m_node);
0806   xercesc::DOMNamedNodeMap* l = e->getAttributes();
0807   for (XmlSize_t i = 0, n = l->getLength(); i < n; ++i) {
0808     xercesc::DOMAttr* a = (xercesc::DOMAttr*) l->item(i);
0809     e->removeAttributeNode(a);
0810   }
0811 #endif
0812 }
0813 
0814 /// Set attributes as in argument handle
0815 #ifdef DD4HEP_USE_TINYXML
0816 void Handle_t::setAttrs(Handle_t elt) const {
0817   removeAttrs();
0818   TiXmlElement* e = Xml(elt).e;
0819   for(TiXmlAttribute* a=e->FirstAttribute(); a; a=a->Next())
0820     e->SetAttribute(a->Name(),a->Value());
0821 }
0822 #else
0823 void Handle_t::setAttrs(Handle_t /* elt */) const {
0824   removeAttrs();
0825   xercesc::DOMElement* e = _E(m_node);
0826   xercesc::DOMNamedNodeMap* l = e->getAttributes();
0827   for (XmlSize_t i = 0, len = l->getLength(); i < len; ++i) {
0828     xercesc::DOMNode* n = l->item(i);
0829     if (n->getNodeType() == xercesc::DOMNode::ATTRIBUTE_NODE) {
0830       xercesc::DOMAttr* a = (xercesc::DOMAttr*) n;
0831       e->setAttribute(a->getName(), a->getValue());
0832     }
0833   }
0834 }
0835 #endif
0836 
0837 /// Access attribute pointer by the attribute's unicode name (throws exception if not present)
0838 Attribute Handle_t::attr_ptr(const XmlChar* t) const {
0839   Attribute a = attribute_node(m_node, t);
0840   if (0 != a)
0841     return a;
0842   std::string msg = "Handle_t::attr_ptr: ";
0843   if (m_node)
0844     msg += "Element [" + tag() + "] has no attribute of type '" + _toString(t) + "'";
0845   else
0846     msg += "Element [INVALID] has no attribute of type '" + _toString(t) + "'";
0847   throw std::runtime_error(msg);
0848 }
0849 
0850 /// Access attribute name (throws exception if not present)
0851 const XmlChar* Handle_t::attr_name(const Attribute a) const {
0852   if (a) {
0853     return Xml(a).a->getName();
0854   }
0855   throw std::runtime_error("Attempt to access invalid XML attribute object!");
0856 }
0857 
0858 /// Access attribute value by the attribute's unicode name (throws exception if not present)
0859 const XmlChar* Handle_t::attr_value(const XmlChar* attr_tag) const {
0860   return attribute_value(attr_ptr(attr_tag));
0861 }
0862 
0863 /// Access attribute value by the attribute  (throws exception if not present)
0864 const XmlChar* Handle_t::attr_value(const Attribute attr_val) const {
0865   return attribute_value(attr_val);
0866 }
0867 
0868 /// Access attribute value by the attribute's unicode name (no exception thrown if not present)
0869 const XmlChar* Handle_t::attr_value_nothrow(const XmlChar* attr_tag) const {
0870   Attribute a = attr_nothrow(attr_tag);
0871   return a ? attribute_value(a) : 0;
0872 }
0873 
0874 /// Generic attribute setter with integer value
0875 Attribute Handle_t::setAttr(const XmlChar* nam, int val) const {
0876   char txt[32];
0877   ::snprintf(txt, sizeof(txt), "%d", val);
0878   return setAttr(nam, Strng_t(txt));
0879 }
0880 
0881 /// Generic attribute setter with boolen value
0882 Attribute Handle_t::setAttr(const XmlChar* name, bool val) const {
0883   char txt[32];
0884   ::snprintf(txt, sizeof(txt), "%s", val ? "true" : "false");
0885   return setAttr(name, Strng_t(txt));
0886 }
0887 
0888 /// Generic attribute setter with floating point value
0889 Attribute Handle_t::setAttr(const XmlChar* name, float val) const {
0890   char txt[32];
0891   ::snprintf(txt, sizeof(txt), "%.8e", val);
0892   return setAttr(name, Strng_t(txt));
0893 }
0894 
0895 /// Generic attribute setter with double precision floating point value
0896 Attribute Handle_t::setAttr(const XmlChar* name, double val) const {
0897   char txt[32];
0898   ::snprintf(txt, sizeof(txt), "%.8e", val);
0899   return setAttr(name, Strng_t(txt));
0900 }
0901 
0902 /// Generic attribute setter with string value
0903 Attribute Handle_t::setAttr(const XmlChar* name, const std::string& val) const {
0904   return setAttr(name, Strng_t(val.c_str()));
0905 }
0906 
0907 #ifndef DD4HEP_USE_TINYXML
0908 Attribute Handle_t::setAttr(const XmlChar* name, const char* v) const {
0909   return setAttr(name, Strng_t(v));
0910 }
0911 #endif
0912 
0913 /// Generic attribute setter with XmlAttr value
0914 Attribute Handle_t::setAttr(const XmlChar* nam, const Attribute v) const {
0915   return v ? setAttr(nam, attribute_value(v)) : 0;
0916 }
0917 
0918 /// Generic attribute setter with unicode value
0919 Attribute Handle_t::setAttr(const XmlChar* nam, const XmlChar* val) const {
0920 #ifdef DD4HEP_USE_TINYXML
0921   TiXmlElement* e = Xml(m_node).e;
0922   e->SetAttribute(nam,val);
0923   return Attribute(e->AttributeNode(nam));
0924 #else
0925   xercesc::DOMElement* e = _E(m_node);
0926   xercesc::DOMAttr* a = e->getAttributeNode(nam);
0927   if (!a) {
0928     a = e->getOwnerDocument()->createAttribute(nam);
0929     e->setAttributeNode(a);
0930   }
0931   a->setValue(val);
0932   return Attribute(a);
0933 #endif
0934 }
0935 
0936 /// Add reference child as a new child node. The obj must have the "name" attribute!
0937 Handle_t Handle_t::setRef(const XmlChar* tag_value, const XmlChar* ref_name) {
0938   Element me(*this);
0939   Element ref(me.document(), tag_value);
0940   ref.setAttr(Unicode_ref, ref_name);
0941   me.append(ref);
0942   return ref;
0943 }
0944 
0945 /// Add reference child as a new child node. The obj must have the "name" attribute!
0946 Handle_t Handle_t::setRef(const XmlChar* tag_value, const std::string& ref_name) {
0947   return setRef(tag_value, Strng_t(ref_name).ptr());
0948 }
0949 
0950 /// Checksum (sub-)tree of a xml document/tree
0951 static unsigned int adler32(unsigned int adler, const XmlChar* xml_buff, size_t len) {
0952 #define DO1(buf,i)  {s1 +=(unsigned char)buf[i]; s2 += s1;}
0953 #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
0954 #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
0955 #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
0956 #define DO16(buf)   DO8(buf,0); DO8(buf,8);
0957 
0958   static const unsigned int BASE = 65521; /* largest prime smaller than 65536 */
0959   /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
0960   static const unsigned int NMAX = 5550;
0961   unsigned int s1 = adler & 0xffff;
0962   unsigned int s2 = (adler >> 16) & 0xffff;
0963   const char* buf = (const char*)xml_buff;
0964 
0965   if (buf == NULL)
0966     return 1;
0967 
0968   while (len > 0) {
0969     int k = len < NMAX ? (int) len : NMAX;
0970     len -= k;
0971     while (k >= 16) {
0972       DO16(buf);
0973       buf += 16;
0974       k -= 16;
0975     }
0976     if (k != 0)
0977       do {
0978         s1 += (unsigned char) *buf++;
0979         s2 += s1;
0980       } while (--k);
0981     s1 %= BASE;
0982     s2 %= BASE;
0983   }
0984   unsigned int result = (s2 << 16) | s1;
0985   return result;
0986 }
0987 
0988 /// Checksum (sub-)tree of a xml document/tree
0989 typedef unsigned int (fcn_t)(unsigned int, const XmlChar*, size_t);
0990 unsigned int Handle_t::checksum(unsigned int param, fcn_t fcn) const {
0991 #ifdef DD4HEP_USE_TINYXML
0992   typedef std::map<std::string, std::string> StringMap;
0993   TiXmlNode* n = Xml(m_node).n;
0994   if ( n ) {
0995     if ( 0 == fcn ) fcn = adler32;
0996     switch (n->Type()) {
0997     case TiXmlNode::ELEMENT: {
0998       std::map<std::string,std::string> m;
0999       TiXmlElement* e = n->ToElement();
1000       TiXmlAttribute* p=e->FirstAttribute();
1001       for(; p; p=p->Next()) m.emplace(p->Name(),p->Value());
1002       param = (*fcn)(param,e->Value(),::strlen(e->Value()));
1003       for(StringMap::const_iterator i=m.begin();i!=m.end();++i) {
1004         param = (*fcn)(param,(*i).first.c_str(),(*i).first.length());
1005         param = (*fcn)(param,(*i).second.c_str(),(*i).second.length());
1006       }
1007       break;
1008     }
1009     case TiXmlNode::TEXT:
1010       param = (*fcn)(param,n->ToText()->Value(),::strlen(n->ToText()->Value()));
1011       break;
1012     case TiXmlNode::UNKNOWN:
1013     case TiXmlNode::COMMENT:
1014     case TiXmlNode::DOCUMENT:
1015     case TiXmlNode::DECLARATION:
1016     default:
1017       break;
1018     }
1019     for(TiXmlNode* c=n->FirstChild(); c; c=c->NextSibling())
1020       param = Handle_t((XmlElement*)c->ToElement()).checksum(param,fcn);
1021   }
1022 #else
1023   if ( 0 == fcn ) fcn = adler32;
1024   if ( 0 == fcn )  {
1025   }
1026 #endif
1027   return param;
1028 }
1029 
1030 /// Create DOM element
1031 Handle_t Document::createElt(const XmlChar* tag_value) const {
1032 #ifdef DD4HEP_USE_TINYXML
1033   return _XE(new TiXmlElement(tag_value));
1034 #else
1035   return _XE(_D(m_doc)->createElement(tag_value));
1036 #endif
1037 }
1038 
1039 /// Access the ROOT eleemnt of the DOM document
1040 Handle_t Document::root() const {
1041   if (m_doc)
1042     return _XE(_D(m_doc)->getDocumentElement());
1043   throw std::runtime_error("Document::root: Invalid handle!");
1044 }
1045 
1046 /// Acces the document URI
1047 std::string Document::uri() const   {
1048   if (m_doc)   {
1049     Tag_t val(_D(m_doc)->getDocumentURI());
1050     return val;
1051   }
1052   throw std::runtime_error("Document::uri: Invalid handle!");
1053 }
1054 
1055 /// Assign new document. Old document is dropped.
1056 DocumentHolder& DocumentHolder::assign(DOC d)   {
1057   if (m_doc)   {
1058     printout(DEBUG,"DocumentHolder","+++ Release DOM document....");
1059 #ifdef DD4HEP_USE_TINYXML
1060     delete _D(m_doc);
1061 #else
1062     _D(m_doc)->release();
1063 #endif
1064   }
1065   m_doc = d;
1066   return *this;
1067 }
1068 
1069 /// Standard destructor - releases the document
1070 DocumentHolder::~DocumentHolder() {
1071   assign(0);
1072 }
1073 
1074 /// Constructor from DOM document entity
1075 Element::Element(const Document& doc, const XmlChar* type)
1076   : m_element(Xml(doc.createElt(type)).xe) {
1077 }
1078 
1079 /// Access the XmlElements parent
1080 Element::Elt_t Element::parentElement()  const   {
1081   Handle_t p = m_element.parent();
1082   if ( p && _N(p.ptr())->getNodeType() == ELEMENT_NODE_TYPE )  {
1083     return Elt_t(p);
1084   }
1085   return Elt_t(0);
1086 }
1087 
1088 /// Access the hosting document handle of this DOM element
1089 Document Element::document() const {
1090   return Document((XmlDocument*) (m_element ? _N(m_element)->getOwnerDocument() : 0));
1091 }
1092 
1093 /// Clone the DOM element tree
1094 Handle_t Element::clone(Handle_t h) const {
1095   if (m_element && h) {
1096     return h.clone(Document::DOC(document()));
1097   }
1098   throw std::runtime_error("Element::clone: Invalid element pointer -- unable to clone node!");
1099 }
1100 
1101 Attribute Element::getAttr(const XmlChar* name) const {
1102   return m_element ? attribute_node(m_element, name) : 0;
1103 }
1104 
1105 /// Set the reference attribute to the node (adds attribute ref="ref-name")
1106 Attribute Element::setRef(const XmlChar* tag_value, const XmlChar* ref_name) const {
1107   return setChild(tag_value).setAttr(Unicode_ref, ref_name);
1108 }
1109 
1110 /// Set the reference attribute to the node (adds attribute ref="ref-name")
1111 Attribute Element::setRef(const XmlChar* tag_value, const std::string& ref_name) const {
1112   return setRef(tag_value, Strng_t(ref_name).ptr());
1113 }
1114 
1115 /// Access the value of the reference attribute of the node (attribute ref="ref-name")
1116 const XmlChar* Element::getRef(const XmlChar* tag_value) const {
1117   return child(tag_value).attr < cpXmlChar > (Unicode_ref);
1118 }
1119 
1120 /// Add a new child to the DOM node
1121 Handle_t Element::addChild(const XmlChar* tag_value) const {
1122   Handle_t e = document().createElt(tag_value);
1123   m_element.append(e);
1124   return e;
1125 }
1126 
1127 /// Check if a child with the required tag exists - if not create it and add it to the current node
1128 Handle_t Element::setChild(const XmlChar* t) const {
1129   Elt_t e = m_element.child(t, false);
1130   return e ? Handle_t(e) : addChild(t);
1131 }
1132 
1133 #ifndef DD4HEP_USE_TINYXML
1134 /// Add comment node to the element
1135 void Element::addComment(const XmlChar* text_value) const {
1136   _N(m_element)->appendChild(_D(document().m_doc)->createComment(text_value));
1137 }
1138 #endif
1139 
1140 /// Add comment node to the element
1141 void Element::addComment(const char* text_value) const {
1142 #ifdef DD4HEP_USE_TINYXML
1143   _N(m_element)->appendChild(new TiXmlComment(text_value));
1144 #else
1145   _N(m_element)->appendChild(_D(document().m_doc)->createComment(Strng_t(text_value)));
1146 #endif
1147 }
1148 
1149 /// Add comment node to the element
1150 void Element::addComment(const std::string& text_value) const {
1151   addComment(text_value.c_str());
1152 }
1153 
1154 /// Initializing constructor to create a new XMLElement and add it to the document.
1155 RefElement::RefElement(const Document& doc, const XmlChar* typ, const XmlChar* nam)
1156   : Element(doc, typ) {
1157   m_name = nam ? setAttr(_U(name), nam) : 0;
1158 }
1159 
1160 /// Construction from existing object handle
1161 RefElement::RefElement(const Handle_t& e)
1162   : Element(e) {
1163   m_name = m_element ? getAttr(_U(name)) : 0;
1164 }
1165 
1166 /// Copy constructor
1167 RefElement::RefElement(const RefElement& e)
1168   : Element(e), m_name(e.m_name) {
1169 }
1170 
1171 /// Assignment operator
1172 RefElement& RefElement::operator=(const RefElement& e) {
1173   m_element = e.m_element;
1174   return *this;
1175 }
1176 
1177 const XmlChar* RefElement::name() const {
1178   if (0 == m_name)
1179     std::cout << "Error:tag=" << m_element.tag() << std::endl;
1180   return attribute_value(m_name);
1181 }
1182 
1183 const XmlChar* RefElement::refName() const {
1184   if (0 == m_name)
1185     std::cout << "Error:tag=" << m_element.tag() << std::endl;
1186   return attribute_value(m_name);
1187 }
1188 
1189 void RefElement::setName(const XmlChar* new_name) {
1190   setAttr(_U(name), new_name);
1191 }
1192 
1193 #ifndef DD4HEP_USE_TINYXML
1194 Collection_t::Collection_t(Handle_t element, const XmlChar* tag_value)
1195   : m_children(element, tag_value) {
1196   m_node = m_children.reset();
1197 }
1198 #endif
1199 
1200 Collection_t::Collection_t(Handle_t element, const char* tag_value)
1201   : m_children(element, Strng_t(tag_value)) {
1202   m_node = m_children.reset();
1203 }
1204 
1205 /// Constructor over XmlElements in a node list
1206 Collection_t::Collection_t(NodeList node_list)
1207   : m_children(node_list) {
1208   m_node = m_children.reset();
1209 }
1210 
1211 /// Reset the collection object to restart the iteration
1212 Collection_t& Collection_t::reset() {
1213   m_node = m_children.reset();
1214   return *this;
1215 }
1216 
1217 /// Access the collection size. Avoid this call -- sloooow!
1218 size_t Collection_t::size() const {
1219   return Handle_t(m_children.m_node).numChildren(m_children.m_tag, false);
1220 }
1221 
1222 /// Helper function to throw an exception
1223 void Collection_t::throw_loop_exception(const std::exception& e) const {
1224   if (m_node) {
1225     throw std::runtime_error(std::string(e.what()) + "\n" + "dd4hep: Error interpreting XML nodes of type <" + tag() + "/>");
1226   }
1227   throw std::runtime_error(std::string(e.what()) + "\n" + "dd4hep: Error interpreting collections XML nodes.");
1228 }
1229 
1230 void Collection_t::operator++() const {
1231   Elt_t e = this->parent();
1232   while (m_node) {
1233     m_node = m_children.next();
1234     if (m_node && _N(m_node)->getNodeType() == ELEMENT_NODE_TYPE) {
1235       if (this->parent() == e)
1236         return;
1237     }
1238   }
1239 }
1240 
1241 void Collection_t::operator--() const {
1242   Elt_t e = this->parent();
1243   while (m_node) {
1244     m_node = m_children.previous();
1245     if (m_node && _N(m_node)->getNodeType() == ELEMENT_NODE_TYPE) {
1246       if (this->parent() == e)
1247         return;
1248     }
1249   }
1250 }
1251 
1252 void Collection_t::operator++(int) const {
1253   ++(*this);
1254 }
1255 
1256 void Collection_t::operator--(int) const {
1257   --(*this);
1258 }
1259 
1260 Handle_t Document::clone(Handle_t source) const {
1261 #ifdef DD4HEP_USE_TINYXML
1262   return _XE(source.clone(0));
1263 #else
1264   return _XE(_D(m_doc)->importNode(_E(source.ptr()),true));
1265 #endif
1266 }
1267 
1268 #ifdef DD4HEP_USE_TINYXML
1269 //These files are located parallel to this one, we cannot use angle brackets for include
1270 #include "tinyxml_inl.h"
1271 #include "tinyxmlerror_inl.h"
1272 #include "tinyxmlparser_inl.h"
1273 #endif