From 73fcc40fa4382e2325be601bd85ebe258420e1ce Mon Sep 17 00:00:00 2001 From: pennae Date: Fri, 31 Dec 2021 03:16:59 +0100 Subject: [PATCH] use boost::lexical_cast for string2* this avoids one copy from `s` into `str`, and possibly another copy needed to construct `s` at the call site. lexical_cast is also more efficient in general. --- src/libutil/util.hh | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/libutil/util.hh b/src/libutil/util.hh index d08f42826..7da60b310 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -11,6 +11,8 @@ #include #include +#include + #include #include #include @@ -417,21 +419,21 @@ bool statusOk(int status); /* Parse a string into an integer. */ template -std::optional string2Int(const std::string & s) +std::optional string2Int(const std::string_view s) { if (s.substr(0, 1) == "-" && !std::numeric_limits::is_signed) return std::nullopt; - std::istringstream str(s); - N n; - str >> n; - if (str && str.get() == EOF) return n; - return std::nullopt; + try { + return boost::lexical_cast(s.data(), s.size()); + } catch (const boost::bad_lexical_cast &) { + return std::nullopt; + } } /* Like string2Int(), but support an optional suffix 'K', 'M', 'G' or 'T' denoting a binary unit prefix. */ template -N string2IntWithUnitPrefix(std::string s) +N string2IntWithUnitPrefix(std::string_view s) { N multiplier = 1; if (!s.empty()) { @@ -442,7 +444,7 @@ N string2IntWithUnitPrefix(std::string s) else if (u == 'G') multiplier = 1ULL << 30; else if (u == 'T') multiplier = 1ULL << 40; else throw UsageError("invalid unit specifier '%1%'", u); - s.resize(s.size() - 1); + s.remove_suffix(1); } } if (auto n = string2Int(s)) @@ -452,13 +454,13 @@ N string2IntWithUnitPrefix(std::string s) /* Parse a string into a float. */ template -std::optional string2Float(const string & s) +std::optional string2Float(const std::string_view s) { - std::istringstream str(s); - N n; - str >> n; - if (str && str.get() == EOF) return n; - return std::nullopt; + try { + return boost::lexical_cast(s.data(), s.size()); + } catch (const boost::bad_lexical_cast &) { + return std::nullopt; + } }