From 6ac10dda3385d9e24ac94501ec265a649a02fe34 Mon Sep 17 00:00:00 2001 From: killua Date: Sun, 15 Mar 2026 23:38:08 +0400 Subject: [PATCH] chore: clean up c++20/23 features to move to 17. --- src/headers/parser/parser_v2.hpp | 402 +++++++++++++++---------------- 1 file changed, 198 insertions(+), 204 deletions(-) diff --git a/src/headers/parser/parser_v2.hpp b/src/headers/parser/parser_v2.hpp index c0d7b6a..99fcef1 100644 --- a/src/headers/parser/parser_v2.hpp +++ b/src/headers/parser/parser_v2.hpp @@ -1,10 +1,9 @@ -#pragma once +#pragma once #include +#include #include -#include #include #include -#include #include #include #include @@ -15,235 +14,230 @@ #include namespace argument_parser::v2 { - namespace internal { - static inline fake_parser fake_parser{}; - } + namespace internal { + static inline fake_parser fake_parser{}; + } - enum class add_argument_flags { - ShortArgument, - LongArgument, - HelpText, - Action, - Required - }; + enum class add_argument_flags { ShortArgument, LongArgument, HelpText, Action, Required }; - namespace flags { - constexpr static inline add_argument_flags ShortArgument = add_argument_flags::ShortArgument; - constexpr static inline add_argument_flags LongArgument = add_argument_flags::LongArgument; - constexpr static inline add_argument_flags HelpText = add_argument_flags::HelpText; - constexpr static inline add_argument_flags Action = add_argument_flags::Action; - constexpr static inline add_argument_flags Required = add_argument_flags::Required; - } + namespace flags { + constexpr static inline add_argument_flags ShortArgument = add_argument_flags::ShortArgument; + constexpr static inline add_argument_flags LongArgument = add_argument_flags::LongArgument; + constexpr static inline add_argument_flags HelpText = add_argument_flags::HelpText; + constexpr static inline add_argument_flags Action = add_argument_flags::Action; + constexpr static inline add_argument_flags Required = add_argument_flags::Required; + } // namespace flags - class base_parser : private argument_parser::base_parser { - public: - template - using typed_flag_value = std::variant, bool>; - using non_typed_flag_value = std::variant; + class base_parser : private argument_parser::base_parser { + public: + template using typed_flag_value = std::variant, bool>; + using non_typed_flag_value = std::variant; - template - using typed_argument_pair = std::pair>; - using non_typed_argument_pair = std::pair; + template using typed_argument_pair = std::pair>; + using non_typed_argument_pair = std::pair; - template - void add_argument(std::unordered_map> const& argument_pairs) { - std::unordered_map found_params {{ - extended_add_argument_flags::IsTyped, true - }}; + template + void add_argument(std::unordered_map> const &argument_pairs) { + std::unordered_map found_params{ + {extended_add_argument_flags::IsTyped, true}}; - std::string short_arg, long_arg, help_text; - std::unique_ptr action; - bool required = false; + std::string short_arg, long_arg, help_text; + std::unique_ptr action; + bool required = false; - if (argument_pairs.contains(add_argument_flags::ShortArgument)) { - found_params[extended_add_argument_flags::ShortArgument] = true; - short_arg = get_or_throw(argument_pairs.at(add_argument_flags::ShortArgument), "short"); - } - if (argument_pairs.contains(add_argument_flags::LongArgument)) { - found_params[extended_add_argument_flags::LongArgument] = true; - long_arg = get_or_throw(argument_pairs.at(add_argument_flags::LongArgument), "long"); - if (short_arg.empty()) short_arg = long_arg; - } else { - if (!short_arg.empty()) long_arg = short_arg; - } + if (argument_pairs.contains(add_argument_flags::ShortArgument)) { + found_params[extended_add_argument_flags::ShortArgument] = true; + short_arg = get_or_throw(argument_pairs.at(add_argument_flags::ShortArgument), "short"); + } + if (argument_pairs.contains(add_argument_flags::LongArgument)) { + found_params[extended_add_argument_flags::LongArgument] = true; + long_arg = get_or_throw(argument_pairs.at(add_argument_flags::LongArgument), "long"); + if (short_arg.empty()) + short_arg = long_arg; + } else { + if (!short_arg.empty()) + long_arg = short_arg; + } - if (argument_pairs.contains(add_argument_flags::Action)) { - found_params[extended_add_argument_flags::Action] = true; - action = get_or_throw>(argument_pairs.at(add_argument_flags::Action), "action").clone(); - } - if (argument_pairs.contains(add_argument_flags::HelpText)) { - help_text = get_or_throw(argument_pairs.at(add_argument_flags::HelpText), "help"); - } else { - help_text = short_arg + ", " + long_arg; - } - if (argument_pairs.contains(add_argument_flags::Required) && get_or_throw(argument_pairs.at(add_argument_flags::Required), "required")) { - required = true; - } + if (argument_pairs.contains(add_argument_flags::Action)) { + found_params[extended_add_argument_flags::Action] = true; + action = get_or_throw>(argument_pairs.at(add_argument_flags::Action), "action") + .clone(); + } + if (argument_pairs.contains(add_argument_flags::HelpText)) { + help_text = get_or_throw(argument_pairs.at(add_argument_flags::HelpText), "help"); + } else { + help_text = short_arg + ", " + long_arg; + } + if (argument_pairs.contains(add_argument_flags::Required) && + get_or_throw(argument_pairs.at(add_argument_flags::Required), "required")) { + required = true; + } - auto suggested_add = suggest_candidate(found_params); - if (suggested_add == candidate_type::unknown) { - throw std::runtime_error("Could not match any add argument overload to given parameters. Are you missing some required parameter?"); - } - switch (suggested_add) { - case candidate_type::typed_action: - base::add_argument(short_arg, long_arg, help_text, *static_cast*>(&(*action)), required); - break; - case candidate_type::store_other: - base::add_argument(short_arg, long_arg, help_text, required); - break; - default: - throw std::runtime_error("Could not match the arguments against any overload."); - } - } - - template - void add_argument(std::initializer_list> const& pairs) { - std::unordered_map> args; + auto suggested_add = suggest_candidate(found_params); + if (suggested_add == candidate_type::unknown) { + throw std::runtime_error("Could not match any add argument overload to given parameters. Are you " + "missing some required parameter?"); + } + switch (suggested_add) { + case candidate_type::typed_action: + base::add_argument(short_arg, long_arg, help_text, *static_cast *>(&(*action)), + required); + break; + case candidate_type::store_other: + base::add_argument(short_arg, long_arg, help_text, required); + break; + default: + throw std::runtime_error("Could not match the arguments against any overload."); + } + } - for (auto& [k, v]: pairs) { - args[k] = v; - } + template void add_argument(std::initializer_list> const &pairs) { + std::unordered_map> args; - add_argument(args); - } + for (auto &[k, v] : pairs) { + args[k] = v; + } - void add_argument(std::initializer_list const& pairs) { - std::unordered_map args; - - for (auto& [k, v] : pairs) { - args[k] = v; - } + add_argument(args); + } - add_argument(args); - } + void add_argument(std::initializer_list const &pairs) { + std::unordered_map args; - void add_argument(std::unordered_map const& argument_pairs) { - std::unordered_map found_params {{ - extended_add_argument_flags::IsTyped, false - }}; + for (auto &[k, v] : pairs) { + args[k] = v; + } - std::string short_arg, long_arg, help_text; - std::unique_ptr action; - bool required = false; + add_argument(args); + } - if (argument_pairs.contains(add_argument_flags::ShortArgument)) { - found_params[extended_add_argument_flags::ShortArgument] = true; - short_arg = get_or_throw(argument_pairs.at(add_argument_flags::ShortArgument), "short"); - } - if (argument_pairs.contains(add_argument_flags::LongArgument)) { - found_params[extended_add_argument_flags::LongArgument] = true; - long_arg = get_or_throw(argument_pairs.at(add_argument_flags::LongArgument), "long"); - if (short_arg.empty()) short_arg = long_arg; - } else { - if (!short_arg.empty()) long_arg = short_arg; - } - if (argument_pairs.contains(add_argument_flags::Action)) { - found_params[extended_add_argument_flags::Action] = true; - action = get_or_throw(argument_pairs.at(add_argument_flags::Action), "action").clone(); - - } - if (argument_pairs.contains(add_argument_flags::HelpText)) { - help_text = get_or_throw(argument_pairs.at(add_argument_flags::HelpText), "help"); - } else { - help_text = short_arg + ", " + long_arg; - } + void add_argument(std::unordered_map const &argument_pairs) { + std::unordered_map found_params{ + {extended_add_argument_flags::IsTyped, false}}; - if (argument_pairs.contains(add_argument_flags::Required) && get_or_throw(argument_pairs.at(add_argument_flags::Required), "required")) { - required = true; - } + std::string short_arg, long_arg, help_text; + std::unique_ptr action; + bool required = false; - auto suggested_add = suggest_candidate(found_params); - if (suggested_add == candidate_type::unknown) { - throw std::runtime_error("Could not match any add argument overload to given parameters. Are you missing some required parameter?"); - } + if (argument_pairs.find(add_argument_flags::ShortArgument) != argument_pairs.end()) { + found_params[extended_add_argument_flags::ShortArgument] = true; + short_arg = get_or_throw(argument_pairs.at(add_argument_flags::ShortArgument), "short"); + } + if (argument_pairs.find(add_argument_flags::LongArgument) != argument_pairs.end()) { + found_params[extended_add_argument_flags::LongArgument] = true; + long_arg = get_or_throw(argument_pairs.at(add_argument_flags::LongArgument), "long"); + if (short_arg.empty()) + short_arg = long_arg; + } else { + if (!short_arg.empty()) + long_arg = short_arg; + } + if (argument_pairs.find(add_argument_flags::Action) != argument_pairs.end()) { + found_params[extended_add_argument_flags::Action] = true; + action = get_or_throw(argument_pairs.at(add_argument_flags::Action), "action") + .clone(); + } + if (argument_pairs.find(add_argument_flags::HelpText) != argument_pairs.end()) { + help_text = get_or_throw(argument_pairs.at(add_argument_flags::HelpText), "help"); + } else { + help_text = short_arg + ", " + long_arg; + } - switch (suggested_add) { - case candidate_type::non_typed_action: - base::add_argument(short_arg, long_arg, help_text, *static_cast(&(*action)), required); - break; - case candidate_type::store_boolean: - base::add_argument(short_arg, long_arg, help_text, required); - break; - default: - throw std::runtime_error("Could not match the arguments against any overload. The suggested candidate was: " + std::to_string((int(suggested_add)))); - } - } + if (argument_pairs.find(add_argument_flags::Required) != argument_pairs.end() && + get_or_throw(argument_pairs.at(add_argument_flags::Required), "required")) { + required = true; + } - argument_parser::base_parser& to_v1() { - return *this; - } + auto suggested_add = suggest_candidate(found_params); + if (suggested_add == candidate_type::unknown) { + throw std::runtime_error("Could not match any add argument overload to given parameters. Are you " + "missing some required parameter?"); + } - void handle_arguments(std::initializer_list convention_types) { - base::handle_arguments(convention_types); - } + switch (suggested_add) { + case candidate_type::non_typed_action: + base::add_argument(short_arg, long_arg, help_text, *static_cast(&(*action)), + required); + break; + case candidate_type::store_boolean: + base::add_argument(short_arg, long_arg, help_text, required); + break; + default: + throw std::runtime_error( + "Could not match the arguments against any overload. The suggested candidate was: " + + std::to_string((int(suggested_add)))); + } + } - template - std::optional get_optional(std::string const& arg) { - return base::get_optional(arg); - } + argument_parser::base_parser &to_v1() { + return *this; + } - void on_complete(std::function const& action) { - base::on_complete(action); - } + void handle_arguments(std::initializer_list convention_types) { + base::handle_arguments(convention_types); + } - protected: - void set_program_name(std::string p) { - base::program_name = std::move(p); - } + template std::optional get_optional(std::string const &arg) { + return base::get_optional(arg); + } - std::vector& ref_parsed_args() { - return base::parsed_arguments; - } + void on_complete(std::function const &action) { + base::on_complete(action); + } - private: - using base = argument_parser::base_parser; - enum class extended_add_argument_flags { - ShortArgument, - LongArgument, - Action, - IsTyped - }; + protected: + void set_program_name(std::string p) { + base::program_name = std::move(p); + } - enum class candidate_type { - store_boolean, - store_other, - typed_action, - non_typed_action, - unknown - }; + std::vector &ref_parsed_args() { + return base::parsed_arguments; + } - template - bool satisfies_at_least_one(std::array const& arr, std::unordered_map const& map) { - for (const auto& req: arr) { - if (map.contains(req)) return true; - } - return false; - } + private: + using base = argument_parser::base_parser; + enum class extended_add_argument_flags { ShortArgument, LongArgument, Action, IsTyped }; - candidate_type suggest_candidate(std::unordered_map const& available_vars) { - auto constexpr required_at_least_one = std::array { extended_add_argument_flags::ShortArgument, extended_add_argument_flags::LongArgument }; - if (!satisfies_at_least_one(required_at_least_one, available_vars)) return candidate_type::unknown; - - if (available_vars.contains(extended_add_argument_flags::Action)) { - if (available_vars.at(extended_add_argument_flags::IsTyped)) - return candidate_type::typed_action; - else return candidate_type::non_typed_action; - } - - if (available_vars.at(extended_add_argument_flags::IsTyped)) return candidate_type::store_other; - return candidate_type::store_boolean; - } + enum class candidate_type { store_boolean, store_other, typed_action, non_typed_action, unknown }; - template - T get_or_throw(typed_flag_value const& v, std::string_view key) { - if (auto p = std::get_if(&v)) return *p; - throw std::invalid_argument(std::string("variant type mismatch for key: ") + std::string(key)); - } + template + bool satisfies_at_least_one(std::array const &arr, std::unordered_map const &map) { + for (const auto &req : arr) { + if (map.find(req) != map.end()) + return true; + } + return false; + } - template - T get_or_throw(non_typed_flag_value const& v, std::string_view key) { - if (auto p = std::get_if(&v)) return *p; - throw std::invalid_argument(std::string("variant type mismatch for key: ") + std::string(key)); - } - }; -} \ No newline at end of file + candidate_type suggest_candidate(std::unordered_map const &available_vars) { + auto constexpr required_at_least_one = std::array{ + extended_add_argument_flags::ShortArgument, extended_add_argument_flags::LongArgument}; + if (!satisfies_at_least_one(required_at_least_one, available_vars)) + return candidate_type::unknown; + + if (available_vars.find(extended_add_argument_flags::Action) != available_vars.end()) { + if (available_vars.at(extended_add_argument_flags::IsTyped)) + return candidate_type::typed_action; + else + return candidate_type::non_typed_action; + } + + if (available_vars.at(extended_add_argument_flags::IsTyped)) + return candidate_type::store_other; + return candidate_type::store_boolean; + } + + template T get_or_throw(typed_flag_value const &v, std::string_view key) { + if (auto p = std::get_if(&v)) + return *p; + throw std::invalid_argument(std::string("variant type mismatch for key: ") + std::string(key)); + } + + template T get_or_throw(non_typed_flag_value const &v, std::string_view key) { + if (auto p = std::get_if(&v)) + return *p; + throw std::invalid_argument(std::string("variant type mismatch for key: ") + std::string(key)); + } + }; +} // namespace argument_parser::v2 \ No newline at end of file