@@ -861,7 +861,7 @@ bool integral_conversion(const std::string &input, T &output) noexcept {
861
861
if (input.empty () || input.front () == ' -' ) {
862
862
return false ;
863
863
}
864
- char *val = nullptr ;
864
+ char *val{ nullptr } ;
865
865
errno = 0 ;
866
866
std::uint64_t output_ll = std::strtoull (input.c_str (), &val, 0 );
867
867
if (errno == ERANGE) {
@@ -904,8 +904,8 @@ bool integral_conversion(const std::string &input, T &output) noexcept {
904
904
return false ;
905
905
}
906
906
907
- // / Convert a flag into an integer value typically binary flags
908
- inline std::int64_t to_flag_value (std::string val) {
907
+ // / Convert a flag into an integer value typically binary flags sets errno to nonzero if conversion failed
908
+ inline std::int64_t to_flag_value (std::string val) noexcept {
909
909
static const std::string trueString (" true" );
910
910
static const std::string falseString (" false" );
911
911
if (val == trueString) {
@@ -933,7 +933,8 @@ inline std::int64_t to_flag_value(std::string val) {
933
933
ret = 1 ;
934
934
break ;
935
935
default :
936
- throw std::invalid_argument (" unrecognized character" );
936
+ errno = EINVAL;
937
+ return -1 ;
937
938
}
938
939
return ret;
939
940
}
@@ -942,7 +943,11 @@ inline std::int64_t to_flag_value(std::string val) {
942
943
} else if (val == falseString || val == " off" || val == " no" || val == " disable" ) {
943
944
ret = -1 ;
944
945
} else {
945
- ret = std::stoll (val);
946
+ char *loc_ptr{nullptr };
947
+ ret = std::strtoll (val.c_str (), &loc_ptr, 0 );
948
+ if (loc_ptr != (val.c_str () + val.size ()) && errno == 0 ) {
949
+ errno = EINVAL;
950
+ }
946
951
}
947
952
return ret;
948
953
}
@@ -971,18 +976,16 @@ bool lexical_cast(const std::string &input, T &output) {
971
976
template <typename T,
972
977
enable_if_t <classify_object<T>::value == object_category::boolean_value, detail::enabler> = detail::dummy>
973
978
bool lexical_cast (const std::string &input, T &output) {
974
- try {
975
- auto out = to_flag_value (input);
979
+ errno = 0 ;
980
+ auto out = to_flag_value (input);
981
+ if (errno == 0 ) {
976
982
output = (out > 0 );
977
- return true ;
978
- } catch (const std::invalid_argument &) {
979
- return false ;
980
- } catch (const std::out_of_range &) {
981
- // if the number is out of the range of a 64 bit value then it is still a number and for this purpose is still
982
- // valid all we care about the sign
983
+ } else if (errno == ERANGE) {
983
984
output = (input[0 ] != ' -' );
984
- return true ;
985
+ } else {
986
+ return false ;
985
987
}
988
+ return true ;
986
989
}
987
990
988
991
// / Floats
@@ -1638,12 +1641,13 @@ inline std::string sum_string_vector(const std::vector<std::string> &values) {
1638
1641
double tv{0.0 };
1639
1642
auto comp = lexical_cast (arg, tv);
1640
1643
if (!comp) {
1641
- try {
1642
- tv = static_cast < double >( detail::to_flag_value (arg) );
1643
- } catch ( const std::exception &) {
1644
- fail = true ;
1644
+ errno = 0 ;
1645
+ auto fv = detail::to_flag_value (arg);
1646
+ fail = (errno != 0 );
1647
+ if ( fail) {
1645
1648
break ;
1646
1649
}
1650
+ tv = static_cast <double >(fv);
1647
1651
}
1648
1652
val += tv;
1649
1653
}
0 commit comments