summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Mittendrein <maxmitti@maxmitti.tk>2022-01-09 20:35:34 +0100
committerMarkus Mittendrein <maxmitti@maxmitti.tk>2022-01-09 20:35:34 +0100
commitbf4c0d7089d262a1ea61550ff4cd951f52dad4da (patch)
tree829adabc1aa9fc8fde0989066318d4ed8b77d345
parentf1ff922eafc6972dd6437d6e9908146fa92577fa (diff)
downloadcxxformat-bf4c0d7089d262a1ea61550ff4cd951f52dad4da.tar.gz
cxxformat-bf4c0d7089d262a1ea61550ff4cd951f52dad4da.zip
Fix maximum value check for parsing numbers from format strings
-rw-r--r--include/cxxformat/core.hpp8
-rw-r--r--include/cxxformat/helpers.hpp5
2 files changed, 8 insertions, 5 deletions
diff --git a/include/cxxformat/core.hpp b/include/cxxformat/core.hpp
index 2a78b26..acf8613 100644
--- a/include/cxxformat/core.hpp
+++ b/include/cxxformat/core.hpp
@@ -189,7 +189,7 @@ namespace format {
}
template<std::unsigned_integral T = unsigned int>
- constexpr std::pair<std::optional<T>, std::size_t> parseNumber(std::string_view s, std::size_t pos)
+ constexpr std::pair<optional_int<T>, std::size_t> parseNumber(std::string_view s, std::size_t pos)
{
if (pos >= s.size())
{
@@ -202,7 +202,7 @@ namespace format {
return {std::nullopt, pos};
}
- constexpr auto max = std::numeric_limits<T>::max();
+ constexpr auto max = optional_int<T>::max;
T val{*d};
auto p = pos + 1;
@@ -225,12 +225,12 @@ namespace format {
}
template<std::unsigned_integral T = unsigned int>
- constexpr std::pair<std::optional<T>, std::size_t> parseNumberWithMessage(std::string_view s, std::size_t pos, std::string_view numberName)
+ constexpr std::pair<optional_int<T>, std::size_t> parseNumberWithMessage(std::string_view s, std::size_t pos, std::string_view numberName)
{
try {
return parseNumber<T>(s, pos);
} catch(const std::out_of_range&) {
- throw std::out_of_range{std::string{numberName} + " is too big; maximum is " + std::to_string(std::numeric_limits<T>::max())};
+ throw std::out_of_range{std::string{numberName} + " is too big; maximum is " + std::to_string(optional_int<T>::max)};
}
}
diff --git a/include/cxxformat/helpers.hpp b/include/cxxformat/helpers.hpp
index 73cb0be..c713835 100644
--- a/include/cxxformat/helpers.hpp
+++ b/include/cxxformat/helpers.hpp
@@ -226,7 +226,7 @@ struct optional_int {
constexpr optional_int() noexcept : val{emptyVal} {}
constexpr optional_int(std::nullopt_t) noexcept : val{emptyVal} {}
- constexpr optional_int(T val) noexcept : val{val} {}
+ constexpr optional_int(T val) noexcept : val{val} { assert(val != emptyVal); }
constexpr optional_int(const optional_int&) noexcept = default;
template<std::convertible_to<T> U>
constexpr optional_int(const optional_int<U>& other) noexcept : val{other ? other.val : emptyVal} {}
@@ -257,4 +257,7 @@ struct optional_int {
constexpr T& operator*() noexcept { return val; }
constexpr T operator*() const noexcept { return val; }
constexpr T value_or(T fallback) const noexcept { return empty() ? fallback : val; }
+
+ static inline constexpr T max{std::signed_integral<T> ? std::numeric_limits<T>::max() : emptyVal - 1};
+ static inline constexpr T min{std::numeric_limits<T>::min() + (std::signed_integral<T> ? 1 : 0)};
};