always store values externally

master
Daniel Kolesa 2017-05-16 00:22:46 +02:00
parent 061d988ef2
commit 0ee5404612
1 changed files with 22 additions and 62 deletions

View File

@ -16,7 +16,6 @@
#ifndef OSTD_ARGPARSE_HH #ifndef OSTD_ARGPARSE_HH
#define OSTD_ARGPARSE_HH #define OSTD_ARGPARSE_HH
#include <any>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
@ -112,9 +111,8 @@ struct arg_optional: arg_argument {
return p_valreq; return p_valreq;
} }
template<typename T> bool used() const {
arg_optional &value(T &&val) { return p_used;
p_value = std::forward<T>(val);
} }
template<typename F> template<typename F>
@ -122,35 +120,12 @@ struct arg_optional: arg_argument {
p_action = [this, func = std::move(func)]( p_action = [this, func = std::move(func)](
iterator_range<string_range const *> vals iterator_range<string_range const *> vals
) mutable { ) mutable {
p_value = func(vals); func(vals);
p_used = true;
}; };
return *this; return *this;
} }
template<typename F, typename T>
arg_optional &action(F func, T &vref) {
p_action = [this, &vref, func = std::move(func)](
iterator_range<string_range const *> vals
) mutable {
vref = func(vals);
p_value = true;
};
return *this;
}
template<typename F, typename T>
arg_optional &action(std::pair<F, T> p) {
p_value = std::move(p.second);
return action(std::move(p.first));
}
template<typename F, typename T, typename U>
arg_optional &action(std::pair<F, T> p, U &vref) {
vref = std::move(p.second);
p_value = false;
return action(std::move(p.first), vref);
}
arg_optional &help(string_range str) { arg_optional &help(string_range str) {
arg_argument::help(str); arg_argument::help(str);
return *this; return *this;
@ -172,30 +147,15 @@ protected:
if (p_action) { if (p_action) {
p_action(vals); p_action(vals);
} else { } else {
switch (vals.size()) { p_used = true;
case 0:
p_value = true;
break;
case 1:
p_value = std::string{vals.front()};
break;
default: {
std::vector<std::string> strs;
strs.reserve(vals.size());
for (auto s: vals) {
strs.emplace_back(s);
}
p_value = std::move(strs);
}
}
} }
} }
private: private:
std::any p_value;
std::function<void(iterator_range<string_range const *>)> p_action; std::function<void(iterator_range<string_range const *>)> p_action;
std::string p_lname; std::string p_lname;
char p_sname; char p_sname;
bool p_used = false;
}; };
struct arg_positional: arg_argument { struct arg_positional: arg_argument {
@ -336,15 +296,9 @@ struct arg_parser {
return find_arg<arg_argument>(name); return find_arg<arg_argument>(name);
} }
template<typename T>
T &get(string_range name) {
auto &arg = find_arg<arg_optional>(name);
return std::any_cast<T &>(arg.p_value);
}
bool used(string_range name) { bool used(string_range name) {
auto &arg = find_arg<arg_optional>(name); auto &arg = find_arg<arg_optional>(name);
return arg.p_value.has_value(); return arg.p_used;
} }
private: private:
@ -577,7 +531,6 @@ auto arg_print_help(OutputRange o, arg_parser &p) {
mutable mutable
{ {
p.print_help(o); p.print_help(o);
return true;
}; };
}; };
@ -585,19 +538,26 @@ auto arg_print_help(arg_parser &p) {
return arg_print_help(cout.iter(), p); return arg_print_help(cout.iter(), p);
} }
template<typename T> template<typename T, typename U>
auto arg_store_const(T &&val) { auto arg_store_const(T &&val, U &ref) {
return [val](iterator_range<string_range const *>) mutable { return [val, &ref](iterator_range<string_range const *>) mutable {
return std::move(val); ref = std::move(val);
}; };
} }
auto arg_store_true() { template<typename T>
return std::make_pair(arg_store_const(true), false); auto arg_store_str(T &ref) {
return [&ref](iterator_range<string_range const *> r) mutable {
ref = T{r[0]};
};
} }
auto arg_store_false() { auto arg_store_true(bool &ref) {
return std::make_pair(arg_store_const(false), true); return arg_store_const(true, ref);
}
auto arg_store_false(bool &ref) {
return arg_store_const(false, ref);
} }
/** @} */ /** @} */