split up arg classes better

master
Daniel Kolesa 2017-05-15 18:49:59 +02:00
parent d1b69963cb
commit 922da4a808
1 changed files with 31 additions and 10 deletions

View File

@ -52,18 +52,32 @@ enum class arg_value {
struct arg_parser; struct arg_parser;
struct arg_argument { struct arg_description {
friend struct arg_parser; friend struct arg_parser;
virtual ~arg_argument() {} virtual ~arg_description() {}
virtual arg_type type() const = 0; virtual arg_type type() const = 0;
virtual bool is_arg(string_range name) const = 0; virtual bool is_arg(string_range name) const = 0;
protected:
arg_description() {}
};
struct arg_argument: arg_description {
friend struct arg_parser;
protected: protected:
arg_argument(arg_value req = arg_value::NONE, int nargs = 1): arg_argument(arg_value req = arg_value::NONE, int nargs = 1):
p_valreq(req), p_nargs(nargs) arg_description(), p_valreq(req), p_nargs(nargs)
{}
arg_argument(int nargs):
arg_description(),
p_valreq((nargs > 0)
? arg_value::REQUIRED
: ((nargs < 0) ? arg_value::ALL : arg_value::NONE)
), p_nargs(nargs)
{} {}
arg_value p_valreq; arg_value p_valreq;
@ -103,6 +117,9 @@ protected:
): ):
arg_argument(req, nargs), p_lname(long_name), p_sname(short_name) arg_argument(req, nargs), p_lname(long_name), p_sname(short_name)
{} {}
arg_optional(char short_name, string_range long_name, int nargs):
arg_argument(nargs), p_lname(long_name), p_sname(short_name)
{}
private: private:
std::optional<std::string> p_value; std::optional<std::string> p_value;
@ -129,12 +146,16 @@ protected:
arg_argument(req, nargs), arg_argument(req, nargs),
p_name(name) p_name(name)
{} {}
arg_positional(string_range name, int nargs):
arg_argument(nargs),
p_name(name)
{}
private: private:
std::string p_name; std::string p_name;
}; };
struct arg_category: arg_argument { struct arg_category: arg_description {
friend struct arg_parser; friend struct arg_parser;
arg_type type() const { arg_type type() const {
@ -198,19 +219,19 @@ struct arg_parser {
template<typename ...A> template<typename ...A>
arg_optional &add_optional(A &&...args) { arg_optional &add_optional(A &&...args) {
arg_argument *p = new arg_optional{std::forward<A>(args)...}; arg_description *p = new arg_optional{std::forward<A>(args)...};
return static_cast<arg_optional &>(*p_opts.emplace_back(p)); return static_cast<arg_optional &>(*p_opts.emplace_back(p));
} }
template<typename ...A> template<typename ...A>
arg_positional &add_positional(A &&...args) { arg_positional &add_positional(A &&...args) {
arg_argument *p = new arg_positional{std::forward<A>(args)...}; arg_description *p = new arg_positional{std::forward<A>(args)...};
return static_cast<arg_positional &>(*p_opts.emplace_back(p)); return static_cast<arg_positional &>(*p_opts.emplace_back(p));
} }
template<typename ...A> template<typename ...A>
arg_category &add_category(A &&...args) { arg_category &add_category(A &&...args) {
arg_argument *p = new arg_category{std::forward<A>(args)...}; arg_description *p = new arg_category{std::forward<A>(args)...};
return static_cast<arg_category &>(*p_opts.emplace_back(p)); return static_cast<arg_category &>(*p_opts.emplace_back(p));
} }
@ -379,7 +400,7 @@ private:
void parse_pos(string_range) { void parse_pos(string_range) {
} }
arg_argument *find_arg_ptr(string_range name) { arg_description *find_arg_ptr(string_range name) {
for (auto &p: p_opts) { for (auto &p: p_opts) {
if (p->is_arg(name)) { if (p->is_arg(name)) {
return &*p; return &*p;
@ -388,7 +409,7 @@ private:
return nullptr; return nullptr;
} }
arg_argument &find_arg(string_range name) { arg_description &find_arg(string_range name) {
auto p = find_arg_ptr(name); auto p = find_arg_ptr(name);
if (p) { if (p) {
return *p; return *p;
@ -398,7 +419,7 @@ private:
).get()}; ).get()};
} }
std::vector<std::unique_ptr<arg_argument>> p_opts; std::vector<std::unique_ptr<arg_description>> p_opts;
std::string p_progname; std::string p_progname;
}; };