From 9b6032653a83eba685ade87b31b152373ebc3d11 Mon Sep 17 00:00:00 2001
From: Joachim Wuttke <j.wuttke@fz-juelich.de>
Date: Tue, 30 Aug 2022 14:34:16 +0200
Subject: [PATCH] service fcts in INode to simplify checks

---
 Param/Node/INode.cpp                 | 14 +++++
 Param/Node/INode.h                   |  5 ++
 Sample/HardParticle/Box.cpp          | 12 ++--
 auto/Wrap/libBornAgainParam.py       | 18 ++++++
 auto/Wrap/libBornAgainParam_wrap.cpp | 90 ++++++++++++++++++++++++++++
 5 files changed, 131 insertions(+), 8 deletions(-)

diff --git a/Param/Node/INode.cpp b/Param/Node/INode.cpp
index bc7cc1c53e6..8f93500471a 100644
--- a/Param/Node/INode.cpp
+++ b/Param/Node/INode.cpp
@@ -14,6 +14,7 @@
 
 #include "Param/Node/INode.h"
 #include "Base/Util/Assert.h"
+#include "Base/Util/StringUtils.h"
 #include "Fit/Param/RealLimits.h"
 #include <algorithm>
 #include <iostream>
@@ -60,3 +61,16 @@ std::vector<const INode*> INode::nodeOffspring() const
     }
     return result;
 }
+
+void INode::requestPositive(
+    std::vector<std::string>& errs, const double& val, const std::string& name)
+{
+    if (val<=0)
+        errs.push_back("nonpositive " + name + "=" + std::to_string(val));
+}
+
+std::string INode::jointError(
+    const std::string& className, const std::vector<std::string> errs)
+{
+    return "{ " + className + ": [ " + BaseUtils::String::join(errs, ", ") + " ] }";
+}
diff --git a/Param/Node/INode.h b/Param/Node/INode.h
index a5e23a9f15a..4308f60ed64 100644
--- a/Param/Node/INode.h
+++ b/Param/Node/INode.h
@@ -59,6 +59,11 @@ public:
     //! Returns all descendants.
     std::vector<const INode*> nodeOffspring() const;
 
+    static void requestPositive(
+        std::vector<std::string>& errs, const double& val, const std::string& name);
+    static std::string jointError(
+        const std::string& className, const std::vector<std::string> errs);
+
 protected:
     std::vector<double> m_P;
 
diff --git a/Sample/HardParticle/Box.cpp b/Sample/HardParticle/Box.cpp
index b2efb5e1366..825a22a4499 100644
--- a/Sample/HardParticle/Box.cpp
+++ b/Sample/HardParticle/Box.cpp
@@ -14,7 +14,6 @@
 
 #include "Sample/HardParticle/Box.h"
 #include "Base/Util/Assert.h"
-#include "Base/Util/StringUtils.h"
 #include "Base/Math/Functions.h"
 
 Box::Box(const std::vector<double> P)
@@ -42,14 +41,11 @@ complex_t Box::formfactor_at_bottom(C3 q) const
 std::string Box::validate() const
 {
     std::vector<std::string> errs;
-    if (m_length<=0)
-        errs.push_back("nonpositive length="+std::to_string(m_length));
-    if (m_width<=0)
-        errs.push_back("nonpositive width="+std::to_string(m_width));
-    if (m_height<=0)
-        errs.push_back("nonpositive height="+std::to_string(m_height));
+    requestPositive(errs, m_length, "length");
+    requestPositive(errs, m_width, "width");
+    requestPositive(errs, m_height, "height");
     if (!errs.empty())
-        return "{ Box: [ " + BaseUtils::String::join(errs, ", ") + " ] }";
+        return jointError("Box", errs);
 
     double a = m_length / 2;
     double b = m_width / 2;
diff --git a/auto/Wrap/libBornAgainParam.py b/auto/Wrap/libBornAgainParam.py
index 62ab86a6098..d7c45299c78 100644
--- a/auto/Wrap/libBornAgainParam.py
+++ b/auto/Wrap/libBornAgainParam.py
@@ -2126,6 +2126,16 @@ class INode(object):
 
         """
         return _libBornAgainParam.INode_nodeOffspring(self)
+
+    @staticmethod
+    def requestPositive(errs, val, name):
+        r"""requestPositive(vector_string_t errs, double const & val, std::string const & name)"""
+        return _libBornAgainParam.INode_requestPositive(errs, val, name)
+
+    @staticmethod
+    def jointError(className, errs):
+        r"""jointError(std::string const & className, vector_string_t errs) -> std::string"""
+        return _libBornAgainParam.INode_jointError(className, errs)
     def __disown__(self):
         self.this.disown()
         _libBornAgainParam.disown_INode(self)
@@ -2134,6 +2144,14 @@ class INode(object):
 # Register INode in _libBornAgainParam:
 _libBornAgainParam.INode_swigregister(INode)
 
+def INode_requestPositive(errs, val, name):
+    r"""INode_requestPositive(vector_string_t errs, double const & val, std::string const & name)"""
+    return _libBornAgainParam.INode_requestPositive(errs, val, name)
+
+def INode_jointError(className, errs):
+    r"""INode_jointError(std::string const & className, vector_string_t errs) -> std::string"""
+    return _libBornAgainParam.INode_jointError(className, errs)
+
 class IDistribution1D(libBornAgainBase.ICloneable, INode):
     r"""
 
diff --git a/auto/Wrap/libBornAgainParam_wrap.cpp b/auto/Wrap/libBornAgainParam_wrap.cpp
index 24c08e57b46..0c546351785 100644
--- a/auto/Wrap/libBornAgainParam_wrap.cpp
+++ b/auto/Wrap/libBornAgainParam_wrap.cpp
@@ -28232,6 +28232,94 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_INode_requestPositive(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string,std::allocator< std::string > > *arg1 = 0 ;
+  double *arg2 = 0 ;
+  std::string *arg3 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double temp2 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
+  PyObject *swig_obj[3] ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "INode_requestPositive", 3, 3, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t,  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INode_requestPositive" "', argument " "1"" of type '" "std::vector< std::string,std::allocator< std::string > > &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INode_requestPositive" "', argument " "1"" of type '" "std::vector< std::string,std::allocator< std::string > > &""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::string,std::allocator< std::string > > * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "INode_requestPositive" "', argument " "2"" of type '" "double""'");
+  } 
+  temp2 = static_cast< double >(val2);
+  arg2 = &temp2;
+  {
+    std::string *ptr = (std::string *)0;
+    res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "INode_requestPositive" "', argument " "3"" of type '" "std::string const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INode_requestPositive" "', argument " "3"" of type '" "std::string const &""'"); 
+    }
+    arg3 = ptr;
+  }
+  INode::requestPositive(*arg1,(double const &)*arg2,(std::string const &)*arg3);
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_INode_jointError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::string *arg1 = 0 ;
+  std::vector< std::string,std::allocator< std::string > > arg2 ;
+  int res1 = SWIG_OLDOBJ ;
+  PyObject *swig_obj[2] ;
+  std::string result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "INode_jointError", 2, 2, swig_obj)) SWIG_fail;
+  {
+    std::string *ptr = (std::string *)0;
+    res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INode_jointError" "', argument " "1"" of type '" "std::string const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "INode_jointError" "', argument " "1"" of type '" "std::string const &""'"); 
+    }
+    arg1 = ptr;
+  }
+  {
+    std::vector< std::string,std::allocator< std::string > > *ptr = (std::vector< std::string,std::allocator< std::string > > *)0;
+    int res = swig::asptr(swig_obj[1], &ptr);
+    if (!SWIG_IsOK(res) || !ptr) {
+      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "INode_jointError" "', argument " "2"" of type '" "std::vector< std::string,std::allocator< std::string > > const""'"); 
+    }
+    arg2 = *ptr;
+    if (SWIG_IsNewObj(res)) delete ptr;
+  }
+  result = INode::jointError((std::string const &)*arg1,arg2);
+  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_disown_INode(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INode *arg1 = (INode *) 0 ;
@@ -34825,6 +34913,8 @@ static PyMethodDef SwigMethods[] = {
 		"Returns all descendants. \n"
 		"\n"
 		""},
+	 { "INode_requestPositive", _wrap_INode_requestPositive, METH_VARARGS, "INode_requestPositive(vector_string_t errs, double const & val, std::string const & name)"},
+	 { "INode_jointError", _wrap_INode_jointError, METH_VARARGS, "INode_jointError(std::string const & className, vector_string_t errs) -> std::string"},
 	 { "disown_INode", _wrap_disown_INode, METH_O, NULL},
 	 { "INode_swigregister", INode_swigregister, METH_O, NULL},
 	 { "INode_swiginit", INode_swiginit, METH_VARARGS, NULL},
-- 
GitLab