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(R__MACOSX)
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