From d544ce5a519e5f636fac44bdb715b82b8a0e91e3 Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Tue, 28 Oct 2014 18:39:05 +0000
Subject: [PATCH] Add XML helper class to access specially formed XML child
 nodes.

---
 DDCore/include/DD4hep/DetFactoryHelper.h |   2 +
 DDCore/include/XML/XMLChildValue.h       | 355 +++++++++++++++++++++++
 DDCore/include/XML/XMLDimension.h        |   4 +-
 DDCore/src/XML/XMLChildValue.cpp         | 211 ++++++++++++++
 DDCore/src/XML/XMLDimension.cpp          |  18 +-
 5 files changed, 577 insertions(+), 13 deletions(-)
 create mode 100644 DDCore/include/XML/XMLChildValue.h
 create mode 100644 DDCore/src/XML/XMLChildValue.cpp

diff --git a/DDCore/include/DD4hep/DetFactoryHelper.h b/DDCore/include/DD4hep/DetFactoryHelper.h
index ee7ee6b15..b55268246 100644
--- a/DDCore/include/DD4hep/DetFactoryHelper.h
+++ b/DDCore/include/DD4hep/DetFactoryHelper.h
@@ -10,6 +10,7 @@
 #define DD4hep_DETECTOR_DETFACTORYHELPER_H
 
 #include "XML/XMLDetector.h"
+#include "XML/XMLChildValue.h"
 #include "DD4hep/LCDD.h"
 #include "DD4hep/Factories.h"
 #include "DD4hep/DD4hepUnits.h"
@@ -24,6 +25,7 @@ typedef DD4hep::XML::RefElement xml_ref_t;
 typedef DD4hep::XML::DetElement xml_det_t;
 typedef DD4hep::XML::Component xml_comp_t;
 typedef DD4hep::XML::Dimension xml_dim_t;
+typedef DD4hep::XML::ChildValue xml_val_t;
 typedef DD4hep::XML::Document xml_doc_t;
 typedef DD4hep::XML::Strng_t Unicode;
 typedef DD4hep::Geometry::LCDD lcdd_t;
diff --git a/DDCore/include/XML/XMLChildValue.h b/DDCore/include/XML/XMLChildValue.h
new file mode 100644
index 000000000..cbbf6c6bf
--- /dev/null
+++ b/DDCore/include/XML/XMLChildValue.h
@@ -0,0 +1,355 @@
+// $Id: XMLDetector.h 513 2013-04-05 14:31:53Z gaede $
+//====================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_XMLCHILDVALUE_H
+#define DD4HEP_XMLCHILDVALUE_H
+
+// Framework include files
+#include "XML/XMLTags.h"
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the AIDA detector description toolkit supporting XML utilities 
+  namespace XML {
+
+    /// XML Handle to xml elements with predefined child access
+    /**
+     *  Helper class to access any field in a xml tag in a
+     *  very easy way.
+     *  - You may assign any xml handle to a childvalue object
+     *  - Any child with the name and the value attribute set may then be accessed
+     *    by it's natural way. All possible child names are
+     *    reflected by the object's member functions.
+     *
+     *    IMPORTANT NOTE:
+     *    to be understood, the child elements MUST have structure like:
+     *    <inner_r value="76*cm" ....other attributes...../>
+     *    Other attributes may e.g. be a comment describing the variable.
+     *    The 'other attributes' are ignored. The 'value' attribute
+     *    is mandatory.
+     *
+     *  - If an child is requested and not present, a exception
+     *    is thrown.
+     *  - Functions, which accept a default value do NOT throw
+     *    an exception if the child is not present. These
+     *    rather return the default value.
+     *  - If a often used function is not present - the
+     *    implementation thereof is simple.
+     *
+     *  Such helper classes may be defined locally by any user
+     *  since XML element handles may easily be transferred.
+     *  Run-time exceptions occur however, if non-exiting child elements
+     *  are accessed.
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_XML
+     */
+    struct ChildValue: public Element {
+      /// Default constructor
+      ChildValue()
+          : Element(Handle_t(0)) {
+      }
+      /// Constructor from Handle
+      ChildValue(Handle_t e)
+          : Element(e) {
+      }
+      /// Constructor from Element
+      ChildValue(const Element& e)
+          : Element(e) {
+      }
+
+      /// Access parameters: id
+      int id() const;
+      /// Access parameters: id, if not present returns default
+      int id(int default_value) const;
+
+      /// Access parameters: type
+      int type() const;
+      /// Access rotation constants: combineHits
+      bool combineHits() const;
+
+      /// Access rotation constants: angle
+      double angle() const;
+      /// Access rotation constants: angle
+      double alpha() const;
+      /// Access rotation constants: angle
+      double beta() const;
+      /// Access rotation constants: angle
+      double gamma() const;
+      /// Access rotation constants: angle
+      double delta() const;
+      /// Access rotation constants: angle
+      double epsilon() const;
+      /// Access rotation constants: theta
+      double theta() const;
+      /// Access rotation constants: thetaBins
+      int thetaBins() const;
+
+      /// Access rotation constants: phi
+      double phi() const;
+      /// Access rotation constants: phiBins
+      int phiBins() const;
+      /// Access rotation constants: phi0
+      double phi0() const;
+      /// Access parameters: phi0, if not present returns default
+      double phi0(double default_value) const;
+      /// Access rotation constants: phi1
+      double phi1() const;
+      /// Access parameters: phi1, if not present returns default
+      double phi1(double default_value) const;
+      /// Access rotation constants: psi
+      double psi() const;
+
+      /// Access Tube parameters: zhalf
+      double zhalf() const;
+      /// Access Tube parameters: deltaphi
+      double deltaphi() const;
+
+      /// Access parameters: b
+      double b() const;
+      /// Access parameters: B
+      double B() const;
+      /// Access parameters: g
+      double g() const;
+      /// Access parameters: G
+      double G() const;
+
+      /// Access parameters: r
+      double r() const;
+      /// Access parameters: r, if not present returns default
+      double r(double default_value) const;
+      /// Access parameters: R
+      double R() const;
+      /// Access parameters: dr
+      double dr() const;
+      /// Access parameters: r0
+      double r0() const;
+      /// Access parameters: dr, if not present returns default
+      double dr(double default_value) const;
+      /// Access min/max parameters: rmin
+      double rmin() const;
+      /// Access min/max parameters: rmax
+      double rmax() const;
+      /// Access min/max parameters: rmin1
+      double rmin1() const;
+      /// Access min/max parameters: rmax1
+      double rmax1() const;
+      /// Access min/max parameters: rmin2
+      double rmin2() const;
+      /// Access min/max parameters: rmax2
+      double rmax2() const;
+      /// Access parameters: radius
+      double radius() const;
+      /// Access attribute values: outer_radius
+      double outer_radius() const;
+      /// Access attribute values: outer_r
+      double outer_r() const;
+      /// Access attribute values: inner_radius
+      double inner_radius() const;
+      /// Access attribute values: inner_r
+      double inner_r() const;
+
+      /// Access parameters: x
+      double x() const;
+      /// Access parameters: x, if not present returns default
+      double x(double default_val) const;
+      /// Access parameters: X
+      double X() const;
+      /// Access parameters: x0
+      double x0() const;
+      /// Access parameters: x1
+      double x1() const;
+      /// Access parameters: x2
+      double x2() const;
+      /// Access parameters: dx
+      double dx() const;
+      /// Access parameters: dx, if not present returns default
+      double dx(double default_value) const;
+      /// Access min/max parameters: xmax
+      double xmin() const;
+      /// Access min/max parameters: xmax
+      double xmax() const;
+      /// Access min/max parameters: x_offset
+      double x_offset() const;
+      /// Access min/max parameters: dim_x
+      double dim_x() const;
+
+      /// Access parameters: y
+      double y() const;
+      /// Access parameters: y, if not present returns default
+      double y(double default_val) const;
+      /// Access parameters: Y
+      double Y() const;
+      /// Access parameters: y0
+      double y0() const;
+      /// Access parameters: y1
+      double y1() const;
+      /// Access parameters: y2
+      double y2() const;
+      /// Access parameters: dy
+      double dy() const;
+      /// Access parameters: dz, if not present returns default
+      double dy(double default_value) const;
+      /// Access min/max parameters: ymax
+      double ymin() const;
+      /// Access min/max parameters: ymax
+      double ymax() const;
+      /// Access min/max parameters: y_offset
+      double y_offset() const;
+      /// Access min/max parameters: dim_y
+      double dim_y() const;
+
+      /// Access parameters: z
+      double z() const;
+      /// Access parameters: z, if not present returns default
+      double z(double default_val) const;
+      /// Access parameters: Z
+      double Z() const;
+      /// Access parameters: z0
+      double z0() const;
+      /// Access parameters: z1
+      double z1() const;
+      /// Access parameters: z2
+      double z2() const;
+      /// Access parameters: dz
+      double dz() const;
+      /// Access parameters: dz, if not present returns default
+      double dz(double default_value) const;
+      /// Access min/max parameters: zmax
+      double zmin() const;
+      /// Access min/max parameters: zmax
+      double zmax() const;
+      /// Access attribute values: outer_z
+      double outer_z() const;
+      /// Access attribute values: inner_z
+      double inner_z() const;
+      /// Access min/max parameters: z_offset
+      double z_offset() const;
+      /// Access min/max parameters: dim_z
+      double dim_z() const;
+
+      /// Access attribute values: length
+      double length() const;
+      /// Access attribute values: width
+      double width() const;
+      /// Access attribute values: height
+      double height() const;
+      /// Access attribute values: depth
+      double depth() const;
+      /// Access attribute values: thickness
+      double thickness() const;
+
+      /// Access attribute values: z_length
+      double z_length() const;
+      /// Access attribute values: gap
+      double gap() const;
+      /// Access attribute values: r_size
+      double r_size() const;
+      /// Access attribute values: phi_size_max
+      double phi_size_max() const;
+      /// Access attribute values: reflect
+      bool reflect() const;
+      /// Access attribute values: reflect
+      bool reflect(bool default_value) const;
+      /// Access attribute values: crossing_angle
+      double crossing_angle() const;
+      /// Access attribute values: repeat
+      int repeat() const;
+
+      /// Access attribute values: outgoing_r
+      double outgoing_r() const;
+      /// Access attribute values: incoming_r
+      double incoming_r() const;
+      /// Access attribute values: offset
+      double offset() const;
+      /// Access attribute values: offset
+      double offset(double default_value) const;
+      /// Access attribute values: number
+      int number() const;
+
+      /// Access attribute values: nmodules
+      int nmodules() const;
+      /// Access attribute values: nModules
+      int nModules() const;
+      /// Access attribute values: RowID
+      int RowID() const;
+      /// Access attribute values: moduleHeight
+      double moduleHeight() const;
+      /// Access attribute values: moduleWidth
+      double moduleWidth() const;
+      /// Access attribute values: modulePitch
+      double modulePitch() const;
+      /// Access attribute values: modulePosX
+      double modulePosX() const;
+      /// Access attribute values: modulePosY
+      double modulePosY() const;
+
+      /// Access attribute values: nPads
+      int nPads() const;
+      /// Access attribute values: rowPitch
+      double rowPitch() const;
+      /// Access attribute values: padPitch
+      double padPitch() const;
+      /// Access attribute values: rowHeight
+      double rowHeight() const;
+      /// Access attribute values: padType
+      std::string padType() const;
+
+      /// Access attribute values: numsides
+      int numsides() const;
+
+      /// Access attribute values: phi_tilt
+      double phi_tilt() const;
+      /// Access attribute values: nphi
+      int nphi() const;
+      /// Access attribute values: rc
+      double rc() const;
+
+      /// Access attribute values: zstart
+      double zstart() const;
+      /// Access attribute values: nz
+      int nz() const;
+
+      /// Access attribute values: start
+      double start() const;
+      /// Access attribute values: end
+      double end() const;
+      /// Access attribute values: inner_field
+      double inner_field() const;
+      /// Access attribute values: outer_field
+      double outer_field() const;
+
+      /// Access attribute values: visible
+      bool visible() const;
+      /// Access attribute values: show_daughters
+      bool show_daughters() const;
+
+      /// Access "name" attribute as STL string
+      std::string nameStr() const;
+      /// Access "ref" attribute as a string
+      std::string refStr() const;
+      /// Access "type" attribute as STL string
+      std::string typeStr() const;
+      /// Access "value" attribute as STL string
+      std::string valueStr() const;
+      /// Access "module" attribute as STL string
+      std::string moduleStr() const;
+      /// Access "readout" attribute as STL string
+      std::string readoutStr() const;
+      /// Access vis attribute as STL string. If not present empty return empty string
+      std::string visStr() const;
+      /// Access region attribute as STL string. If not present empty return empty string
+      std::string regionStr() const;
+      /// Access limits attribute as STL string. If not present empty return empty string
+      std::string limitsStr() const;
+    };
+  } /* End namespace XML       */
+} /* End namespace DD4hep    */
+#endif    /* DD4HEP_XMLCHILDVALUE_H   */
diff --git a/DDCore/include/XML/XMLDimension.h b/DDCore/include/XML/XMLDimension.h
index f66e1b59e..cd2da45e2 100644
--- a/DDCore/include/XML/XMLDimension.h
+++ b/DDCore/include/XML/XMLDimension.h
@@ -25,7 +25,7 @@ namespace DD4hep {
      *  - You may assign any xml handle to a dimension object
      *  - Any attribute of this xml element may then be accessed
      *    by it's natural way. All possible attribute names are
-     *    reflected by the Dimmension object's member functions.
+     *    reflected by the Dimension object's member functions.
      *  - If an attribute is requested and not present, a exception
      *    is thrown.
      *  - Functions, which accept a default value do NOT throw
@@ -34,7 +34,7 @@ namespace DD4hep {
      *  - If a often used function is not present - the
      *    implementation thereof is simple.
      *
-     *  Such heklper classes may be defined locally by any user
+     *  Such helper classes may be defined locally by any user
      *  since XML element handles may easily be transferred.
      *  Run-time exceptions occur however, if non-exiting attributes
      *  are accessed.
diff --git a/DDCore/src/XML/XMLChildValue.cpp b/DDCore/src/XML/XMLChildValue.cpp
new file mode 100644
index 000000000..3e861531f
--- /dev/null
+++ b/DDCore/src/XML/XMLChildValue.cpp
@@ -0,0 +1,211 @@
+// $Id: XMLElements.cpp 513 2013-04-05 14:31:53Z gaede $
+//====================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+// Framework include files
+#include "XML/XMLChildValue.h"
+
+using namespace std;
+using namespace DD4hep::XML;
+
+#define childValue(name,type)   m_element.child(Unicode_##name).attr<type>(Unicode_value)
+
+#define childValueDefault(name,type,def)  \
+  Handle_t __h = m_element.child(Unicode_##name,false);	     \
+  if ( __h.ptr() && __h.hasAttr(Unicode_value) ) return __h.attr < type > (Unicode_value); \
+  return def;
+
+#define XML_ATTR_ACCESSOR(type,name)  type ChildValue::name() const { return childValue(name,type); }
+#define XML_ATTR_ACCESSOR_DEFAULT(name,type,dressing)			\
+  type ChildValue::name(type default_val) const {                       \
+    Handle_t __h = m_element.child(Unicode_##name,false);	        \
+    if ( __h.ptr() )  {                                                 \
+      const XmlChar* val = __h.attr_value_nothrow(Unicode_value);	\
+      return val ? dressing(val) : default_val; }                       \
+    return default_val; }
+
+#define XML_ATTR_ACCESSOR_DOUBLE(name) XML_ATTR_ACCESSOR_DEFAULT(name,double,_toDouble)
+#define XML_ATTR_ACCESSOR_INT(name)    XML_ATTR_ACCESSOR_DEFAULT(name,int,_toInt)
+#define XML_ATTR_ACCESSOR_BOOL(name)   XML_ATTR_ACCESSOR_DEFAULT(name,bool,_toBool)
+
+XML_ATTR_ACCESSOR(int, id)
+XML_ATTR_ACCESSOR_INT(id)
+XML_ATTR_ACCESSOR(bool, combineHits)
+
+XML_ATTR_ACCESSOR(double, x)
+XML_ATTR_ACCESSOR_DOUBLE(x)
+XML_ATTR_ACCESSOR(double, X)
+XML_ATTR_ACCESSOR(double, dx)
+XML_ATTR_ACCESSOR_DOUBLE(dx)
+XML_ATTR_ACCESSOR(double, x0)
+XML_ATTR_ACCESSOR(double, x1)
+XML_ATTR_ACCESSOR(double, x2)
+XML_ATTR_ACCESSOR(double, xmin)
+XML_ATTR_ACCESSOR(double, xmax)
+XML_ATTR_ACCESSOR(double, x_offset)
+XML_ATTR_ACCESSOR(double, dim_x)
+
+XML_ATTR_ACCESSOR(double, y)
+XML_ATTR_ACCESSOR_DOUBLE(y)
+XML_ATTR_ACCESSOR(double, Y)
+XML_ATTR_ACCESSOR(double, dy)
+XML_ATTR_ACCESSOR_DOUBLE(dy)
+XML_ATTR_ACCESSOR(double, y0)
+XML_ATTR_ACCESSOR(double, y1)
+XML_ATTR_ACCESSOR(double, y2)
+XML_ATTR_ACCESSOR(double, ymin)
+XML_ATTR_ACCESSOR(double, ymax)
+XML_ATTR_ACCESSOR(double, y_offset)
+XML_ATTR_ACCESSOR(double, dim_y)
+
+XML_ATTR_ACCESSOR(double, z)
+XML_ATTR_ACCESSOR_DOUBLE(z)
+XML_ATTR_ACCESSOR(double, Z)
+XML_ATTR_ACCESSOR(double, dz)
+XML_ATTR_ACCESSOR_DOUBLE(dz)
+XML_ATTR_ACCESSOR(double, z0)
+XML_ATTR_ACCESSOR(double, z1)
+XML_ATTR_ACCESSOR(double, z2)
+XML_ATTR_ACCESSOR(double, zmin)
+XML_ATTR_ACCESSOR(double, zmax)
+XML_ATTR_ACCESSOR(double, z_offset)
+XML_ATTR_ACCESSOR(double, dim_z)
+XML_ATTR_ACCESSOR(double, outer_z)
+XML_ATTR_ACCESSOR(double, inner_z)
+
+XML_ATTR_ACCESSOR(double, b)
+XML_ATTR_ACCESSOR(double, g)
+XML_ATTR_ACCESSOR(double, B)
+XML_ATTR_ACCESSOR(double, G)
+XML_ATTR_ACCESSOR(double, r)
+XML_ATTR_ACCESSOR_DOUBLE(r)
+XML_ATTR_ACCESSOR(double, R)
+XML_ATTR_ACCESSOR(double, dr)
+XML_ATTR_ACCESSOR(double, rmin)
+XML_ATTR_ACCESSOR(double, rmax)
+XML_ATTR_ACCESSOR(double, rmin1)
+XML_ATTR_ACCESSOR(double, rmax1)
+XML_ATTR_ACCESSOR(double, rmin2)
+XML_ATTR_ACCESSOR(double, rmax2)
+XML_ATTR_ACCESSOR(double, radius)
+XML_ATTR_ACCESSOR(double, outer_r)
+XML_ATTR_ACCESSOR(double, outer_radius)
+XML_ATTR_ACCESSOR(double, inner_r)
+XML_ATTR_ACCESSOR(double, inner_radius)
+
+XML_ATTR_ACCESSOR(double, angle)
+XML_ATTR_ACCESSOR(double, alpha)
+XML_ATTR_ACCESSOR(double, beta)
+XML_ATTR_ACCESSOR(double, gamma)
+XML_ATTR_ACCESSOR(double, delta)
+XML_ATTR_ACCESSOR(double, epsilon)
+XML_ATTR_ACCESSOR(double, theta)
+XML_ATTR_ACCESSOR(int, thetaBins)
+XML_ATTR_ACCESSOR(double, psi)
+XML_ATTR_ACCESSOR(double, phi)
+XML_ATTR_ACCESSOR(int, phiBins)
+XML_ATTR_ACCESSOR(double, phi0)
+XML_ATTR_ACCESSOR_DOUBLE(phi0)
+XML_ATTR_ACCESSOR(double, phi1)
+XML_ATTR_ACCESSOR_DOUBLE(phi1)
+XML_ATTR_ACCESSOR(double, deltaphi)
+
+XML_ATTR_ACCESSOR(double, length)
+XML_ATTR_ACCESSOR(double, width)
+XML_ATTR_ACCESSOR(double, height)
+XML_ATTR_ACCESSOR(double, depth)
+XML_ATTR_ACCESSOR(double, offset)
+XML_ATTR_ACCESSOR_DOUBLE(offset)
+XML_ATTR_ACCESSOR(double, crossing_angle)
+XML_ATTR_ACCESSOR(double, incoming_r)
+XML_ATTR_ACCESSOR(double, outgoing_r)
+XML_ATTR_ACCESSOR(double, phi_size_max)
+XML_ATTR_ACCESSOR(double, r_size)
+
+XML_ATTR_ACCESSOR(double, gap)
+XML_ATTR_ACCESSOR(double, z_length)
+XML_ATTR_ACCESSOR(double, zhalf)
+XML_ATTR_ACCESSOR(double, phi_tilt)
+XML_ATTR_ACCESSOR(int, nphi)
+XML_ATTR_ACCESSOR(double, rc)
+XML_ATTR_ACCESSOR(int, nz)
+XML_ATTR_ACCESSOR(double, zstart)
+XML_ATTR_ACCESSOR(double, start)
+XML_ATTR_ACCESSOR(double, end)
+XML_ATTR_ACCESSOR(double, thickness)
+XML_ATTR_ACCESSOR(int, numsides)
+XML_ATTR_ACCESSOR(int, number)
+XML_ATTR_ACCESSOR(int, repeat)
+XML_ATTR_ACCESSOR(bool, reflect)
+XML_ATTR_ACCESSOR_BOOL(reflect)
+
+XML_ATTR_ACCESSOR(int, nmodules)
+XML_ATTR_ACCESSOR(int, nModules)
+XML_ATTR_ACCESSOR(int, RowID)
+XML_ATTR_ACCESSOR(int, nPads)
+XML_ATTR_ACCESSOR(double, moduleHeight)
+XML_ATTR_ACCESSOR(double, moduleWidth)
+XML_ATTR_ACCESSOR(double, modulePosX)
+XML_ATTR_ACCESSOR(double, modulePosY)
+XML_ATTR_ACCESSOR(double, modulePitch)
+XML_ATTR_ACCESSOR(double, rowPitch)
+XML_ATTR_ACCESSOR(double, padPitch)
+XML_ATTR_ACCESSOR(double, rowHeight)
+XML_ATTR_ACCESSOR(double, inner_field)
+XML_ATTR_ACCESSOR(double, outer_field)
+XML_ATTR_ACCESSOR(int, type)
+
+XML_ATTR_ACCESSOR(bool, visible)
+XML_ATTR_ACCESSOR(bool, show_daughters)
+#if 0
+XML_ATTR_ACCESSOR(double,)
+XML_ATTR_ACCESSOR(double,)
+XML_ATTR_ACCESSOR(double,)
+XML_ATTR_ACCESSOR(double,)
+#endif
+
+
+string ChildValue::padType() const {
+  return childValue(pads,string);
+}
+
+string ChildValue::nameStr() const {
+  return childValue(name,string);
+}
+
+string ChildValue::refStr() const {
+  return childValue(ref,string);
+}
+
+string ChildValue::typeStr() const {
+  return childValue(type,string);
+}
+
+/// Access "value" attribute as STL string
+std::string ChildValue::valueStr() const   {
+  return childValue(value,string);
+}
+
+string ChildValue::regionStr() const {
+  childValueDefault(region,string,string());
+}
+
+string ChildValue::limitsStr() const {
+  childValueDefault(limits,string,string());
+}
+
+string ChildValue::visStr() const {
+  childValueDefault(vis,string,string());
+}
+
+string ChildValue::readoutStr() const {
+  childValueDefault(readout,string,string());
+}
+
+string ChildValue::moduleStr() const {
+  childValueDefault(module,string,string());
+}
diff --git a/DDCore/src/XML/XMLDimension.cpp b/DDCore/src/XML/XMLDimension.cpp
index 6910a59ce..b3964c29d 100644
--- a/DDCore/src/XML/XMLDimension.cpp
+++ b/DDCore/src/XML/XMLDimension.cpp
@@ -13,18 +13,14 @@ using namespace std;
 using namespace DD4hep::XML;
 
 #define XML_ATTR_ACCESSOR(type,name)  type Dimension::name() const { return m_element.attr<type>(Unicode_##name); }
-#define XML_ATTR_ACCESSOR_DOUBLE(name)	                                \
-  double Dimension::name(double default_val) const {		       	\
+#define XML_ATTR_ACCESSOR_DEFAULT(name,type,dressing)			\
+  type Dimension::name(type default_val) const {                       \
     const XmlChar* val = m_element.attr_value_nothrow(Unicode_##name);	\
-    return val ? _toDouble(val) : default_val; }
-#define XML_ATTR_ACCESSOR_INT(name)	                                \
-  int Dimension::name(int default_val) const {				\
-    const XmlChar* val = m_element.attr_value_nothrow(Unicode_##name);	\
-    return val ? _toInt(val) : default_val; }
-#define XML_ATTR_ACCESSOR_BOOL(name)	                                \
-  bool Dimension::name(bool default_val) const {		       	\
-    const XmlChar* val = m_element.attr_value_nothrow(Unicode_##name);	\
-    return val ? _toBool(val) : default_val; }
+    return val ? dressing(val) : default_val; }
+
+#define XML_ATTR_ACCESSOR_DOUBLE(name)	 XML_ATTR_ACCESSOR_DEFAULT(name,double,_toDouble)
+#define XML_ATTR_ACCESSOR_INT(name)	 XML_ATTR_ACCESSOR_DEFAULT(name,int,_toInt)
+#define XML_ATTR_ACCESSOR_BOOL(name)	 XML_ATTR_ACCESSOR_DEFAULT(name,bool,_toBool)
 
 #define XML_CHILD_ACCESSOR_XML_DIM(name)	                        \
   Dimension Dimension::name(bool throw_if_not_present) const {          \
-- 
GitLab