|
|
|
@ -98,24 +98,24 @@ private:
|
|
|
|
|
|
|
|
|
|
class args final { |
|
|
|
|
public: |
|
|
|
|
using value_t = std::variant<bool, const char *>; |
|
|
|
|
using value_t = std::variant<bool, const char *, unsigned>; |
|
|
|
|
using text_t = std::initializer_list<std::string_view>; |
|
|
|
|
using char_p = const char *; |
|
|
|
|
|
|
|
|
|
struct option { |
|
|
|
|
friend class args; |
|
|
|
|
explicit option(char_p help) noexcept : |
|
|
|
|
value_(false), code_(0), usage_(nullptr), id_(nullptr), help_(help), next_(nullptr) { |
|
|
|
|
value_(false), code_(0), counter_(false), usage_(nullptr), id_(nullptr), help_(help), next_(nullptr) { |
|
|
|
|
add_option(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
option(char ch, char_p id, char_p help) noexcept : |
|
|
|
|
value_(false), code_(ch), usage_(nullptr), id_(id), help_(help), next_(nullptr) { |
|
|
|
|
option(char ch, char_p id, char_p help, bool counter = false) noexcept : |
|
|
|
|
value_(false), code_(ch), counter_(counter), usage_(nullptr), id_(id), help_(help), next_(nullptr) { |
|
|
|
|
add_option(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
option(char ch, char_p id, char_p help, char_p usage) noexcept : |
|
|
|
|
value_(false), code_(ch), usage_(usage), id_(id), help_(help), next_(nullptr) { |
|
|
|
|
value_(false), code_(ch), counter_(false), usage_(usage), id_(id), help_(help), next_(nullptr) { |
|
|
|
|
add_option(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -127,13 +127,17 @@ public:
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto operator *() const { |
|
|
|
|
return value_.index() < 1 ? nullptr : std::get<const char *>(value_); |
|
|
|
|
return (value_.index() != 1) ? nullptr : std::get<const char *>(value_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto operator!() const { |
|
|
|
|
return value_.index() < 1 && !std::get<bool>(value_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto count() const { |
|
|
|
|
return (value_.index() < 2) ? ((value_.index() > 0 || std::get<bool>(value_)) ? 1U : 0U) : std::get<unsigned>(value_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto value(long default_value = 0) const { |
|
|
|
|
return value_.index() > 0 ? bad_arg::str_value(std::get<const char *>(value_)) : default_value; |
|
|
|
|
} |
|
|
|
@ -156,6 +160,7 @@ public:
|
|
|
|
|
private: |
|
|
|
|
value_t value_; |
|
|
|
|
char code_; |
|
|
|
|
bool counter_; |
|
|
|
|
char_p usage_, id_, help_; |
|
|
|
|
option *next_; |
|
|
|
|
|
|
|
|
@ -224,6 +229,15 @@ public:
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(op->counter_) { |
|
|
|
|
if(op->value_.index() < 1) |
|
|
|
|
op->value_ = 1U; |
|
|
|
|
else |
|
|
|
|
op->value_ = op->count() + 1U; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(op->value_.index() > 0 || std::get<bool>(op->value_)) |
|
|
|
|
throw bad_arg("already used", keyword); |
|
|
|
|
|
|
|
|
@ -264,6 +278,15 @@ public:
|
|
|
|
|
if(!op) |
|
|
|
|
throw bad_arg("unknown option", arg[pos]); |
|
|
|
|
|
|
|
|
|
if(op->counter_) { |
|
|
|
|
if(op->value_.index() < 1) |
|
|
|
|
op->value_ = 1U; |
|
|
|
|
else |
|
|
|
|
op->value_ = op->count() + 1U; |
|
|
|
|
++pos; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(op->value_.index() > 0 || std::get<bool>(op->value_)) |
|
|
|
|
throw bad_arg("already used", arg[pos]); |
|
|
|
|
|
|
|
|
|