comparison 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
comparison
equal deleted inserted replaced
1165:4d97f532f1e0 1167:ad4e21df4e40
30 #include <boost/lexical_cast.hpp> 30 #include <boost/lexical_cast.hpp>
31 #include <boost/numeric/ublas/lu.hpp> 31 #include <boost/numeric/ublas/lu.hpp>
32 32
33 #include <stdio.h> 33 #include <stdio.h>
34 #include <iostream> 34 #include <iostream>
35 #include <cstdlib>
35 36
36 namespace OrthancStone 37 namespace OrthancStone
37 { 38 {
38 namespace LinearAlgebra 39 namespace LinearAlgebra
39 { 40 {
73 74
74 for (size_t i = 0; i < items.size(); i++) 75 for (size_t i = 0; i < items.size(); i++)
75 { 76 {
76 /** 77 /**
77 * SJO - 2019-11-19 - WARNING: I reverted from "std::stod()" 78 * SJO - 2019-11-19 - WARNING: I reverted from "std::stod()"
78 * to "boost::lexical_cast", as "std::stod()" is sensitive to 79 * to "boost::lexical_cast", as both "std::stod()" and
79 * locale settings, making this code non portable and very 80 * "std::strtod()" are sensitive to locale settings, making
80 * dangerous as it fails silently. A string such as 81 * this code non portable and very dangerous as it fails
81 * "1.3671875\1.3671875" is interpreted as "1\1", because 82 * silently. A string such as "1.3671875\1.3671875" is
82 * "std::stod()" expects a comma (",") instead of a point 83 * interpreted as "1\1", because "std::stod()" expects a comma
83 * ("."). 84 * (",") instead of a point ("."). This problem is notably
85 * seen in Qt-based applications, that somehow set locales
86 * aggressively.
87 *
88 * "boost::lexical_cast<>" is also dependent on the locale
89 * settings, but apparently not in a way that makes this
90 * function fail with Qt. The Orthanc core defines macro
91 * "-DBOOST_LEXICAL_CAST_ASSUME_C_LOCALE" in static builds to
92 * this end.
84 **/ 93 **/
85 94
86 #if 0 // __cplusplus >= 201103L // Is C++11 enabled? 95 #if 0 // __cplusplus >= 201103L // Is C++11 enabled?
87 /** 96 /**
88 * We try and avoid the use of "boost::lexical_cast<>" here, 97 * We try and avoid the use of "boost::lexical_cast<>" here,
89 * as it is very slow. As we are parsing many doubles, we 98 * as it is very slow, and as Stone has to parse many doubles.
90 * prefer to use the standard "std::stod" function if 99 * https://tinodidriksen.com/2011/05/cpp-convert-string-to-double-speed/
91 * available: http://www.cplusplus.com/reference/string/stod/
92 **/ 100 **/
93 101
94 try 102 try
95 { 103 {
96 target[i] = std::stod(items[i]); 104 target[i] = std::stod(items[i]);
98 catch (std::exception&) 106 catch (std::exception&)
99 { 107 {
100 target.clear(); 108 target.clear();
101 return false; 109 return false;
102 } 110 }
103 #else // Fallback implementation using Boost 111
112 #elif 0
113 /**
114 * "std::strtod()" is the recommended alternative to
115 * "std::stod()". It is apparently as fast as plain-C
116 * "atof()", with more security.
117 **/
118 char* end = NULL;
119 target[i] = std::strtod(items[i].c_str(), &end);
120 if (end == NULL ||
121 end != items[i].c_str() + items[i].size())
122 {
123 return false;
124 }
125
126 #else
127 /**
128 * Fallback implementation using Boost (slower, but somewhat
129 * independent to locale).
130 **/
104 try 131 try
105 { 132 {
106 target[i] = boost::lexical_cast<double>(items[i]); 133 target[i] = boost::lexical_cast<double>(items[i]);
107 } 134 }
108 catch (boost::bad_lexical_cast&) 135 catch (boost::bad_lexical_cast&)