forked from lix-project/lix
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.
This commit is contained in:
parent
5838354d34
commit
73fcc40fa4
|
@ -11,6 +11,8 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -417,21 +419,21 @@ bool statusOk(int status);
|
||||||
|
|
||||||
/* Parse a string into an integer. */
|
/* Parse a string into an integer. */
|
||||||
template<class N>
|
template<class N>
|
||||||
std::optional<N> string2Int(const std::string & s)
|
std::optional<N> string2Int(const std::string_view s)
|
||||||
{
|
{
|
||||||
if (s.substr(0, 1) == "-" && !std::numeric_limits<N>::is_signed)
|
if (s.substr(0, 1) == "-" && !std::numeric_limits<N>::is_signed)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
std::istringstream str(s);
|
try {
|
||||||
N n;
|
return boost::lexical_cast<N>(s.data(), s.size());
|
||||||
str >> n;
|
} catch (const boost::bad_lexical_cast &) {
|
||||||
if (str && str.get() == EOF) return n;
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Like string2Int(), but support an optional suffix 'K', 'M', 'G' or
|
/* Like string2Int(), but support an optional suffix 'K', 'M', 'G' or
|
||||||
'T' denoting a binary unit prefix. */
|
'T' denoting a binary unit prefix. */
|
||||||
template<class N>
|
template<class N>
|
||||||
N string2IntWithUnitPrefix(std::string s)
|
N string2IntWithUnitPrefix(std::string_view s)
|
||||||
{
|
{
|
||||||
N multiplier = 1;
|
N multiplier = 1;
|
||||||
if (!s.empty()) {
|
if (!s.empty()) {
|
||||||
|
@ -442,7 +444,7 @@ N string2IntWithUnitPrefix(std::string s)
|
||||||
else if (u == 'G') multiplier = 1ULL << 30;
|
else if (u == 'G') multiplier = 1ULL << 30;
|
||||||
else if (u == 'T') multiplier = 1ULL << 40;
|
else if (u == 'T') multiplier = 1ULL << 40;
|
||||||
else throw UsageError("invalid unit specifier '%1%'", u);
|
else throw UsageError("invalid unit specifier '%1%'", u);
|
||||||
s.resize(s.size() - 1);
|
s.remove_suffix(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (auto n = string2Int<N>(s))
|
if (auto n = string2Int<N>(s))
|
||||||
|
@ -452,14 +454,14 @@ N string2IntWithUnitPrefix(std::string s)
|
||||||
|
|
||||||
/* Parse a string into a float. */
|
/* Parse a string into a float. */
|
||||||
template<class N>
|
template<class N>
|
||||||
std::optional<N> string2Float(const string & s)
|
std::optional<N> string2Float(const std::string_view s)
|
||||||
{
|
{
|
||||||
std::istringstream str(s);
|
try {
|
||||||
N n;
|
return boost::lexical_cast<N>(s.data(), s.size());
|
||||||
str >> n;
|
} catch (const boost::bad_lexical_cast &) {
|
||||||
if (str && str.get() == EOF) return n;
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return true iff `s' starts with `prefix'. */
|
/* Return true iff `s' starts with `prefix'. */
|
||||||
|
|
Loading…
Reference in a new issue