mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 23:18:14 +01:00
util: Introduce ToIntegral<T>(const std::string&) for locale independent parsing using std::from_chars(…) (C++17)
util: Avoid locale dependent functions strtol/strtoll/strtoul/strtoull in ParseInt32/ParseInt64/ParseUInt32/ParseUInt64
fuzz: Assert equivalence between new and old Parse{Int,Uint}{8,32,64} functions
test: Add unit tests for ToIntegral<T>(const std::string&)
This commit is contained in:
@@ -12,8 +12,10 @@
|
||||
#include <attributes.h>
|
||||
#include <span.h>
|
||||
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -94,6 +96,24 @@ constexpr inline bool IsSpace(char c) noexcept {
|
||||
return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to integral type T.
|
||||
*
|
||||
* @returns std::nullopt if the entire string could not be parsed, or if the
|
||||
* parsed value is not in the range representable by the type T.
|
||||
*/
|
||||
template <typename T>
|
||||
std::optional<T> ToIntegral(const std::string& str)
|
||||
{
|
||||
static_assert(std::is_integral<T>::value);
|
||||
T result;
|
||||
const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result);
|
||||
if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return {result};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to signed 32-bit integer with strict parse error feedback.
|
||||
* @returns true if the entire string could be parsed as valid integer,
|
||||
|
||||
Reference in New Issue
Block a user