From 01679ed9bee037b0e0019ebcb79594778ec3c033 Mon Sep 17 00:00:00 2001 From: q66 Date: Thu, 25 May 2017 19:25:06 +0200 Subject: [PATCH] derive arg_group from arg_description_container --- ostd/argparse.hh | 212 +++++++++++++++++++---------------------------- 1 file changed, 83 insertions(+), 129 deletions(-) diff --git a/ostd/argparse.hh b/ostd/argparse.hh index 5e2c7cd..2ad0870 100644 --- a/ostd/argparse.hh +++ b/ostd/argparse.hh @@ -375,91 +375,6 @@ private: bool p_required; }; -struct arg_group: arg_description { - friend struct arg_description_container; - - arg_type type() const { - return arg_type::GROUP; - } - - string_range get_name() const { - return p_name; - } - - template - arg_optional &add_optional(A &&...args) { - arg_description *p = new arg_optional(std::forward(args)...); - return static_cast(*p_opts.emplace_back(p)); - } - - template - arg_positional &add_positional(A &&...args) { - arg_description *p = new arg_positional(std::forward(args)...); - return static_cast(*p_opts.emplace_back(p)); - } - - template - arg_mutually_exclusive_group &add_mutually_exclusive_group(A &&...args) { - arg_description *p = new arg_mutually_exclusive_group( - std::forward(args)... - ); - return static_cast( - *p_opts.emplace_back(p) - ); - } - - template - bool for_each(F &&func, bool iter_ex) const { - return for_each_impl(func, iter_ex); - } - -protected: - arg_group() = delete; - arg_group(string_range name): - p_name(name) - {} - - arg_description *find_arg( - string_range name, std::optional tp, bool parsing - ) { - for (auto &opt: p_opts) { - if (auto *p = opt->find_arg(name, tp, parsing); p) { - return p; - } - } - return nullptr; - } - -private: - template - bool for_each_impl(F &func, bool iter_ex) const { - for (auto &desc: p_opts) { - switch (desc->type()) { - case arg_type::OPTIONAL: - case arg_type::POSITIONAL: - if (!func(*desc)) { - return false; - } - break; - case arg_type::MUTUALLY_EXCLUSIVE_GROUP: - if (!static_cast( - *desc - ).for_each(func, iter_ex)) { - return false; - } - break; - default: - /* should never happen */ - throw arg_error{"invalid argument type"}; - } - } - return true; - } - - std::string p_name; - std::vector> p_opts; -}; - struct arg_description_container { template arg_optional &add_optional(A &&...args) { @@ -473,12 +388,6 @@ struct arg_description_container { return static_cast(*p_opts.emplace_back(p)); } - template - arg_group &add_group(A &&...args) { - arg_description *p = new arg_group(std::forward(args)...); - return static_cast(*p_opts.emplace_back(p)); - } - template arg_mutually_exclusive_group &add_mutually_exclusive_group(A &&...args) { arg_description *p = new arg_mutually_exclusive_group( @@ -519,48 +428,87 @@ protected: } template - bool for_each_impl(F &func, bool iter_ex) const { - for (auto &desc: p_opts) { - switch (desc->type()) { - case arg_type::OPTIONAL: - case arg_type::POSITIONAL: - if (!func(static_cast(*desc))) { - return false; - } - break; - case arg_type::GROUP: - if (!static_cast(*desc).for_each( - func, iter_ex - )) { - return false; - } - break; - case arg_type::MUTUALLY_EXCLUSIVE_GROUP: - if (!iter_ex) { - if (!func(static_cast( - *desc - ))) { - return false; - } - continue; - } - if (!static_cast( - *desc - ).for_each(func, iter_ex)) { - return false; - } - break; - default: - /* should never happen */ - throw arg_error{"invalid argument type"}; - } - } - return true; - } + bool for_each_impl(F &func, bool iter_ex) const; std::vector> p_opts; }; +struct arg_group: arg_description, arg_description_container { + template + friend struct basic_arg_parser; + + arg_type type() const { + return arg_type::GROUP; + } + + string_range get_name() const { + return p_name; + } + +protected: + arg_group() = delete; + arg_group(string_range name): + arg_description(), arg_description_container(), p_name(name) + {} + + arg_description *find_arg( + string_range name, std::optional tp, bool parsing + ) { + for (auto &opt: p_opts) { + if (auto *p = opt->find_arg(name, tp, parsing); p) { + return p; + } + } + return nullptr; + } + +private: + std::string p_name; + std::vector> p_opts; +}; + +template +inline bool arg_description_container::for_each_impl( + F &func, bool iter_ex +) const { + for (auto &desc: p_opts) { + switch (desc->type()) { + case arg_type::OPTIONAL: + case arg_type::POSITIONAL: + if (!func(static_cast(*desc))) { + return false; + } + break; + case arg_type::GROUP: + if (!static_cast(*desc).for_each( + func, iter_ex + )) { + return false; + } + break; + case arg_type::MUTUALLY_EXCLUSIVE_GROUP: + if (!iter_ex) { + if (!func(static_cast( + *desc + ))) { + return false; + } + continue; + } + if (!static_cast( + *desc + ).for_each(func, iter_ex)) { + return false; + } + break; + default: + /* should never happen */ + throw arg_error{"invalid argument type"}; + } + } + return true; +} + template struct basic_arg_parser: arg_description_container { private: @@ -573,6 +521,12 @@ public: arg_description_container(), p_progname(progname), p_posix(posix) {} + template + arg_group &add_group(A &&...args) { + arg_description *p = new arg_group(std::forward(args)...); + return static_cast(*p_opts.emplace_back(p)); + } + void parse(int argc, char **argv) { if (p_progname.empty()) { p_progname = argv[0];