Back to home page

EIC code displayed by LXR

 
 

    


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

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 XML_XMLELEMENTS_H
0014 #define XML_XMLELEMENTS_H
0015 
0016 // C/C++ include files
0017 #include <cmath>
0018 #include <string>
0019 #include <vector>
0020 #include <stdexcept>
0021 
0022 // Framework include files
0023 #include <XML/config.h>
0024 
0025 #ifndef RAD_2_DEGREE
0026 #define RAD_2_DEGREE 57.295779513082320876798154814105
0027 #endif
0028 #ifndef M_PI
0029 #define M_PI 3.14159265358979323846
0030 #endif
0031 
0032 /// Namespace for the AIDA detector description toolkit
0033 namespace dd4hep {
0034 
0035   /// Namespace for the AIDA detector description toolkit supporting XML utilities
0036   namespace xml {
0037 
0038     typedef const XmlAttr* Attribute;
0039 
0040     /// Definition of the XmlString class.
0041     /**
0042      *  Definition of the XmlString class.
0043      *  Unly used to have the same code base as for XercesC,
0044      *  where this class does the unicode translations and
0045      *  en/decoding.
0046      *
0047      *  \author   M.Frank
0048      *  \version  1.0
0049      *  \ingroup DD4HEP_XML
0050      */
0051     class XmlString {
0052     public:
0053       /// Replicate string: internally allocates new string, which must be free'ed with release
0054       static XmlChar* replicate(const XmlChar* c);
0055       /// Transcode string
0056       static XmlChar* transcode(const char* c);
0057       /// Release string
0058       static void release(char** p);
0059       /// String length in native representation
0060       static size_t length(const char* s);
0061 #ifndef __TIXML__
0062       /// String length in native representation
0063       static size_t length(const XmlChar* s);
0064       /// Transcoded string from unicode to ascii
0065       static char* transcode(const XmlChar* c);
0066       /// Release string
0067       static void release(XmlChar** p);
0068 #endif
0069     };
0070 
0071 #ifdef __TIXML__
0072     /// Definition of the XmlException class.
0073     /**
0074      *  Currently no real use. Present to make Xerces happy,
0075      *  which has such a class.
0076      *
0077      *  \author   M.Frank
0078      *  \version  1.0
0079      *  \ingroup DD4HEP_XML
0080      */
0081     class XmlException {
0082     public:
0083       std::string msg;
0084       XmlException() : msg() {}
0085       XmlException(const std::string& m) : msg(m) {}
0086       XmlException(const XmlException& e) : msg(e.msg) {}
0087       virtual ~XmlException() {}
0088       XmlException& operator=(const XmlException& c) {
0089         if ( &c != this ) msg = c.msg;
0090         return *this;
0091       }
0092     };
0093 #endif
0094 
0095     typedef const std::string& CSTR;
0096 
0097     /// Dump DOM tree of a document
0098     void dumpTree(XmlDocument* doc);
0099 
0100     /// Change floating point precision on conversion to string
0101     int set_float_precision(int precision);
0102     /// Access floating point precision on conversion to string
0103     int get_float_precision();
0104 
0105     /// Convert xml attribute to STL string  \ingroup DD4HEP_XML
0106     std::string _toString(const Attribute attr);
0107     /// Convert xml string to STL string  \ingroup DD4HEP_XML
0108     std::string _toString(const XmlChar *toTranscode);
0109     /// Do-nothing version. Present for completeness and argument interchangeability  \ingroup DD4HEP_XML
0110     std::string _toString(const char* s);
0111     /// Do-nothing version. Present for completeness and argument interchangeability  \ingroup DD4HEP_XML
0112     std::string _toString(const std::string& s);
0113     /// Format unsigned long integer to string with arbitrary format  \ingroup DD4HEP_XML
0114     std::string _toString(unsigned long i, const char* fmt = "%lu");
0115     /// Format unsigned integer (32 bits) to string with arbitrary format  \ingroup DD4HEP_XML
0116     std::string _toString(unsigned int i, const char* fmt = "%u");
0117     /// Format signed integer (32 bits) to string with arbitrary format  \ingroup DD4HEP_XML
0118     std::string _toString(int i, const char* fmt = "%d");
0119     /// Format signed long integer to string with arbitrary format  \ingroup DD4HEP_XML
0120     std::string _toString(long i, const char* fmt = "%ld");
0121     /// Format single procision float number (32 bits) to string with arbitrary format  \ingroup DD4HEP_XML
0122     std::string _toString(float d, const char* fmt = "%.17e");
0123     /// Format double procision float number (64 bits) to string with arbitrary format  \ingroup DD4HEP_XML
0124     std::string _toString(double d, const char* fmt = "%.17e");
0125     /// Format void pointer (64 bits) to string with arbitrary format  \ingroup DD4HEP_XML
0126     std::string _ptrToString(const void* p, const char* fmt = "%p");
0127     /// Format void pointer (64 bits) to string with arbitrary format  \ingroup DD4HEP_XML
0128     template <typename T> std::string _toString(const T* p, const char* fmt = "%p")
0129     {      return _ptrToString((void*)p,fmt);       }
0130 
0131     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0132     void _toDictionary(const XmlChar* name, const XmlChar* value);
0133     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0134     template <typename T> void _toDictionary(const XmlChar* name, T value);
0135 
0136     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0137     void _toDictionary(const XmlChar* name, float  value);
0138     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0139     void _toDictionary(const XmlChar* name, double value);
0140 
0141     /// Conversion function from raw unicode string to bool  \ingroup DD4HEP_XML
0142     bool _toBool(const XmlChar* value);
0143     /// Conversion function from raw unicode string to int  \ingroup DD4HEP_XML
0144     int _toInt(const XmlChar* value);
0145     /// Conversion function from raw unicode string to unsigned int  \ingroup DD4HEP_XML
0146     unsigned int _toUInt(const XmlChar* value);
0147     /// Conversion function from raw unicode string to long  \ingroup DD4HEP_XML
0148     long _toLong(const XmlChar* value);
0149     /// Conversion function from raw unicode string to unsigned long  \ingroup DD4HEP_XML
0150     unsigned long _toULong(const XmlChar* value);
0151     /// Conversion function from raw unicode string to float  \ingroup DD4HEP_XML
0152     float _toFloat(const XmlChar* value);
0153     /// Conversion function from raw unicode string to double  \ingroup DD4HEP_XML
0154     double _toDouble(const XmlChar* value);
0155 
0156     /// Helper function to lookup environment from the expression evaluator
0157     std::string getEnviron(const std::string& env);
0158     /// Enable/disable environment resolution when parsing strings
0159     bool enableEnvironResolution(bool new_value);
0160     
0161     /// Helper class to encapsulate a unicode string.
0162     /**
0163      *  Simple conversion from ascii strings to unicode strings.
0164      *  Useful when using XercesC - dummy implementation for TiXml.
0165      *
0166      *  \author  M.Frank
0167      *  \version 1.0
0168      *  \ingroup DD4HEP_XML
0169      */
0170     class Strng_t {
0171     public:
0172       /// Pointer to unicode string
0173       XmlChar* m_xml;
0174 #ifndef __TIXML__
0175       /// Initializing constructor from unicode string
0176       Strng_t(const XmlChar* c) {
0177         m_xml = XmlString::replicate(c);
0178       }
0179       /// Assignment opertor from unicode string
0180       Strng_t& operator=(const XmlChar* s);
0181 #endif
0182       /// Initializing constructor from ascii string
0183       Strng_t(const char* c) {
0184         m_xml = XmlString::transcode(c);
0185       }
0186       /// Initializing constructor from STL string
0187       Strng_t(const std::string& c) {
0188         m_xml = XmlString::transcode(c.c_str());
0189       }
0190       /// Copy constructor
0191       Strng_t(const Strng_t& c) {
0192         m_xml = XmlString::replicate(c.m_xml);
0193       }
0194       /// Default destructor - release unicode string
0195       ~Strng_t() {
0196         if (m_xml)
0197           XmlString::release(&m_xml);
0198       }
0199       /// Auto-conversion to unicode string
0200       operator const XmlChar*() const {
0201         return m_xml;
0202       }
0203       /// Accessor to unicode string
0204       const XmlChar* ptr() const {
0205         return m_xml;
0206       }
0207       /// String length in native representation
0208       size_t length()  const  {
0209         return XmlString::length(m_xml);
0210       }
0211       /// Assignment opertor from ascii string
0212       Strng_t& operator=(const char* s);
0213       /// Assignment opertor from helper string
0214       Strng_t& operator=(const Strng_t& s);
0215       /// Assignment opertor from STL string
0216       Strng_t& operator=(const std::string& s);
0217     };
0218 
0219     /// Unicode string concatenation of a normal ASCII string from right side  \ingroup DD4HEP_XML
0220     Strng_t operator+(const Strng_t& a, const char* b);
0221     /// Unicode string concatenation of a encapsulated and an STL string from right side  \ingroup DD4HEP_XML
0222     Strng_t operator+(const Strng_t& a, const std::string& b);
0223     /// Unicode string concatenation of a encapsulated and an encapsulated string from right side  \ingroup DD4HEP_XML
0224     Strng_t operator+(const Strng_t& a, const Strng_t& b);
0225     /// Unicode string concatenation of a normal ASCII string from left side  \ingroup DD4HEP_XML
0226     Strng_t operator+(const char* a, const Strng_t& b);
0227     /// Unicode string concatenation of a STL string and an encapsulated string from the left.  \ingroup DD4HEP_XML
0228     Strng_t operator+(const std::string& a, const Strng_t& b);
0229 
0230 #ifndef __TIXML__
0231     /// Unicode string concatenation of a encapsulated and raw unicode string from right side  \ingroup DD4HEP_XML
0232     Strng_t operator+(const Strng_t& a, const XmlChar* b);
0233     /// Unicode string concatenation of a encapsulated and raw unicode string from left side  \ingroup DD4HEP_XML
0234     Strng_t operator+(const XmlChar* a, const Strng_t& b);
0235     /// Unicode string concatenation of a raw unicode and an STL string from the right  \ingroup DD4HEP_XML
0236     Strng_t operator+(const XmlChar* a, const std::string& b);
0237     /// Unicode string concatenation of a raw unicode and an STL string from the left  \ingroup DD4HEP_XML
0238     Strng_t operator+(const std::string& a, const XmlChar* b);
0239 
0240 #endif
0241 
0242     /// Class to support both way translation between C++ and XML strings
0243     /**
0244      *  Helper class to easily convert between
0245      *  -- unicode
0246      *  -- std::string
0247      *  -- const char*.
0248      *  Internaly a copy representation as an std::string is kept.
0249      *
0250      *  \author  M.Frank
0251      *  \version 1.0
0252      *  \ingroup DD4HEP_XML
0253      */
0254     class Tag_t : public Strng_t {
0255     public:
0256       /// STL string buffer
0257       std::string m_str;
0258 #ifndef __TIXML__
0259       /// Constructor from normal ASCII string
0260       Tag_t(const char* s)
0261         : Strng_t(s), m_str(s) {
0262       }
0263 #endif
0264       /// Constructor from unicode string
0265       Tag_t(const XmlChar* s)
0266         : Strng_t(s), m_str(_toString(s)) {
0267       }
0268       /// Constructor from internal XML string
0269       Tag_t(const Strng_t& s)
0270         : Strng_t(s), m_str(_toString(s)) {
0271       }
0272       /// Constructor from STL string
0273       Tag_t(const std::string& s)
0274         : Strng_t(s), m_str(s) {
0275       }
0276       /// Constructor from STL string with registration.
0277       /// ONLY to be used for static global entries to protect against duplicated static memory.
0278       Tag_t(const std::string& v, const std::string& s, void (*register_func)(const std::string&, Tag_t*))
0279         : Strng_t(s), m_str(s) {
0280         register_func(v, this);
0281       }
0282       /// Copy constructor
0283       Tag_t(const Tag_t& c)
0284         : Strng_t(c), m_str(c.m_str) {
0285       }
0286       /// Destructor
0287       ~Tag_t() {
0288       }
0289 
0290       /// Assignment of a normal ASCII string
0291       Tag_t& operator=(const char* s);
0292       /// Assignment of a tag object
0293       Tag_t& operator=(const Tag_t& s);
0294       /// Assignment of a internal Xml string
0295       Tag_t& operator=(const Strng_t& s);
0296       /// Assignment of a STL string
0297       Tag_t& operator=(const std::string& s);
0298 
0299       /// Automatic conversion to STL string
0300       operator const std::string&() const {
0301         return m_str;
0302       }
0303       /// Access writable STL string
0304       const std::string& str() const {
0305         return m_str;
0306       }
0307       /// Access data buffer of STL string
0308       const char* c_str() const {
0309         return m_str.c_str();
0310       }
0311     };
0312 
0313     /// Tag/string concatenation with a normal ASCII string from right side  \ingroup DD4HEP_XML
0314     Tag_t operator+(const Tag_t& a, const char* b);
0315     /// Tag/string concatenation with a normal ASCII string from left side  \ingroup DD4HEP_XML
0316     Tag_t operator+(const char* a, const Tag_t& b);
0317     /// Tag/string concatenation with a unicode string from right side  \ingroup DD4HEP_XML
0318     Tag_t operator+(const Tag_t& a, const XmlChar* b);
0319     /// Tag/string concatenation with a internal Xml string from right side  \ingroup DD4HEP_XML
0320     Tag_t operator+(const Tag_t& a, const Strng_t& b);
0321     /// Tag/string concatenation with a STL string from right side  \ingroup DD4HEP_XML
0322     Tag_t operator+(const Tag_t& a, const std::string& b);
0323     /// Equality operator between tag object and STL string  \ingroup DD4HEP_XML
0324     inline bool operator==(const std::string& c, const Tag_t& b) {
0325       return c == b.m_str;
0326     }
0327 
0328     /// Convert Strng_t to std::string
0329     std::string _toString(const Strng_t& s);
0330     /// Convert Tag_t to std::string
0331     std::string _toString(const Tag_t& s);
0332     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0333     void _toDictionary(const XmlChar* name, const Strng_t& s);
0334     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0335     void _toDictionary(const XmlChar* name, const Tag_t& t);
0336 
0337     /// Class describing a list of XML nodes
0338     /**
0339      *  Definition of a "list" of xml elements hanging of the parent.
0340      *  The list allows iterations, which can be restarted.
0341      *  Please not: Copies are not entirely free, since the
0342      *  string tag need to be replicated using strdup/free
0343      *  (or when using xerces the corresponding unicode routines).
0344      *
0345      *  \author   M.Frank
0346      *  \version  1.0
0347      *  \ingroup DD4HEP_XML
0348      */
0349     class NodeList {
0350     public:
0351       Tag_t m_tag;
0352       XmlElement* m_node;
0353       mutable XmlElement* m_ptr;
0354 
0355       /// Copy constructor
0356       NodeList(const NodeList& l);
0357       /// Initializing constructor
0358       NodeList(XmlElement* frst, const XmlChar* t);
0359       /// Default destructor
0360       ~NodeList();
0361       /// Reset the nodelist - e.g. restart iteration from beginning
0362       XmlElement* reset();
0363       /// Advance to next element
0364       XmlElement* next() const;
0365       /// Go back to previous element
0366       XmlElement* previous() const;
0367       /// Assignment operator
0368       NodeList& operator=(const NodeList& l);
0369     };
0370 
0371     /// Class to easily access the properties of single XmlElements.
0372     /**
0373      *  Note: The assignmant operator as well as the copy constructor
0374      *  do not have to be implemented, they are aut-generated by the compiler!
0375      *
0376      *  \author  M.Frank
0377      *  \version 1.0
0378      *  \ingroup DD4HEP_XML
0379      */
0380     class Handle_t {
0381     public:
0382       // Abbreviation for internal use
0383       typedef XmlElement* Elt_t;
0384 
0385       /// The pointer to the XmlElement
0386       mutable Elt_t m_node;
0387 
0388       /// Initializing constructor
0389       Handle_t(Elt_t e = 0)
0390         : m_node(e) {
0391       }
0392       /// Direct access to the XmlElement using the operator->
0393       Elt_t operator->() const {
0394         return m_node;
0395       }
0396       /// Direct access to the XmlElement by dereferencing
0397       operator Elt_t() const {
0398         return m_node;
0399       }
0400       /// Direct access to the XmlElement by function
0401       Elt_t ptr() const {
0402         return m_node;
0403       }
0404       /// Clone the DOMelement - with the option of a deep copy
0405       Handle_t clone(XmlDocument* new_doc) const;
0406 
0407       /// Unicode text access to the element's tag. Tis must be wrong ....
0408       const XmlChar* rawTag() const;
0409       /// Unicode text access to the element's text
0410       const XmlChar* rawText() const;
0411       /// Unicode text access to the element's value
0412       const XmlChar* rawValue() const;
0413       /// Text access to the element's tag
0414       std::string tag() const {
0415         return _toString(rawTag());
0416       }
0417       /// Text access to the element's text
0418       std::string text() const {
0419         return _toString(rawText());
0420       }
0421       /// Text access to the element's value
0422       std::string value() const {
0423         return _toString(rawValue());
0424       }
0425       /// Set the element's value
0426       void setValue(const XmlChar* text) const;
0427       /// Set the element's value
0428       void setValue(const std::string& text) const;
0429       /// Set the element's text
0430       void setText(const XmlChar* text) const;
0431       /// Set the element's text
0432       void setText(const std::string& text) const;
0433 
0434       /*** DOM Attribute handling
0435        */
0436       /// Access attribute name (throws exception if not present)
0437       const XmlChar* attr_name(const Attribute attr) const;
0438       /// Access attribute value by the attribute  (throws exception if not present)
0439       const XmlChar* attr_value(const Attribute attr) const;
0440       /// Access attribute value by the attribute's unicode name (throws exception if not present)
0441       const XmlChar* attr_value(const XmlChar* attr) const;
0442       /// Access attribute value by the attribute's unicode name (no exception thrown if not present)
0443       const XmlChar* attr_value_nothrow(const XmlChar* attr) const;
0444 
0445       /// Access attribute pointer by the attribute's unicode name (throws exception if not present)
0446       Attribute attr_ptr(const XmlChar* attr) const;
0447       /// Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
0448       Attribute attr_nothrow(const XmlChar* tag) const;
0449       /// Check for the existence of a named attribute
0450       bool hasAttr(const XmlChar* t) const;
0451       /// Retrieve a collection of all attributes of this DOM element
0452       std::vector<Attribute> attributes() const;
0453       /// Access typed attribute value by the XmlAttr
0454       template <class T> T attr(const Attribute a) const {
0455         return this->attr<T>(this->attr_name(a));
0456       }
0457       /// Remove all attributes of this element
0458       void removeAttrs() const;
0459       /// Set attributes as in argument handle
0460       void setAttrs(Handle_t e) const;
0461       /// Access typed attribute value by its unicode name
0462       template <class T> T attr(const XmlChar* name) const;
0463       /// Access typed attribute value by its unicode name. If not existing returns default value
0464       template <class T> T attr(const XmlChar* name, T default_value) const;
0465 
0466       /// Generic attribute setter with unicode value
0467       Attribute setAttr(const XmlChar* t, const XmlChar* v) const;
0468       /// Generic attribute setter with XmlAttr value
0469       Attribute setAttr(const XmlChar* t, const Attribute v) const;
0470       /// Generic attribute setter with integer value
0471       Attribute setAttr(const XmlChar* t, int val) const;
0472       /// Generic attribute setter with boolen value
0473       Attribute setAttr(const XmlChar* t, bool val) const;
0474       /// Generic attribute setter with floating point value
0475       Attribute setAttr(const XmlChar* t, float val) const;
0476       /// Generic attribute setter with double precision floating point value
0477       Attribute setAttr(const XmlChar* t, double val) const;
0478       /// Generic attribute setter with string value
0479       Attribute setAttr(const XmlChar* t, const std::string& val) const;
0480 #ifndef __TIXML__
0481       /// Check for the existence of a named attribute
0482       bool hasAttr(const char* t) const {
0483         return hasAttr(Strng_t(t));
0484       }
0485       /// Access typed attribute value by its name
0486       template <class T> T attr(const char* name) const {
0487         return this->attr<T>(Strng_t(name));
0488       }
0489       /// Access typed attribute value by its name
0490       template <class T> T attr(const char* name, const T& default_value) const {
0491         Strng_t tag(name);
0492         return this->hasAttr(tag) ? this->attr<T>(tag) : default_value;
0493       }
0494       /// Generic attribute setter with text value
0495       Attribute setAttr(const XmlChar* t, const char* v) const;
0496 #endif
0497 
0498       /// Add reference child as a new child node. The obj must have the "name" attribute!
0499       Handle_t setRef(const XmlChar* tag, const XmlChar* ref);
0500       /// Add reference child as a new child node. The obj must have the "name" attribute!
0501       Handle_t setRef(const XmlChar* tag, const std::string& ref);
0502 
0503       /*** DOM Element child handling
0504        */
0505       /// Check the existence of a child with a given tag name
0506       bool hasChild(const XmlChar* tag) const;
0507       /// Access a single child by its tag name (unicode)
0508       Handle_t child(const XmlChar* tag, bool throw_exception = true) const;
0509       /// Access a group of children identified by the same tag name
0510       NodeList children(const XmlChar* tag) const;
0511       /// Access the number of children of this DOM element with a given tag name
0512       size_t numChildren(const XmlChar* tag, bool throw_exception) const;
0513       /// Remove a single child node identified by its handle from the tree of the element
0514       Handle_t remove(Handle_t e) const;
0515       /// Remove children with a given tag name from the DOM node
0516       void removeChildren(const XmlChar* tag) const;
0517       /// Append a DOM element to the current node
0518       void append(Handle_t e) const;
0519       /// Access the element's parent element
0520       Handle_t parent() const;
0521       /// Checksum (sub-)tree of a xml document/tree. Default will pick up the adler32 checksum.
0522       unsigned int checksum(unsigned int param, unsigned int (fcn)(unsigned int param, const XmlChar*, size_t)=0) const;
0523     };
0524 
0525 #define INLINE inline
0526     typedef const XmlChar* cpXmlChar;
0527 
0528     template <> INLINE Attribute Handle_t::attr<Attribute>(const XmlChar* tag_value) const {
0529       return attr_ptr(tag_value);
0530     }
0531 
0532     template <> INLINE cpXmlChar Handle_t::attr<cpXmlChar>(const XmlChar* tag_value) const {
0533       return attr_value(tag_value);
0534     }
0535 
0536     template <> INLINE bool Handle_t::attr<bool>(const XmlChar* tag_value) const {
0537       return _toBool(attr_value(tag_value));
0538     }
0539 
0540     template <> INLINE int Handle_t::attr<int>(const XmlChar* tag_value) const {
0541       return _toInt(attr_value(tag_value));
0542     }
0543     
0544     template <> INLINE unsigned int Handle_t::attr<unsigned int>(const XmlChar* tag_value) const {
0545       return _toUInt(attr_value(tag_value));
0546     }
0547     
0548     template <> INLINE long Handle_t::attr<long>(const XmlChar* tag_value) const {
0549       return _toLong(attr_value(tag_value));
0550     }
0551 
0552     template <> INLINE unsigned long Handle_t::attr<unsigned long>(const XmlChar* tag_value) const {
0553       return _toULong(attr_value(tag_value));
0554     }
0555 
0556     template <> INLINE float Handle_t::attr<float>(const XmlChar* tag_value) const {
0557       return _toFloat(attr_value(tag_value));
0558     }
0559 
0560     template <> INLINE double Handle_t::attr<double>(const XmlChar* tag_value) const {
0561       return _toDouble(attr_value(tag_value));
0562     }
0563 
0564     template <> INLINE std::string Handle_t::attr<std::string>(const XmlChar* tag_value) const {
0565       return _toString(attr_value(tag_value));
0566     }
0567 
0568     template <> INLINE Attribute Handle_t::attr<Attribute>(const XmlChar* tag_value, Attribute default_value) const {
0569       Attribute a = attr_nothrow(tag_value);
0570       return a ? a : std::move(default_value);
0571     }
0572 
0573     template <> INLINE bool Handle_t::attr<bool>(const XmlChar* tag_value, bool default_value) const {
0574       Attribute a = attr_nothrow(tag_value);
0575       return a ? _toBool(attr_value(a)) : default_value;
0576     }
0577 
0578     template <> INLINE int Handle_t::attr<int>(const XmlChar* tag_value, int default_value) const {
0579       Attribute a = attr_nothrow(tag_value);
0580       return a ? _toInt(attr_value(a)) : default_value;
0581     }
0582     
0583     template <> INLINE unsigned int Handle_t::attr<unsigned int>(const XmlChar* tag_value, unsigned int default_value) const {
0584       Attribute a = attr_nothrow(tag_value);
0585       return a ? _toUInt(attr_value(a)) : default_value;
0586     }
0587     
0588     template <> INLINE long Handle_t::attr<long>(const XmlChar* tag_value, long default_value) const {
0589       Attribute a = attr_nothrow(tag_value);
0590       return a ? _toLong(attr_value(a)) : default_value;
0591     }
0592 
0593     template <> INLINE unsigned long Handle_t::attr<unsigned long>(const XmlChar* tag_value, unsigned long default_value) const {
0594       Attribute a = attr_nothrow(tag_value);
0595       return a ? _toULong(attr_value(a)) : default_value;
0596     }
0597 
0598     template <> INLINE float Handle_t::attr<float>(const XmlChar* tag_value, float default_value) const {
0599       Attribute a = attr_nothrow(tag_value);
0600       return a ? _toFloat(attr_value(a)) : default_value;
0601     }
0602 
0603     template <> INLINE double Handle_t::attr<double>(const XmlChar* tag_value, double default_value) const {
0604       Attribute a = attr_nothrow(tag_value);
0605       return a ? _toDouble(attr_value(a)) : default_value;
0606     }
0607 
0608     template <> INLINE std::string Handle_t::attr<std::string>(const XmlChar* tag_value, std::string default_value) const {
0609       Attribute a = attr_nothrow(tag_value);
0610       return a ? _toString(attr_value(a)) : std::move(default_value);
0611     }
0612 
0613 #if 0
0614     template<> INLINE bool Handle_t::attr<bool>(const Attribute tag_value) const
0615     { return _toBool(attr_value(tag_value));}
0616 
0617     template<> INLINE int Handle_t::attr<int>(const Attribute tag_value) const
0618     { return _toInt(attr_value(tag_value));}
0619 
0620     template<> INLINE float Handle_t::attr<float>(const Attribute tag_value) const
0621     { return _toFloat(attr_value(tag_value));}
0622 
0623     template<> INLINE double Handle_t::attr<double>(const Attribute tag_value) const
0624     { return _toDouble(attr_value(tag_value));}
0625 
0626     template<> INLINE std::string Handle_t::attr<std::string>(const Attribute tag_value) const
0627     { return _toString(attr_value(tag_value));}
0628 #endif
0629 
0630     /// Class to support the access to collections of XmlNodes (or XmlElements)
0631     /**
0632      *  \author  M.Frank
0633      *  \version 1.0
0634      *  \ingroup DD4HEP_XML
0635      */
0636     class Collection_t : public Handle_t {
0637     public:
0638       /// Reference to the list of child nodes
0639       NodeList m_children;
0640 #ifndef __TIXML__
0641       /// Constructor over XmlElements with a given tag name
0642       Collection_t(Handle_t node, const XmlChar* tag);
0643 #endif
0644       /// Constructor over XmlElements with a given tag name
0645       Collection_t(Handle_t node, const char* tag);
0646       /// Constructor over XmlElements in a node list
0647       Collection_t(NodeList children);
0648       /// Reset the collection object to restart the iteration
0649       Collection_t& reset();
0650       /// Access the collection size. Avoid this call -- sloooow!
0651       size_t size() const;
0652       /// Operator to advance the collection (pre increment)
0653       void operator++() const;
0654       /// Operator to advance the collection (post increment)
0655       void operator++(int) const;
0656       /// Operator to advance the collection (pre decrement)
0657       void operator--() const;
0658       /// Operator to advance the collection (post decrement)
0659       void operator--(int) const;
0660       /// Access to current element
0661       Elt_t current() const {
0662         return m_node;
0663       }
0664       /// Helper function to throw an exception
0665       void throw_loop_exception(const std::exception& e) const;
0666       /// Loop processor using function object
0667       template <class T> void for_each(T oper) const {
0668         try {
0669           for (const Collection_t& c = *this; c; ++c)
0670             oper(*this);
0671         }
0672         catch (const std::exception& e) {
0673           throw_loop_exception(e);
0674         }
0675       }
0676       /// Loop processor using function object
0677       template <class T> void for_each(const XmlChar* tag_name, T oper) const {
0678         try {
0679           for (const Collection_t& c = *this; c; ++c)
0680             Collection_t(c.m_node, tag_name).for_each(oper);
0681         }
0682         catch (const std::exception& e) {
0683           throw_loop_exception(e);
0684         }
0685       }
0686     };
0687 
0688     /// Class supporting the basic functionality of an XML document
0689     /**
0690      *  User class encapsulating a DOM document.
0691      *  Nothing special - normal handle around pointer.
0692      *
0693      *  \author  M.Frank
0694      *  \version 1.0
0695      *  \ingroup DD4HEP_XML
0696      */
0697     class Document {
0698     public:
0699       typedef XmlDocument* DOC;
0700       DOC m_doc;
0701 
0702       /// Default Constructor
0703       Document() : m_doc(0) {}
0704       /// Initializing Constructor
0705       Document(DOC d) : m_doc(d) {}
0706       /// Copy constructor
0707       Document(const Document& d) = default;
0708       /// Assignment
0709       Document& operator=(const Document& d) = default;
0710       /// Destructor
0711       ~Document() = default;
0712       /// Auto-conversion to DOM document
0713       operator DOC() const       {        return m_doc;      }
0714       /// Accessot to DOM document behaviour using arrow operator
0715       DOC operator->() const     {        return m_doc;      }
0716       /// Accessot to DOM document behaviour
0717       DOC ptr() const            {        return m_doc;      }
0718 
0719       /// Access the ROOT eleemnt of the DOM document
0720       Handle_t root() const;
0721       /// Create DOM element
0722       Handle_t createElt(const XmlChar* tag) const;
0723       /// Clone a DOM element / sub-tree
0724       Handle_t clone(Handle_t source) const;
0725       /// Acces the document URI
0726       std::string uri() const;
0727     };
0728 
0729     /// Class supporting the basic functionality of an XML document including ownership
0730     /**
0731      *  User class encapsulating a DOM document.
0732      *  Nothing special - normal handle around pointer.
0733      *  Contrary to the Document class, on destruction the
0734      *  XML document shall be destroyed and the corresponding
0735      *  resources released.
0736      *
0737      *  \author  M.Frank
0738      *  \version 1.0
0739      *  \ingroup DD4HEP_XML
0740      */
0741     class DocumentHolder : public Document {
0742     public:
0743       /// Default Constructor
0744       DocumentHolder() = default;
0745       /// Default Constructor
0746       DocumentHolder(const DocumentHolder& copy) = delete;
0747       /// Constructor
0748       DocumentHolder(DOC d) : Document(d) { }
0749       /// Assignment operator
0750       DocumentHolder& operator=(const DocumentHolder& copy) = delete;
0751       /// Assign new document. Old document is dropped.
0752       DocumentHolder& assign(DOC d);
0753       /// Standard destructor - releases the document
0754       virtual ~DocumentHolder();
0755     };
0756 
0757     /// User abstraction class to manipulate XML elements within a document
0758     /**
0759      *  User class encapsulating a DOM element
0760      *  using the Handle_t helper.
0761      *  This is the main class we interact with when
0762      *  analysing the xml documents for constructing
0763      *  sub-detectors etc.
0764      *
0765      *  \author  M.Frank
0766      *  \version 1.0
0767      *  \ingroup DD4HEP_XML
0768      */
0769     class Element {
0770     public:
0771       /// Simplification type declarations
0772       typedef Handle_t::Elt_t Elt_t;
0773 
0774       /// The underlying object holding the XmlElement pointer
0775       Handle_t m_element;
0776 
0777       /// Constructor from XmlElement handle
0778       Element(const Handle_t& e) : m_element(e)          {      }
0779       /// Constructor from XmlElement handle
0780       Element(const Element& e) : m_element(e.m_element) {      }
0781       /// Constructor from DOM document entity
0782       Element(const Document& document, const XmlChar* type);
0783       /// Access the hosting document handle of this DOM element
0784       Document document() const;
0785 
0786       /// operator bool: check handle validity
0787       operator bool() const {
0788         return 0 != m_element.ptr();
0789       }
0790       /// operator NOT: check handle validity
0791       bool operator!() const {
0792         return 0 == m_element.ptr();
0793       }
0794       /// Assignment operator
0795       Element& operator=(const Element& c)  {
0796         m_element = c.m_element;
0797         return *this;
0798       }
0799       /// Assignment operator
0800       Element& operator=(Handle_t handle)  {
0801         m_element = handle;
0802         return *this;
0803       }
0804       /// Automatic conversion to DOM element handle
0805       operator Handle_t() const {
0806         return m_element;
0807       }
0808       /// Automatic conversion to XmlElement pointer
0809       operator Elt_t() const {
0810         return m_element;
0811       }
0812       /// Access to XmlElement pointer
0813       Elt_t ptr() const {
0814         return m_element;
0815       }
0816       /// Access the XmlElements parent
0817       Handle_t parent()  const   {
0818         return m_element.parent();
0819       }
0820       /// Access the XmlElements parent
0821       Elt_t parentElement()  const;
0822       /// Access the tag name of this DOM element
0823       std::string tag() const {
0824         return m_element.tag();
0825       }
0826       /// Access the tag name of this DOM element
0827       const XmlChar* tagName() const {
0828         return m_element.rawTag();
0829       }
0830       /// Access the tag name of this DOM element
0831       std::string text() const {
0832         return m_element.text();
0833       }
0834       /// Set text attribute to the XML node
0835       void text(const std::string value) const {
0836         return m_element.setText(value);
0837       }
0838       /// Append a new element to the existing tree
0839       void append(Handle_t handle) const {
0840         m_element.append(handle);
0841       }
0842       /// Clone the DOMelement
0843       Handle_t clone(const Document& new_doc) const {
0844         return new_doc.clone(m_element);
0845       }
0846       /// Check for the existence of a named attribute
0847       bool hasAttr(const XmlChar* name) const {
0848         return m_element.hasAttr(name);
0849       }
0850       /// Access attribute with implicit return type conversion
0851       template <class T> T attr(const XmlAttr* att) const {
0852         return m_element.attr<T>(att);
0853       }
0854       /// Access attribute with implicit return type conversion
0855       template <class T> T attr(const XmlChar* tag_value) const {
0856         return m_element.attr<T>(tag_value);
0857       }
0858       /// Access attribute with implicit return type conversion
0859       template <class T> T attr(const XmlChar* tag_value, T default_value) const {
0860         return m_element.attr<T>(tag_value, default_value);
0861       }
0862 #ifndef __TIXML__
0863       /// Access typed attribute value by its name
0864       template <class T> T attr(const char* name) const {
0865         return this->attr<T>(Strng_t(name));
0866       }
0867       /// Access typed attribute value by its name
0868       template <class T> T attr(const char* name, T default_value) const {
0869         return this->attr<T>(Strng_t(name), default_value);
0870       }
0871 #endif
0872       /// Access attribute name (throws exception if not present)
0873       const XmlChar* attr_name(const Attribute a) const {
0874         return m_element.attr_name(a);
0875       }
0876       /// Access attribute value by the attribute  (throws exception if not present)
0877       const XmlChar* attr_value(const Attribute a) const {
0878         return m_element.attr_value(a);
0879       }
0880       /// Access the number of children of this DOM element with a given tag name
0881       size_t numChildren(const XmlChar* tag_value, bool exc = true) const {
0882         return m_element.numChildren(tag_value, exc);
0883       }
0884       /// Remove own attributes and copy all attributes from handle 'e'
0885       void setAttrs(Handle_t e) const {
0886         return m_element.setAttrs(e);
0887       }
0888       /// Remove all attributes of this element
0889       void removeAttrs() const {
0890         m_element.removeAttrs();
0891       }
0892       /// Retrieve a collection of all attributes of this DOM element
0893       std::vector<Attribute> attributes() const {
0894         return m_element.attributes();
0895       }
0896       /// Access single attribute by its name
0897       Attribute getAttr(const XmlChar* name) const;
0898       /// Set single attribute
0899       template <class T>
0900       Attribute setAttr(const XmlChar* nam, const T& val) const {
0901         return m_element.setAttr(nam, val);
0902       }
0903       /// Set element value
0904       template <class T> void setValue(const T& val) const {
0905         m_element.setValue(val);
0906       }
0907       /// Clone the DOM element tree
0908       Handle_t clone(Handle_t h) const;
0909       /// Add a new child to the DOM node
0910       Handle_t addChild(const XmlChar* tag) const;
0911       /// Check if a child with the required tag exists - if not create it and add it to the current node
0912       Handle_t setChild(const XmlChar* tag) const;
0913       /// Access child by tag name. Thow an exception if required in case the child is not present
0914       Handle_t child(const Strng_t& tag_value, bool except = true) const {
0915         return m_element.child(tag_value, except);
0916       }
0917       /// Remove a child node identified by its handle
0918       Handle_t remove(Handle_t node) const {
0919         return m_element.remove(node);
0920       }
0921       /// Check the existence of a child with a given tag name
0922       bool hasChild(const XmlChar* tag_value) const {
0923         return m_element.hasChild(tag_value);
0924       }
0925       /// Set the reference attribute to the node (adds attribute ref="ref-name")
0926       Attribute setRef(const XmlChar* tag, const XmlChar* refname) const;
0927       /// Set the reference attribute to the node (adds attribute ref="ref-name")
0928       Attribute setRef(const XmlChar* tag, const std::string& refname) const;
0929       /// Access the value of the reference attribute of the node (attribute ref="ref-name")
0930       const XmlChar* getRef(const XmlChar* tag) const;
0931 #ifndef __TIXML__
0932       /// Add comment node to the element
0933       void addComment(const XmlChar* text) const;
0934 #endif
0935       /// Add comment node to the element
0936       void addComment(const char* text) const;
0937       /// Add comment node to the element
0938       void addComment(const std::string& text_value) const;
0939     };
0940 
0941     /// User abstraction class to manipulate named XML elements (references) within a document
0942     /**
0943      *  User class encapsulating a DOM element which can
0944      *  be referenced. Like the Element, but the "name"
0945      *  attribute is required. The reference then has the
0946      *  corresponding "ref" attribute. The value of "name"
0947      *  and "ref" must match to establish the reference.
0948      *
0949      *  \author  M.Frank
0950      *  \version 1.0
0951      *  \ingroup DD4HEP_XML
0952      */
0953     class RefElement : public Element {
0954     public:
0955       /// Attribute holding thre name
0956       Attribute m_name;
0957       /// Construction from existing object handle
0958       RefElement(const Handle_t& e);
0959       /// Copy constructor
0960       RefElement(const RefElement& e);
0961       /// Initializing constructor to create a new XMLElement and add it to the document.
0962       RefElement(const Document& d, const XmlChar* type, const XmlChar* name);
0963       /// Assignment operator
0964       RefElement& operator=(const RefElement& e);
0965       /// Access the object's name in unicode
0966       const XmlChar* name() const;
0967       /// Access the object's reference name in unicode (same as name)
0968       const XmlChar* refName() const;
0969       /// Change/set the object's name
0970       void setName(const XmlChar* new_name);
0971     };
0972 
0973 #undef INLINE
0974 
0975     /// Forward declarations
0976     class DocumentHandler;
0977 
0978     /// Dump partial or full XML trees to stdout
0979     void dump_tree(Handle_t elt);
0980     /// Dump partial or full XML trees
0981     void dump_tree(Handle_t elt, std::ostream& os);
0982     /// Dump partial or full XML documents to stdout
0983     void dump_tree(Document doc);
0984     /// Dump partial or full XML documents
0985     void dump_tree(Document doc, std::ostream& os);
0986 
0987   }
0988 } /* End namespace dd4hep   */
0989 #endif // XML_XMLELEMENTS_H