Skip to content

Commit 2e8863d

Browse files
committed
[RF][HS3] Simplify isNumber using standard stream parsing
Replace the hand-rolled character-by-character number parser with a std::istringstream extraction that requires the whole string to be consumed. This mirrors the parsing done by toDouble(), so isNumber(s) is true exactly when toDouble(s) can convert the entire string. std::from_chars for floating-point types is not portably available on all platforms ROOT supports, so the stream extraction is used instead.
1 parent f87a55e commit 2e8863d

1 file changed

Lines changed: 7 additions & 29 deletions

File tree

roofit/hs3/src/RooJSONFactoryWSTool.cxx

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <algorithm>
4040
#include <fstream>
4141
#include <iostream>
42+
#include <sstream>
4243
#include <stack>
4344
#include <stdexcept>
4445

@@ -154,35 +155,12 @@ bool matches(const RooJSONFactoryWSTool::CombinedData &data, const RooSimultaneo
154155
*/
155156
bool isNumber(const std::string &str)
156157
{
157-
bool seen_digit = false;
158-
bool seen_dot = false;
159-
bool seen_e = false;
160-
bool after_e = false;
161-
bool sign_allowed = true;
162-
163-
for (size_t i = 0; i < str.size(); ++i) {
164-
char c = str[i];
165-
166-
if (std::isdigit(c)) {
167-
seen_digit = true;
168-
sign_allowed = false;
169-
} else if ((c == '+' || c == '-') && sign_allowed) {
170-
// Sign allowed at the beginning or right after 'e'/'E'
171-
sign_allowed = false;
172-
} else if (c == '.' && !seen_dot && !after_e) {
173-
seen_dot = true;
174-
sign_allowed = false;
175-
} else if ((c == 'e' || c == 'E') && seen_digit && !seen_e) {
176-
seen_e = true;
177-
after_e = true;
178-
sign_allowed = true; // allow sign immediately after 'e'
179-
seen_digit = false; // reset: we now expect digits after e
180-
} else {
181-
return false;
182-
}
183-
}
184-
185-
return seen_digit;
158+
// Parse with the same mechanism as toDouble() and require that the whole string is consumed, so that isNumber(s) is
159+
// true exactly when toDouble(s) can turn the entire string into a value. (std::from_chars for floating-point types
160+
// is not portably available on all platforms ROOT supports, so we rely on the stream extraction instead.)
161+
std::istringstream stream(str);
162+
double value = 0.0;
163+
return (stream >> value) && stream.eof();
186164
}
187165

188166
/**

0 commit comments

Comments
 (0)