mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 15:14:39 +00:00
Enable clang-tidy readability-braces-around-statements check
All tests still pass. Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
This commit is contained in:
parent
419648bf74
commit
158b8a0d2f
@ -1,7 +1,6 @@
|
|||||||
Checks:
|
Checks:
|
||||||
-*,
|
-*,
|
||||||
readability-*,
|
readability-*,
|
||||||
-readability-braces-around-statements,
|
|
||||||
-readability-container-size-empty,
|
-readability-container-size-empty,
|
||||||
-readability-else-after-return,
|
-readability-else-after-return,
|
||||||
-readability-implicit-bool-conversion,
|
-readability-implicit-bool-conversion,
|
||||||
|
@ -101,13 +101,15 @@ template <typename T> std::string repr(T const &val) {
|
|||||||
std::next(val.begin()),
|
std::next(val.begin()),
|
||||||
std::next(val.begin(), std::min<std::size_t>(size, repr_max_container_size) - 1),
|
std::next(val.begin(), std::min<std::size_t>(size, repr_max_container_size) - 1),
|
||||||
[&out](const auto &v) { out << " " << repr(v); });
|
[&out](const auto &v) { out << " " << repr(v); });
|
||||||
if (size <= repr_max_container_size)
|
if (size <= repr_max_container_size) {
|
||||||
out << " ";
|
out << " ";
|
||||||
else
|
} else {
|
||||||
out << "...";
|
out << "...";
|
||||||
}
|
}
|
||||||
if (size > 0)
|
}
|
||||||
|
if (size > 0) {
|
||||||
out << repr(*std::prev(val.end()));
|
out << repr(*std::prev(val.end()));
|
||||||
|
}
|
||||||
out << "}";
|
out << "}";
|
||||||
return out.str();
|
return out.str();
|
||||||
} else if constexpr (is_streamable_v<T>) {
|
} else if constexpr (is_streamable_v<T>) {
|
||||||
@ -197,10 +199,11 @@ inline auto do_from_chars(std::string_view s) -> T {
|
|||||||
auto [first, last] = pointer_range(s);
|
auto [first, last] = pointer_range(s);
|
||||||
auto [ptr, ec] = std::from_chars(first, last, x, Param);
|
auto [ptr, ec] = std::from_chars(first, last, x, Param);
|
||||||
if (ec == std::errc()) {
|
if (ec == std::errc()) {
|
||||||
if (ptr == last)
|
if (ptr == last) {
|
||||||
return x;
|
return x;
|
||||||
else
|
} else {
|
||||||
throw std::invalid_argument{"pattern does not match to the end"};
|
throw std::invalid_argument{"pattern does not match to the end"};
|
||||||
|
}
|
||||||
} else if (ec == std::errc::invalid_argument) {
|
} else if (ec == std::errc::invalid_argument) {
|
||||||
throw std::invalid_argument{"pattern not found"};
|
throw std::invalid_argument{"pattern not found"};
|
||||||
} else if (ec == std::errc::result_out_of_range) {
|
} else if (ec == std::errc::result_out_of_range) {
|
||||||
@ -218,22 +221,24 @@ template <class T, auto Param = 0> struct parse_number {
|
|||||||
|
|
||||||
template <class T> struct parse_number<T, 16> {
|
template <class T> struct parse_number<T, 16> {
|
||||||
auto operator()(std::string_view s) -> T {
|
auto operator()(std::string_view s) -> T {
|
||||||
if (auto [ok, rest] = consume_hex_prefix(s); ok)
|
if (auto [ok, rest] = consume_hex_prefix(s); ok) {
|
||||||
return do_from_chars<T, 16>(rest);
|
return do_from_chars<T, 16>(rest);
|
||||||
else
|
} else {
|
||||||
throw std::invalid_argument{"pattern not found"};
|
throw std::invalid_argument{"pattern not found"};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> struct parse_number<T> {
|
template <class T> struct parse_number<T> {
|
||||||
auto operator()(std::string_view s) -> T {
|
auto operator()(std::string_view s) -> T {
|
||||||
if (auto [ok, rest] = consume_hex_prefix(s); ok)
|
if (auto [ok, rest] = consume_hex_prefix(s); ok) {
|
||||||
return do_from_chars<T, 16>(rest);
|
return do_from_chars<T, 16>(rest);
|
||||||
else if (starts_with("0"sv, s))
|
} else if (starts_with("0"sv, s)) {
|
||||||
return do_from_chars<T, 8>(rest);
|
return do_from_chars<T, 8>(rest);
|
||||||
else
|
} else {
|
||||||
return do_from_chars<T, 10>(rest);
|
return do_from_chars<T, 10>(rest);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -246,18 +251,20 @@ template <> constexpr auto generic_strtod<long double> = strtold;
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
template <class T> inline auto do_strtod(std::string const &s) -> T {
|
template <class T> inline auto do_strtod(std::string const &s) -> T {
|
||||||
if (isspace(static_cast<unsigned char>(s[0])) || s[0] == '+')
|
if (isspace(static_cast<unsigned char>(s[0])) || s[0] == '+') {
|
||||||
throw std::invalid_argument{"pattern not found"};
|
throw std::invalid_argument{"pattern not found"};
|
||||||
|
}
|
||||||
|
|
||||||
auto [first, last] = pointer_range(s);
|
auto [first, last] = pointer_range(s);
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (auto x = generic_strtod<T>(first, &ptr); errno == 0) {
|
if (auto x = generic_strtod<T>(first, &ptr); errno == 0) {
|
||||||
if (ptr == last)
|
if (ptr == last) {
|
||||||
return x;
|
return x;
|
||||||
else
|
} else {
|
||||||
throw std::invalid_argument{"pattern does not match to the end"};
|
throw std::invalid_argument{"pattern does not match to the end"};
|
||||||
|
}
|
||||||
} else if (errno == ERANGE) {
|
} else if (errno == ERANGE) {
|
||||||
throw std::range_error{"not representable"};
|
throw std::range_error{"not representable"};
|
||||||
} else {
|
} else {
|
||||||
@ -267,9 +274,10 @@ template <class T> inline auto do_strtod(std::string const &s) -> T {
|
|||||||
|
|
||||||
template <class T> struct parse_number<T, chars_format::general> {
|
template <class T> struct parse_number<T, chars_format::general> {
|
||||||
auto operator()(std::string const &s) -> T {
|
auto operator()(std::string const &s) -> T {
|
||||||
if (auto r = consume_hex_prefix(s); r.is_hexadecimal)
|
if (auto r = consume_hex_prefix(s); r.is_hexadecimal) {
|
||||||
throw std::invalid_argument{
|
throw std::invalid_argument{
|
||||||
"chars_format::general does not parse hexfloat"};
|
"chars_format::general does not parse hexfloat"};
|
||||||
|
}
|
||||||
|
|
||||||
return do_strtod<T>(s);
|
return do_strtod<T>(s);
|
||||||
}
|
}
|
||||||
@ -277,8 +285,9 @@ template <class T> struct parse_number<T, chars_format::general> {
|
|||||||
|
|
||||||
template <class T> struct parse_number<T, chars_format::hex> {
|
template <class T> struct parse_number<T, chars_format::hex> {
|
||||||
auto operator()(std::string const &s) -> T {
|
auto operator()(std::string const &s) -> T {
|
||||||
if (auto r = consume_hex_prefix(s); !r.is_hexadecimal)
|
if (auto r = consume_hex_prefix(s); !r.is_hexadecimal) {
|
||||||
throw std::invalid_argument{"chars_format::hex parses hexfloat"};
|
throw std::invalid_argument{"chars_format::hex parses hexfloat"};
|
||||||
|
}
|
||||||
|
|
||||||
return do_strtod<T>(s);
|
return do_strtod<T>(s);
|
||||||
}
|
}
|
||||||
@ -286,12 +295,14 @@ template <class T> struct parse_number<T, chars_format::hex> {
|
|||||||
|
|
||||||
template <class T> struct parse_number<T, chars_format::scientific> {
|
template <class T> struct parse_number<T, chars_format::scientific> {
|
||||||
auto operator()(std::string const &s) -> T {
|
auto operator()(std::string const &s) -> T {
|
||||||
if (auto r = consume_hex_prefix(s); r.is_hexadecimal)
|
if (auto r = consume_hex_prefix(s); r.is_hexadecimal) {
|
||||||
throw std::invalid_argument{
|
throw std::invalid_argument{
|
||||||
"chars_format::scientific does not parse hexfloat"};
|
"chars_format::scientific does not parse hexfloat"};
|
||||||
if (s.find_first_of("eE") == s.npos)
|
}
|
||||||
|
if (s.find_first_of("eE") == s.npos) {
|
||||||
throw std::invalid_argument{
|
throw std::invalid_argument{
|
||||||
"chars_format::scientific requires exponent part"};
|
"chars_format::scientific requires exponent part"};
|
||||||
|
}
|
||||||
|
|
||||||
return do_strtod<T>(s);
|
return do_strtod<T>(s);
|
||||||
}
|
}
|
||||||
@ -299,12 +310,14 @@ template <class T> struct parse_number<T, chars_format::scientific> {
|
|||||||
|
|
||||||
template <class T> struct parse_number<T, chars_format::fixed> {
|
template <class T> struct parse_number<T, chars_format::fixed> {
|
||||||
auto operator()(std::string const &s) -> T {
|
auto operator()(std::string const &s) -> T {
|
||||||
if (auto r = consume_hex_prefix(s); r.is_hexadecimal)
|
if (auto r = consume_hex_prefix(s); r.is_hexadecimal) {
|
||||||
throw std::invalid_argument{
|
throw std::invalid_argument{
|
||||||
"chars_format::fixed does not parse hexfloat"};
|
"chars_format::fixed does not parse hexfloat"};
|
||||||
if (s.find_first_of("eE") != s.npos)
|
}
|
||||||
|
if (s.find_first_of("eE") != s.npos) {
|
||||||
throw std::invalid_argument{
|
throw std::invalid_argument{
|
||||||
"chars_format::fixed does not parse exponent part"};
|
"chars_format::fixed does not parse exponent part"};
|
||||||
|
}
|
||||||
|
|
||||||
return do_strtod<T>(s);
|
return do_strtod<T>(s);
|
||||||
}
|
}
|
||||||
@ -375,15 +388,16 @@ public:
|
|||||||
using action_type = std::conditional_t<
|
using action_type = std::conditional_t<
|
||||||
std::is_void_v<std::invoke_result_t<F, Args..., std::string const>>,
|
std::is_void_v<std::invoke_result_t<F, Args..., std::string const>>,
|
||||||
void_action, valued_action>;
|
void_action, valued_action>;
|
||||||
if constexpr (sizeof...(Args) == 0)
|
if constexpr (sizeof...(Args) == 0) {
|
||||||
mAction.emplace<action_type>(std::forward<F>(aAction));
|
mAction.emplace<action_type>(std::forward<F>(aAction));
|
||||||
else
|
} else {
|
||||||
mAction.emplace<action_type>(
|
mAction.emplace<action_type>(
|
||||||
[f = std::forward<F>(aAction),
|
[f = std::forward<F>(aAction),
|
||||||
tup = std::make_tuple(std::forward<Args>(aBound)...)](
|
tup = std::make_tuple(std::forward<Args>(aBound)...)](
|
||||||
std::string const &opt) mutable {
|
std::string const &opt) mutable {
|
||||||
return details::apply_plus_one(f, tup, opt);
|
return details::apply_plus_one(f, tup, opt);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,40 +414,42 @@ public:
|
|||||||
return ((c == x) || ...);
|
return ((c == x) || ...);
|
||||||
};
|
};
|
||||||
|
|
||||||
if constexpr (is_one_of(Shape, 'd') && details::standard_integer<T>)
|
if constexpr (is_one_of(Shape, 'd') && details::standard_integer<T>) {
|
||||||
action(details::parse_number<T, 10>());
|
action(details::parse_number<T, 10>());
|
||||||
else if constexpr (is_one_of(Shape, 'i') && details::standard_integer<T>)
|
} else if constexpr (is_one_of(Shape, 'i') && details::standard_integer<T>) {
|
||||||
action(details::parse_number<T>());
|
action(details::parse_number<T>());
|
||||||
else if constexpr (is_one_of(Shape, 'u') &&
|
} else if constexpr (is_one_of(Shape, 'u') &&
|
||||||
details::standard_unsigned_integer<T>)
|
details::standard_unsigned_integer<T>) {
|
||||||
action(details::parse_number<T, 10>());
|
action(details::parse_number<T, 10>());
|
||||||
else if constexpr (is_one_of(Shape, 'o') &&
|
} else if constexpr (is_one_of(Shape, 'o') &&
|
||||||
details::standard_unsigned_integer<T>)
|
details::standard_unsigned_integer<T>) {
|
||||||
action(details::parse_number<T, 8>());
|
action(details::parse_number<T, 8>());
|
||||||
else if constexpr (is_one_of(Shape, 'x', 'X') &&
|
} else if constexpr (is_one_of(Shape, 'x', 'X') &&
|
||||||
details::standard_unsigned_integer<T>)
|
details::standard_unsigned_integer<T>) {
|
||||||
action(details::parse_number<T, 16>());
|
action(details::parse_number<T, 16>());
|
||||||
else if constexpr (is_one_of(Shape, 'a', 'A') &&
|
} else if constexpr (is_one_of(Shape, 'a', 'A') &&
|
||||||
std::is_floating_point_v<T>)
|
std::is_floating_point_v<T>) {
|
||||||
action(details::parse_number<T, details::chars_format::hex>());
|
action(details::parse_number<T, details::chars_format::hex>());
|
||||||
else if constexpr (is_one_of(Shape, 'e', 'E') &&
|
} else if constexpr (is_one_of(Shape, 'e', 'E') &&
|
||||||
std::is_floating_point_v<T>)
|
std::is_floating_point_v<T>) {
|
||||||
action(details::parse_number<T, details::chars_format::scientific>());
|
action(details::parse_number<T, details::chars_format::scientific>());
|
||||||
else if constexpr (is_one_of(Shape, 'f', 'F') &&
|
} else if constexpr (is_one_of(Shape, 'f', 'F') &&
|
||||||
std::is_floating_point_v<T>)
|
std::is_floating_point_v<T>) {
|
||||||
action(details::parse_number<T, details::chars_format::fixed>());
|
action(details::parse_number<T, details::chars_format::fixed>());
|
||||||
else if constexpr (is_one_of(Shape, 'g', 'G') &&
|
} else if constexpr (is_one_of(Shape, 'g', 'G') &&
|
||||||
std::is_floating_point_v<T>)
|
std::is_floating_point_v<T>) {
|
||||||
action(details::parse_number<T, details::chars_format::general>());
|
action(details::parse_number<T, details::chars_format::general>());
|
||||||
else
|
} else {
|
||||||
static_assert(alignof(T) == 0, "No scan specification for T");
|
static_assert(alignof(T) == 0, "No scan specification for T");
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Argument &nargs(int aNumArgs) {
|
Argument &nargs(int aNumArgs) {
|
||||||
if (aNumArgs < 0)
|
if (aNumArgs < 0) {
|
||||||
throw std::logic_error("Number of arguments must be non-negative");
|
throw std::logic_error("Number of arguments must be non-negative");
|
||||||
|
}
|
||||||
mNumArgs = aNumArgs;
|
mNumArgs = aNumArgs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -471,10 +487,11 @@ public:
|
|||||||
void operator()(void_action &f) {
|
void operator()(void_action &f) {
|
||||||
std::for_each(first, last, f);
|
std::for_each(first, last, f);
|
||||||
if (!self.mDefaultValue.has_value()) {
|
if (!self.mDefaultValue.has_value()) {
|
||||||
if (auto expected = self.maybe_nargs())
|
if (auto expected = self.maybe_nargs()) {
|
||||||
self.mValues.resize(*expected);
|
self.mValues.resize(*expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Iterator first, last;
|
Iterator first, last;
|
||||||
Argument &self;
|
Argument &self;
|
||||||
@ -517,8 +534,9 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
if (mValues.size() != expected && !mDefaultValue.has_value()) {
|
if (mValues.size() != expected && !mDefaultValue.has_value()) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
if (!mUsedName.empty())
|
if (!mUsedName.empty()) {
|
||||||
stream << mUsedName << ": ";
|
stream << mUsedName << ": ";
|
||||||
|
}
|
||||||
stream << *expected << " argument(s) expected. " << mValues.size()
|
stream << *expected << " argument(s) expected. " << mValues.size()
|
||||||
<< " provided.";
|
<< " provided.";
|
||||||
throw std::runtime_error(stream.str());
|
throw std::runtime_error(stream.str());
|
||||||
@ -528,11 +546,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto maybe_nargs() const -> std::optional<std::size_t> {
|
auto maybe_nargs() const -> std::optional<std::size_t> {
|
||||||
if (mNumArgs < 0)
|
if (mNumArgs < 0) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
else
|
} else {
|
||||||
return static_cast<std::size_t>(mNumArgs);
|
return static_cast<std::size_t>(mNumArgs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t get_arguments_length() const {
|
std::size_t get_arguments_length() const {
|
||||||
return std::accumulate(std::begin(mNames), std::end(mNames), std::size_t(0),
|
return std::accumulate(std::begin(mNames), std::end(mNames), std::size_t(0),
|
||||||
@ -549,12 +568,14 @@ public:
|
|||||||
std::ostream_iterator<std::string>(nameStream, " "));
|
std::ostream_iterator<std::string>(nameStream, " "));
|
||||||
stream << nameStream.str() << "\t" << argument.mHelp;
|
stream << nameStream.str() << "\t" << argument.mHelp;
|
||||||
if (argument.mDefaultValue.has_value()) {
|
if (argument.mDefaultValue.has_value()) {
|
||||||
if (!argument.mHelp.empty())
|
if (!argument.mHelp.empty()) {
|
||||||
stream << " ";
|
stream << " ";
|
||||||
|
}
|
||||||
stream << "[default: " << argument.mDefaultValueRepr << "]";
|
stream << "[default: " << argument.mDefaultValueRepr << "]";
|
||||||
} else if (argument.mIsRequired) {
|
} else if (argument.mIsRequired) {
|
||||||
if (!argument.mHelp.empty())
|
if (!argument.mHelp.empty()) {
|
||||||
stream << " ";
|
stream << " ";
|
||||||
|
}
|
||||||
stream << "[required]";
|
stream << "[required]";
|
||||||
}
|
}
|
||||||
stream << "\n";
|
stream << "\n";
|
||||||
@ -586,11 +607,12 @@ private:
|
|||||||
static constexpr int eof = std::char_traits<char>::eof();
|
static constexpr int eof = std::char_traits<char>::eof();
|
||||||
|
|
||||||
static auto lookahead(std::string_view s) -> int {
|
static auto lookahead(std::string_view s) -> int {
|
||||||
if (s.empty())
|
if (s.empty()) {
|
||||||
return eof;
|
return eof;
|
||||||
else
|
} else {
|
||||||
return static_cast<int>(static_cast<unsigned char>(s[0]));
|
return static_cast<int>(static_cast<unsigned char>(s[0]));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decimal-literal:
|
* decimal-literal:
|
||||||
@ -648,11 +670,12 @@ private:
|
|||||||
switch (lookahead(s)) {
|
switch (lookahead(s)) {
|
||||||
case '0': {
|
case '0': {
|
||||||
s.remove_prefix(1);
|
s.remove_prefix(1);
|
||||||
if (s.empty())
|
if (s.empty()) {
|
||||||
return true;
|
return true;
|
||||||
else
|
} else {
|
||||||
goto integer_part;
|
goto integer_part;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
case '3':
|
case '3':
|
||||||
@ -663,11 +686,12 @@ private:
|
|||||||
case '8':
|
case '8':
|
||||||
case '9': {
|
case '9': {
|
||||||
s = consume_digits(s);
|
s = consume_digits(s);
|
||||||
if (s.empty())
|
if (s.empty()) {
|
||||||
return true;
|
return true;
|
||||||
else
|
} else {
|
||||||
goto integer_part_consumed;
|
goto integer_part_consumed;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case '.': {
|
case '.': {
|
||||||
s.remove_prefix(1);
|
s.remove_prefix(1);
|
||||||
goto post_decimal_point;
|
goto post_decimal_point;
|
||||||
@ -682,11 +706,12 @@ private:
|
|||||||
switch (lookahead(s)) {
|
switch (lookahead(s)) {
|
||||||
case '.': {
|
case '.': {
|
||||||
s.remove_prefix(1);
|
s.remove_prefix(1);
|
||||||
if (is_digit(lookahead(s)))
|
if (is_digit(lookahead(s))) {
|
||||||
goto post_decimal_point;
|
goto post_decimal_point;
|
||||||
else
|
} else {
|
||||||
goto exponent_part_opt;
|
goto exponent_part_opt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E': {
|
case 'E': {
|
||||||
s.remove_prefix(1);
|
s.remove_prefix(1);
|
||||||
@ -748,11 +773,12 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
case '-': {
|
case '-': {
|
||||||
aName.remove_prefix(1);
|
aName.remove_prefix(1);
|
||||||
if (aName.empty())
|
if (aName.empty()) {
|
||||||
return true;
|
return true;
|
||||||
else
|
} else {
|
||||||
return is_decimal_literal(aName);
|
return is_decimal_literal(aName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -764,11 +790,12 @@ private:
|
|||||||
*/
|
*/
|
||||||
template <typename T> T get() const {
|
template <typename T> T get() const {
|
||||||
if (!mValues.empty()) {
|
if (!mValues.empty()) {
|
||||||
if constexpr (details::is_container_v<T>)
|
if constexpr (details::is_container_v<T>) {
|
||||||
return any_cast_container<T>(mValues);
|
return any_cast_container<T>(mValues);
|
||||||
else
|
} else {
|
||||||
return std::any_cast<T>(mValues.front());
|
return std::any_cast<T>(mValues.front());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (mDefaultValue.has_value()) {
|
if (mDefaultValue.has_value()) {
|
||||||
return std::any_cast<T>(mDefaultValue);
|
return std::any_cast<T>(mDefaultValue);
|
||||||
}
|
}
|
||||||
@ -781,16 +808,18 @@ private:
|
|||||||
* @returns The stored value if any, std::nullopt otherwise.
|
* @returns The stored value if any, std::nullopt otherwise.
|
||||||
*/
|
*/
|
||||||
template <typename T> auto present() const -> std::optional<T> {
|
template <typename T> auto present() const -> std::optional<T> {
|
||||||
if (mDefaultValue.has_value())
|
if (mDefaultValue.has_value()) {
|
||||||
throw std::logic_error("Argument with default value always presents");
|
throw std::logic_error("Argument with default value always presents");
|
||||||
|
}
|
||||||
|
|
||||||
if (mValues.empty())
|
if (mValues.empty()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
else if constexpr (details::is_container_v<T>)
|
} else if constexpr (details::is_container_v<T>) {
|
||||||
return any_cast_container<T>(mValues);
|
return any_cast_container<T>(mValues);
|
||||||
else
|
} else {
|
||||||
return std::any_cast<T>(mValues.front());
|
return std::any_cast<T>(mValues.front());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static auto any_cast_container(const std::vector<std::any> &aOperand) -> T {
|
static auto any_cast_container(const std::vector<std::any> &aOperand) -> T {
|
||||||
@ -864,12 +893,14 @@ public:
|
|||||||
mPositionalArguments(other.mPositionalArguments),
|
mPositionalArguments(other.mPositionalArguments),
|
||||||
mOptionalArguments(other.mOptionalArguments) {
|
mOptionalArguments(other.mOptionalArguments) {
|
||||||
for (auto it = std::begin(mPositionalArguments); it != std::end(mPositionalArguments);
|
for (auto it = std::begin(mPositionalArguments); it != std::end(mPositionalArguments);
|
||||||
++it)
|
++it) {
|
||||||
index_argument(it);
|
index_argument(it);
|
||||||
|
}
|
||||||
for (auto it = std::begin(mOptionalArguments); it != std::end(mOptionalArguments);
|
for (auto it = std::begin(mOptionalArguments); it != std::end(mOptionalArguments);
|
||||||
++it)
|
++it) {
|
||||||
index_argument(it);
|
index_argument(it);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ArgumentParser &operator=(const ArgumentParser &other) {
|
ArgumentParser &operator=(const ArgumentParser &other) {
|
||||||
auto tmp = other;
|
auto tmp = other;
|
||||||
@ -884,9 +915,10 @@ public:
|
|||||||
auto tArgument = mOptionalArguments.emplace(cend(mOptionalArguments),
|
auto tArgument = mOptionalArguments.emplace(cend(mOptionalArguments),
|
||||||
array_of_sv{Fargs...});
|
array_of_sv{Fargs...});
|
||||||
|
|
||||||
if (!tArgument->mIsOptional)
|
if (!tArgument->mIsOptional) {
|
||||||
mPositionalArguments.splice(cend(mPositionalArguments),
|
mPositionalArguments.splice(cend(mPositionalArguments),
|
||||||
mOptionalArguments, tArgument);
|
mOptionalArguments, tArgument);
|
||||||
|
}
|
||||||
|
|
||||||
index_argument(tArgument);
|
index_argument(tArgument);
|
||||||
return *tArgument;
|
return *tArgument;
|
||||||
@ -1011,28 +1043,32 @@ public:
|
|||||||
}
|
}
|
||||||
stream << "\n\n";
|
stream << "\n\n";
|
||||||
|
|
||||||
if (!parser.mDescription.empty())
|
if (!parser.mDescription.empty()) {
|
||||||
stream << parser.mDescription << "\n\n";
|
stream << parser.mDescription << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (!parser.mPositionalArguments.empty())
|
if (!parser.mPositionalArguments.empty()) {
|
||||||
stream << "Positional arguments:\n";
|
stream << "Positional arguments:\n";
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &mPositionalArgument : parser.mPositionalArguments) {
|
for (const auto &mPositionalArgument : parser.mPositionalArguments) {
|
||||||
stream.width(tLongestArgumentLength);
|
stream.width(tLongestArgumentLength);
|
||||||
stream << mPositionalArgument;
|
stream << mPositionalArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parser.mOptionalArguments.empty())
|
if (!parser.mOptionalArguments.empty()) {
|
||||||
stream << (parser.mPositionalArguments.empty() ? "" : "\n")
|
stream << (parser.mPositionalArguments.empty() ? "" : "\n")
|
||||||
<< "Optional arguments:\n";
|
<< "Optional arguments:\n";
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &mOptionalArgument : parser.mOptionalArguments) {
|
for (const auto &mOptionalArgument : parser.mOptionalArguments) {
|
||||||
stream.width(tLongestArgumentLength);
|
stream.width(tLongestArgumentLength);
|
||||||
stream << mOptionalArgument;
|
stream << mOptionalArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parser.mEpilog.empty())
|
if (!parser.mEpilog.empty()) {
|
||||||
stream << parser.mEpilog << "\n\n";
|
stream << parser.mEpilog << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
@ -1114,8 +1150,9 @@ private:
|
|||||||
|
|
||||||
// Used by print_help.
|
// Used by print_help.
|
||||||
std::size_t get_length_of_longest_argument() const {
|
std::size_t get_length_of_longest_argument() const {
|
||||||
if (mArgumentMap.empty())
|
if (mArgumentMap.empty()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
std::vector<std::size_t> argumentLengths(mArgumentMap.size());
|
std::vector<std::size_t> argumentLengths(mArgumentMap.size());
|
||||||
std::transform(std::begin(mArgumentMap), std::end(mArgumentMap),
|
std::transform(std::begin(mArgumentMap), std::end(mArgumentMap),
|
||||||
std::begin(argumentLengths), [](const auto &argPair) {
|
std::begin(argumentLengths), [](const auto &argPair) {
|
||||||
@ -1129,9 +1166,10 @@ private:
|
|||||||
using list_iterator = std::list<Argument>::iterator;
|
using list_iterator = std::list<Argument>::iterator;
|
||||||
|
|
||||||
void index_argument(list_iterator argIt) {
|
void index_argument(list_iterator argIt) {
|
||||||
for (auto &mName : std::as_const(argIt->mNames))
|
for (auto &mName : std::as_const(argIt->mNames)) {
|
||||||
mArgumentMap.insert_or_assign(mName, argIt);
|
mArgumentMap.insert_or_assign(mName, argIt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string mProgramName;
|
std::string mProgramName;
|
||||||
std::string mVersion;
|
std::string mVersion;
|
||||||
|
Loading…
Reference in New Issue
Block a user