diff Framework/Toolbox/LinearAlgebra.cpp @ 1167:ad4e21df4e40 broker

enriching OrthancStone::StoneInitialize()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 20 Nov 2019 10:55:44 +0100
parents 6c159b8362ff
children 1644de437a7b
line wrap: on
line diff
--- a/Framework/Toolbox/LinearAlgebra.cpp	Tue Nov 19 21:40:25 2019 +0100
+++ b/Framework/Toolbox/LinearAlgebra.cpp	Wed Nov 20 10:55:44 2019 +0100
@@ -32,6 +32,7 @@
 
 #include <stdio.h>
 #include <iostream>
+#include <cstdlib>
 
 namespace OrthancStone
 {
@@ -75,20 +76,27 @@
       {
         /**
          * SJO - 2019-11-19 - WARNING: I reverted from "std::stod()"
-         * to "boost::lexical_cast", as "std::stod()" is sensitive to
-         * locale settings, making this code non portable and very
-         * dangerous as it fails silently. A string such as
-         * "1.3671875\1.3671875" is interpreted as "1\1", because
-         * "std::stod()" expects a comma (",") instead of a point
-         * (".").
+         * to "boost::lexical_cast", as both "std::stod()" and
+         * "std::strtod()" are sensitive to locale settings, making
+         * this code non portable and very dangerous as it fails
+         * silently. A string such as "1.3671875\1.3671875" is
+         * interpreted as "1\1", because "std::stod()" expects a comma
+         * (",") instead of a point ("."). This problem is notably
+         * seen in Qt-based applications, that somehow set locales
+         * aggressively.
+         *
+         * "boost::lexical_cast<>" is also dependent on the locale
+         * settings, but apparently not in a way that makes this
+         * function fail with Qt. The Orthanc core defines macro
+         * "-DBOOST_LEXICAL_CAST_ASSUME_C_LOCALE" in static builds to
+         * this end.
          **/
         
 #if 0  // __cplusplus >= 201103L  // Is C++11 enabled?
         /**
          * We try and avoid the use of "boost::lexical_cast<>" here,
-         * as it is very slow. As we are parsing many doubles, we
-         * prefer to use the standard "std::stod" function if
-         * available: http://www.cplusplus.com/reference/string/stod/
+         * as it is very slow, and as Stone has to parse many doubles.
+         * https://tinodidriksen.com/2011/05/cpp-convert-string-to-double-speed/
          **/
           
         try
@@ -100,7 +108,26 @@
           target.clear();
           return false;
         }
-#else  // Fallback implementation using Boost
+
+#elif 0
+        /**
+         * "std::strtod()" is the recommended alternative to
+         * "std::stod()". It is apparently as fast as plain-C
+         * "atof()", with more security.
+         **/
+        char* end = NULL;
+        target[i] = std::strtod(items[i].c_str(), &end);
+        if (end == NULL ||
+            end != items[i].c_str() + items[i].size())
+        {
+          return false;
+        }
+
+#else
+        /**
+         * Fallback implementation using Boost (slower, but somewhat
+         * independent to locale).
+         **/
         try
         {
           target[i] = boost::lexical_cast<double>(items[i]);