diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2021-01-15 02:01:24 +0000 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2021-01-15 02:01:24 +0000 |
commit | 0027b05a15e5845c5ce70c86b5b1a34e7caff039 (patch) | |
tree | 9264ad326d070ec2dcf5d19a373721672eb1df2e /src/libutil/util.hh | |
parent | fed123724679de89d3f56a4c01b5c4c96f93e584 (diff) | |
parent | 7a472a76d4dcbbd0eb7832c0bdcb120d32881e8b (diff) |
Merge remote-tracking branch 'upstream/master' into non-local-store-build
Diffstat (limited to 'src/libutil/util.hh')
-rw-r--r-- | src/libutil/util.hh | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 0f82bed78..ab0bd865a 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -397,21 +397,49 @@ bool statusOk(int status); /* Parse a string into an integer. */ -template<class N> bool string2Int(const string & s, N & n) +template<class N> +std::optional<N> string2Int(const std::string & s) { - if (string(s, 0, 1) == "-" && !std::numeric_limits<N>::is_signed) - return false; + if (s.substr(0, 1) == "-" && !std::numeric_limits<N>::is_signed) + return std::nullopt; std::istringstream str(s); + N n; str >> n; - return str && str.get() == EOF; + if (str && str.get() == EOF) return n; + return std::nullopt; +} + +/* Like string2Int(), but support an optional suffix 'K', 'M', 'G' or + 'T' denoting a binary unit prefix. */ +template<class N> +N string2IntWithUnitPrefix(std::string s) +{ + N multiplier = 1; + if (!s.empty()) { + char u = std::toupper(*s.rbegin()); + if (std::isalpha(u)) { + if (u == 'K') multiplier = 1ULL << 10; + else if (u == 'M') multiplier = 1ULL << 20; + 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); + } + } + if (auto n = string2Int<N>(s)) + return *n * multiplier; + throw UsageError("'%s' is not an integer", s); } /* Parse a string into a float. */ -template<class N> bool string2Float(const string & s, N & n) +template<class N> +std::optional<N> string2Float(const string & s) { std::istringstream str(s); + N n; str >> n; - return str && str.get() == EOF; + if (str && str.get() == EOF) return n; + return std::nullopt; } |