You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.3 KiB
C++
52 lines
1.3 KiB
C++
// SPDX-License-Identifier: BSD-2-Clause
|
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
|
|
|
#pragma once
|
|
|
|
#include <charconv>
|
|
#include <concepts>
|
|
#include <optional>
|
|
#include <string_view>
|
|
|
|
/**
|
|
* A std::from_chars() wrapper taking a std::string_view. How
|
|
* annoying that the C++ standard library doesn't allow this!
|
|
*/
|
|
inline std::from_chars_result
|
|
FromChars(std::string_view s, std::integral auto &value, int base=10) noexcept
|
|
{
|
|
return std::from_chars(s.data(), s.data() + s.size(), value, base);
|
|
}
|
|
|
|
/**
|
|
* A wrapper for FromChars() which translates the #from_chars_result
|
|
* to a boolean (true on success, false on error).
|
|
*/
|
|
inline bool
|
|
ParseIntegerTo(std::string_view s, std::integral auto &value, int base=10) noexcept
|
|
{
|
|
auto [ptr, ec] = FromChars(s, value, base);
|
|
return ptr == s.data() + s.size() && ec == std::errc{};
|
|
}
|
|
|
|
template<std::integral T>
|
|
[[gnu::pure]]
|
|
std::optional<T>
|
|
ParseInteger(const char *first, const char *last, int base=10) noexcept
|
|
{
|
|
T value;
|
|
auto [ptr, ec] = std::from_chars(first, last, value, base);
|
|
if (ptr == last && ec == std::errc{})
|
|
return value;
|
|
else
|
|
return std::nullopt;
|
|
}
|
|
|
|
template<std::integral T>
|
|
[[gnu::pure]]
|
|
std::optional<T>
|
|
ParseInteger(std::string_view src, int base=10) noexcept
|
|
{
|
|
return ParseInteger<T>(src.data(), src.data() + src.size(), base);
|
|
}
|