mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-03 22:54:39 +00:00
Enable clang-tidy readability-else-after-return check
A common pattern in the previous code was goto/return/throw if a condition is true, else goto/return/throw something different. The new pattern uses the fact that the second goto/return/throw is only reachable when the first goto/return/throw is not called. Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
This commit is contained in:
parent
3c317ddd2d
commit
d0a492ccba
@ -3,7 +3,6 @@ Checks:
|
||||
clang-analyzer-*,
|
||||
cppcoreguidelines-special-member-functions,
|
||||
readability-*,
|
||||
-readability-else-after-return,
|
||||
-readability-function-cognitive-complexity,
|
||||
|
||||
CheckOptions:
|
||||
|
@ -192,9 +192,8 @@ constexpr auto consume_hex_prefix(std::string_view s)
|
||||
if (starts_with("0x"sv, s) || starts_with("0X"sv, s)) {
|
||||
s.remove_prefix(2);
|
||||
return {true, s};
|
||||
} else {
|
||||
return {false, s};
|
||||
}
|
||||
return {false, s};
|
||||
}
|
||||
|
||||
template <class T, auto Param>
|
||||
@ -205,16 +204,16 @@ inline auto do_from_chars(std::string_view s) -> T {
|
||||
if (ec == std::errc()) {
|
||||
if (ptr == last) {
|
||||
return x;
|
||||
} else {
|
||||
}
|
||||
throw std::invalid_argument{"pattern does not match to the end"};
|
||||
}
|
||||
} else if (ec == std::errc::invalid_argument) {
|
||||
if (ec == std::errc::invalid_argument) {
|
||||
throw std::invalid_argument{"pattern not found"};
|
||||
} else if (ec == std::errc::result_out_of_range) {
|
||||
throw std::range_error{"not representable"};
|
||||
} else {
|
||||
return x; // unreachable
|
||||
}
|
||||
if (ec == std::errc::result_out_of_range) {
|
||||
throw std::range_error{"not representable"};
|
||||
}
|
||||
return x; // unreachable
|
||||
}
|
||||
|
||||
template <class T, auto Param = 0> struct parse_number {
|
||||
@ -227,21 +226,21 @@ template <class T> struct parse_number<T, radix_16> {
|
||||
auto operator()(std::string_view s) -> T {
|
||||
if (auto [ok, rest] = consume_hex_prefix(s); ok) {
|
||||
return do_from_chars<T, radix_16>(rest);
|
||||
} else {
|
||||
throw std::invalid_argument{"pattern not found"};
|
||||
}
|
||||
throw std::invalid_argument{"pattern not found"};
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> struct parse_number<T> {
|
||||
auto operator()(std::string_view s) -> T {
|
||||
if (auto [ok, rest] = consume_hex_prefix(s); ok) {
|
||||
auto [ok, rest] = consume_hex_prefix(s);
|
||||
if (ok) {
|
||||
return do_from_chars<T, radix_16>(rest);
|
||||
} else if (starts_with("0"sv, s)) {
|
||||
return do_from_chars<T, radix_8>(rest);
|
||||
} else {
|
||||
return do_from_chars<T, radix_10>(rest);
|
||||
}
|
||||
if (starts_with("0"sv, s)) {
|
||||
return do_from_chars<T, radix_8>(rest);
|
||||
}
|
||||
return do_from_chars<T, radix_10>(rest);
|
||||
}
|
||||
};
|
||||
|
||||
@ -263,17 +262,17 @@ template <class T> inline auto do_strtod(std::string const &s) -> T {
|
||||
char *ptr;
|
||||
|
||||
errno = 0;
|
||||
if (auto x = generic_strtod<T>(first, &ptr); errno == 0) {
|
||||
auto x = generic_strtod<T>(first, &ptr);
|
||||
if (errno == 0) {
|
||||
if (ptr == last) {
|
||||
return x;
|
||||
} else {
|
||||
}
|
||||
throw std::invalid_argument{"pattern does not match to the end"};
|
||||
}
|
||||
} else if (errno == ERANGE) {
|
||||
if (errno == ERANGE) {
|
||||
throw std::range_error{"not representable"};
|
||||
} else {
|
||||
return x; // unreachable
|
||||
}
|
||||
return x; // unreachable
|
||||
}
|
||||
|
||||
template <class T> struct parse_number<T, chars_format::general> {
|
||||
@ -478,7 +477,8 @@ public:
|
||||
mValues.emplace_back(mImplicitValue);
|
||||
std::visit([](const auto &aAction) { aAction({}); }, mAction);
|
||||
return start;
|
||||
} else if (mNumArgs <= std::distance(start, end)) {
|
||||
}
|
||||
if (mNumArgs <= std::distance(start, end)) {
|
||||
if (auto expected = maybe_nargs()) {
|
||||
end = std::next(start, *expected);
|
||||
if (std::any_of(start, end, Argument::is_optional)) {
|
||||
@ -505,13 +505,13 @@ public:
|
||||
};
|
||||
std::visit(action_apply{start, end, *this}, mAction);
|
||||
return end;
|
||||
} else if (mDefaultValue.has_value()) {
|
||||
}
|
||||
if (mDefaultValue.has_value()) {
|
||||
return start;
|
||||
} else {
|
||||
}
|
||||
throw std::runtime_error("Too few arguments for '" +
|
||||
std::string(mUsedName) + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @throws std::runtime_error if argument values are not valid
|
||||
@ -525,7 +525,7 @@ public:
|
||||
stream << mUsedName << ": expected " << *expected << " argument(s). "
|
||||
<< mValues.size() << " provided.";
|
||||
throw std::runtime_error(stream.str());
|
||||
} else {
|
||||
}
|
||||
// TODO: check if an implicit value was programmed for this argument
|
||||
if (!mIsUsed && !mDefaultValue.has_value() && mIsRequired) {
|
||||
std::stringstream stream;
|
||||
@ -537,9 +537,7 @@ public:
|
||||
stream << mUsedName << ": no value provided.";
|
||||
throw std::runtime_error(stream.str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mValues.size() != expected && !mDefaultValue.has_value()) {
|
||||
} else if (mValues.size() != expected && !mDefaultValue.has_value()) {
|
||||
std::stringstream stream;
|
||||
if (!mUsedName.empty()) {
|
||||
stream << mUsedName << ": ";
|
||||
@ -550,14 +548,12 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto maybe_nargs() const -> std::optional<std::size_t> {
|
||||
if (mNumArgs < 0) {
|
||||
return std::nullopt;
|
||||
} else {
|
||||
return static_cast<std::size_t>(mNumArgs);
|
||||
}
|
||||
return static_cast<std::size_t>(mNumArgs);
|
||||
}
|
||||
|
||||
std::size_t get_arguments_length() const {
|
||||
@ -616,9 +612,8 @@ private:
|
||||
static auto lookahead(std::string_view s) -> int {
|
||||
if (s.empty()) {
|
||||
return eof;
|
||||
} else {
|
||||
return static_cast<int>(static_cast<unsigned char>(s[0]));
|
||||
}
|
||||
return static_cast<int>(static_cast<unsigned char>(s[0]));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -680,9 +675,8 @@ private:
|
||||
s.remove_prefix(1);
|
||||
if (s.empty()) {
|
||||
return true;
|
||||
} else {
|
||||
goto integer_part;
|
||||
}
|
||||
goto integer_part;
|
||||
}
|
||||
case '1':
|
||||
case '2':
|
||||
@ -696,9 +690,8 @@ private:
|
||||
s = consume_digits(s);
|
||||
if (s.empty()) {
|
||||
return true;
|
||||
} else {
|
||||
goto integer_part_consumed;
|
||||
}
|
||||
goto integer_part_consumed;
|
||||
}
|
||||
case '.': {
|
||||
s.remove_prefix(1);
|
||||
@ -733,9 +726,8 @@ private:
|
||||
if (is_digit(lookahead(s))) {
|
||||
s = consume_digits(s);
|
||||
goto exponent_part_opt;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
exponent_part_opt:
|
||||
switch (lookahead(s)) {
|
||||
@ -759,9 +751,8 @@ private:
|
||||
if (is_digit(lookahead(s))) {
|
||||
s = consume_digits(s);
|
||||
return s.empty();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_optional(std::string_view aName) {
|
||||
@ -783,9 +774,8 @@ private:
|
||||
aName.remove_prefix(1);
|
||||
if (aName.empty()) {
|
||||
return true;
|
||||
} else {
|
||||
return is_decimal_literal(aName);
|
||||
}
|
||||
return is_decimal_literal(aName);
|
||||
}
|
||||
default:
|
||||
return true;
|
||||
@ -819,14 +809,13 @@ private:
|
||||
if (mDefaultValue.has_value()) {
|
||||
throw std::logic_error("Argument with default value always presents");
|
||||
}
|
||||
|
||||
if (mValues.empty()) {
|
||||
return std::nullopt;
|
||||
} else if constexpr (details::is_container_v<T>) {
|
||||
return any_cast_container<T>(mValues);
|
||||
} else {
|
||||
return std::any_cast<T>(mValues.front());
|
||||
}
|
||||
if constexpr (details::is_container_v<T>) {
|
||||
return any_cast_container<T>(mValues);
|
||||
}
|
||||
return std::any_cast<T>(mValues.front());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
Loading…
Reference in New Issue
Block a user