From 53dd85db961f36ae8d83bdcc642a60f68fbdb590 Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Tue, 16 Sep 2025 23:05:29 +0200 Subject: [PATCH 1/4] Add definition of Argument class --- include/argparse.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/argparse.hpp b/include/argparse.hpp index c936b83..74da809 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -565,6 +565,25 @@ namespace argparse } }; + class Argument + { + public: + virtual auto parse_args(tokens & args) -> void = 0; + virtual auto is_positional() const -> bool = 0; + virtual auto is_present() const -> bool = 0; + virtual auto is_required() const -> bool = 0; + virtual auto is_mutually_exclusive() const -> bool = 0; + virtual auto is_mutually_exclusive_with(Argument const & other) const -> bool = 0; + virtual auto expects_argument() const -> bool = 0; + virtual auto has_value() const -> bool = 0; + virtual auto get_value() const -> std::any = 0; + virtual auto get_dest_name() const -> std::string = 0; + virtual auto get_joined_names() const -> std::string = 0; + + protected: + ~Argument() = default; + }; + class Formattable { public: From e9d4e48bfa4753219c4422e731cd008e7b1fed4c Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Tue, 16 Sep 2025 23:19:28 +0200 Subject: [PATCH 2/4] Use Argument class --- include/argparse.hpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index 74da809..0900f41 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -423,14 +423,15 @@ namespace argparse auto check_excluded_arguments() const -> void { - auto const filter = [](auto const & arg) { return arg->is_present() && arg->is_mutually_exclusive(); }; - for (auto const & arg1 : m_arguments | std::views::filter(filter)) + auto const transform = [](auto const & up) -> Argument const & { return *up; }; + auto const filter = [](auto const & arg) { return arg.is_present() && arg.is_mutually_exclusive(); }; + for (auto const & arg1 : m_arguments | std::views::transform(transform) | std::views::filter(filter)) { - for (auto const & arg2 : m_arguments | std::views::filter(filter)) + for (auto const & arg2 : m_arguments | std::views::transform(transform) | std::views::filter(filter)) { - if ((arg2 != arg1) && arg2->is_mutually_exclusive_with(*arg1)) + if ((&arg2 != &arg1) && arg2.is_mutually_exclusive_with(arg1)) { - throw parsing_error(std::format("argument {}: not allowed with argument {}", arg2->get_joined_names(), arg1->get_joined_names())); + throw parsing_error(std::format("argument {}: not allowed with argument {}", arg2.get_joined_names(), arg1.get_joined_names())); } } } @@ -696,7 +697,7 @@ namespace argparse Options m_options; }; - class ArgumentCommon : public Formattable, public OptionsHolder + class ArgumentCommon : public Argument, public Formattable, public OptionsHolder { public: explicit ArgumentCommon(Options options) @@ -754,6 +755,11 @@ namespace argparse return get_mutually_exclusive_group() != nullptr; } + auto is_mutually_exclusive_with(Argument const & other) const -> bool + { + return (get_mutually_exclusive_group() != nullptr) && (get_mutually_exclusive_group() == static_cast(other).get_mutually_exclusive_group()); + } + auto is_mutually_exclusive_with(Formattable const & other) const -> bool { return (get_mutually_exclusive_group() != nullptr) && (get_mutually_exclusive_group() == static_cast(other).get_mutually_exclusive_group()); From e4a7635fa2d25028a9ce532e108f88f219df01fe Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Wed, 17 Sep 2025 00:25:26 +0200 Subject: [PATCH 3/4] Use Argument class --- include/argparse.hpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index 0900f41..a8adadd 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -380,25 +380,28 @@ namespace argparse auto parse_optional_arguments(tokens & args) -> void { - for (auto const & arg : m_arguments - | std::views::filter([](auto const & arg) { return !arg->is_positional() && arg->expects_argument(); })) + for (auto & arg : m_arguments + | std::views::transform([](auto const & up) -> Argument & { return *up; }) + | std::views::filter([](auto const & arg) { return !arg.is_positional() && arg.expects_argument(); })) { - arg->parse_args(args); + arg.parse_args(args); } - for (auto const & arg : m_arguments - | std::views::filter([](auto const & arg) { return !arg->is_positional() && !arg->expects_argument(); })) + for (auto & arg : m_arguments + | std::views::transform([](auto const & up) -> Argument & { return *up; }) + | std::views::filter([](auto const & arg) { return !arg.is_positional() && !arg.expects_argument(); })) { - arg->parse_args(args); + arg.parse_args(args); } } auto parse_positional_arguments(tokens & args) -> void { - for (auto const & arg : m_arguments - | std::views::filter(&ArgumentCommon::is_positional)) + for (auto & arg : m_arguments + | std::views::transform([](auto const & up) -> Argument & { return *up; }) + | std::views::filter(&Argument::is_positional)) { - arg->parse_args(args); + arg.parse_args(args); } } @@ -442,15 +445,16 @@ namespace argparse auto error_message = optstring(); for (auto const & arg : m_arguments - | std::views::filter([](auto const & arg) { return arg->is_required() && !arg->has_value(); })) + | std::views::transform([](auto const & up) -> Argument & { return *up; }) + | std::views::filter([](auto const & arg) { return arg.is_required() && !arg.has_value(); })) { if (!error_message) { - error_message = "the following arguments are required: " + arg->get_joined_names(); + error_message = "the following arguments are required: " + arg.get_joined_names(); } else { - *error_message += " " + arg->get_joined_names(); + *error_message += " " + arg.get_joined_names(); } } @@ -464,9 +468,10 @@ namespace argparse { auto result = Parameters(); - for (auto const & arg : m_arguments) + for (auto const & arg : m_arguments + | std::views::transform([](auto const & up) -> Argument & { return *up; })) { - result.insert(arg->get_dest_name(), arg->get_value()); + result.insert(arg.get_dest_name(), arg.get_value()); } return result; From 81ac430641e2681b3f1b9976851cade8917be9f7 Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Wed, 17 Sep 2025 00:26:28 +0200 Subject: [PATCH 4/4] Remove function redeclarations --- include/argparse.hpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index a8adadd..e7446aa 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -711,15 +711,6 @@ namespace argparse } virtual ~ArgumentCommon() = default; - virtual auto parse_args(tokens & args) -> void = 0; - virtual auto get_dest_name() const -> std::string = 0; - virtual auto get_metavar_name() const -> std::string = 0; - virtual auto has_value() const -> bool = 0; - virtual auto get_value() const -> std::any = 0; - virtual auto is_required() const -> bool = 0; - virtual auto is_positional() const -> bool = 0; - virtual auto is_present() const -> bool = 0; - auto get_name() const -> std::string const & { return get_names().front();