Skip to content

Commit c566635

Browse files
committed
[main] optparse: don't use std::from_chars on macOS
1 parent 3e4fe8b commit c566635

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

main/src/optparse.hxx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include <charconv>
5555
#include <cstring>
5656
#include <iostream>
57+
#include <limits>
5758
#include <optional>
5859
#include <sstream>
5960
#include <stdexcept>
@@ -194,6 +195,8 @@ public:
194195
static_assert(std::is_integral_v<T> || std::is_floating_point_v<T>);
195196

196197
if (auto val = GetFlagValue(name); !val.empty()) {
198+
// NOTE: std::from_chars is not supported on MacOS < 26
199+
#if !defined(__APPLE__)
197200
T converted;
198201
auto res = std::from_chars(val.data(), val.data() + val.size(), converted);
199202
if (res.ptr == val.end() && res.ec == std::errc{}) {
@@ -211,6 +214,32 @@ public:
211214
else
212215
throw std::invalid_argument(err.str());
213216
}
217+
#else
218+
std::conditional_t<std::is_integral_v<T>, long long, long double> converted;
219+
std::size_t unconvertedPos;
220+
if constexpr (std::is_integral_v<T>) {
221+
converted = std::stoll(std::string(val), &unconvertedPos);
222+
} else {
223+
converted = std::stold(std::string(val), &unconvertedPos);
224+
}
225+
226+
const bool isOor = converted > std::numeric_limits<T>::max();
227+
if (unconvertedPos != val.size() || isOor) {
228+
std::stringstream err;
229+
err << "Failed to parse flag `" << name << "` with value `" << val << "`";
230+
if constexpr (std::is_integral_v<T>)
231+
err << " as an integer.\n";
232+
else
233+
err << " as a floating point number.\n";
234+
235+
if (isOor)
236+
throw std::out_of_range(err.str());
237+
else
238+
throw std::invalid_argument(err.str());
239+
}
240+
241+
return converted;
242+
#endif
214243
}
215244
return std::nullopt;
216245
}

0 commit comments

Comments
 (0)