@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <charconv>
|
||||
#include <concepts>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
#include <type_traits>
|
||||
|
||||
#include <modulus/result.hpp>
|
||||
|
||||
#include <vamp_zero/errors.hpp>
|
||||
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
template <std::integral VALUE>
|
||||
requires(!std::is_same_v<VALUE, std::bool_t>)
|
||||
auto parse_integer(std::string_view text, std::string_view name) -> std::expected<VALUE, modulus::error> {
|
||||
auto invalid = [&](std::string_view reason) {
|
||||
return modulus::fail<VALUE>(
|
||||
make_error(error_code::INVALID_ARGUMENT, std::string{name} + " " + std::string{reason}));
|
||||
};
|
||||
if (text.empty()) {
|
||||
return invalid("must be an integer");
|
||||
}
|
||||
auto value = VALUE{};
|
||||
auto end = text.data() + text.size();
|
||||
auto parsed = std::from_chars(text.data(), end, value);
|
||||
if (parsed.ec == std::errc::result_out_of_range) {
|
||||
return invalid("is out of range");
|
||||
}
|
||||
if (parsed.ec != std::errc{} || parsed.ptr != end) {
|
||||
return invalid("must be an integer");
|
||||
}
|
||||
return modulus::success(value);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user