diff options
Diffstat (limited to 'src/lib/netlist/plib/poptions.h')
-rw-r--r-- | src/lib/netlist/plib/poptions.h | 161 |
1 files changed, 103 insertions, 58 deletions
diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index 491ac0b4d91..086fe32fc8a 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -10,8 +10,8 @@ #ifndef POPTIONS_H_ #define POPTIONS_H_ -#include "pstring.h" #include "plists.h" +#include "pstring.h" #include "putil.h" namespace plib { @@ -24,10 +24,12 @@ class options; class option_base { public: - option_base(options &parent, pstring help); - virtual ~option_base(); + option_base(options &parent, const pstring &help); + virtual ~option_base() = default; + + COPYASSIGNMOVE(option_base, delete) - pstring help() { return m_help; } + pstring help() const { return m_help; } private: pstring m_help; }; @@ -35,11 +37,10 @@ private: class option_group : public option_base { public: - option_group(options &parent, pstring group, pstring help) + option_group(options &parent, const pstring &group, const pstring &help) : option_base(parent, help), m_group(group) { } - ~option_group(); - pstring group() { return m_group; } + pstring group() const { return m_group; } private: pstring m_group; }; @@ -47,11 +48,10 @@ private: class option_example : public option_base { public: - option_example(options &parent, pstring group, pstring help) + option_example(options &parent, const pstring &group, const pstring &help) : option_base(parent, help), m_example(group) { } - ~option_example(); - pstring example() { return m_example; } + pstring example() const { return m_example; } private: pstring m_example; }; @@ -60,8 +60,7 @@ private: class option : public option_base { public: - option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument); - ~option(); + option(options &parent, const pstring &ashort, const pstring &along, const pstring &help, bool has_argument); /* no_argument options will be called with "" argument */ @@ -89,131 +88,177 @@ private: class option_str : public option { public: - option_str(options &parent, pstring ashort, pstring along, pstring defval, pstring help) + option_str(options &parent, const pstring &ashort, const pstring &along, const pstring &defval, const pstring &help) : option(parent, ashort, along, help, true), m_val(defval) {} - pstring operator ()() { return m_val; } + pstring operator ()() const { return m_val; } protected: - virtual int parse(const pstring &argument) override; + int parse(const pstring &argument) override; private: pstring m_val; }; -class option_str_limit : public option +class option_str_limit_base : public option { public: - option_str_limit(options &parent, pstring ashort, pstring along, pstring defval, pstring limit, pstring help) - : option(parent, ashort, along, help, true), m_val(defval) - , m_limit(plib::psplit(limit, ":")) + option_str_limit_base(options &parent, const pstring &ashort, const pstring &along, std::vector<pstring> &&limit, const pstring &help) + : option(parent, ashort, along, help, true) + , m_limit(limit) { } - - pstring operator ()() { return m_val; } - const std::vector<pstring> &limit() { return m_limit; } + const std::vector<pstring> &limit() const { return m_limit; } protected: - virtual int parse(const pstring &argument) override; private: - pstring m_val; std::vector<pstring> m_limit; }; -class option_bool : public option + +template <typename T> +class option_str_limit : public option_str_limit_base { public: - option_bool(options &parent, pstring ashort, pstring along, pstring help) - : option(parent, ashort, along, help, false), m_val(false) - {} + option_str_limit(options &parent, const pstring &ashort, const pstring &along, const T &defval, std::vector<pstring> &&limit, const pstring &help) + : option_str_limit_base(parent, ashort, along, std::move(limit), help), m_val(defval) + { + } + + T operator ()() const { return m_val; } - bool operator ()() { return m_val; } + pstring as_string() const { return limit()[m_val]; } protected: - virtual int parse(const pstring &argument) override; + int parse(const pstring &argument) override + { + auto raw = plib::container::indexof(limit(), argument); + + if (raw != plib::container::npos) + { + m_val = static_cast<T>(raw); + return 0; + } + else + return 1; + } private: - bool m_val; + T m_val; }; -class option_double : public option +class option_bool : public option { public: - option_double(options &parent, pstring ashort, pstring along, double defval, pstring help) - : option(parent, ashort, along, help, true), m_val(defval) + option_bool(options &parent, const pstring &ashort, const pstring &along, const pstring &help) + : option(parent, ashort, along, help, false), m_val(false) {} - double operator ()() { return m_val; } + bool operator ()() const { return m_val; } protected: - virtual int parse(const pstring &argument) override; + int parse(const pstring &argument) override; private: - double m_val; + bool m_val; }; -class option_long : public option +template <typename T> +class option_num : public option { public: - option_long(options &parent, pstring ashort, pstring along, long defval, pstring help) - : option(parent, ashort, along, help, true), m_val(defval) + option_num(options &parent, const pstring &ashort, const pstring &along, T defval, + const pstring &help, + T minval = std::numeric_limits<T>::min(), + T maxval = std::numeric_limits<T>::max() ) + : option(parent, ashort, along, help, true) + , m_val(defval) + , m_min(minval) + , m_max(maxval) {} - long operator ()() { return m_val; } + T operator ()() const { return m_val; } protected: - virtual int parse(const pstring &argument) override; + int parse(const pstring &argument) override + { + bool err; + m_val = pstonum_ne<T>(argument, err); + return (err ? 1 : (m_val < m_min || m_val > m_max)); + } private: - long m_val; + T m_val; + T m_min; + T m_max; }; class option_vec : public option { public: - option_vec(options &parent, pstring ashort, pstring along, pstring help) + option_vec(options &parent, const pstring &ashort, const pstring &along, const pstring &help) : option(parent, ashort, along, help, true) {} - std::vector<pstring> operator ()() { return m_val; } + const std::vector<pstring> &operator ()() const { return m_val; } protected: - virtual int parse(const pstring &argument) override; + int parse(const pstring &argument) override; private: std::vector<pstring> m_val; }; -class options +class option_args : public option_vec { public: + option_args(options &parent, const pstring &help) + : option_vec(parent, "", "", help) + {} +}; - options(); - explicit options(option *o[]); +class options : public nocopyassignmove +{ +public: - ~options(); + options(); + explicit options(option **o); void register_option(option_base *opt); - int parse(int argc, char *argv[]); + int parse(int argc, char **argv); - pstring help(pstring description, pstring usage, - unsigned width = 72, unsigned indent = 20); + pstring help(const pstring &description, const pstring &usage, + unsigned width = 72, unsigned indent = 20) const; - pstring app() { return m_app; } + pstring app() const { return m_app; } private: - static pstring split_paragraphs(pstring text, unsigned width, unsigned indent, + static pstring split_paragraphs(const pstring &text, unsigned width, unsigned indent, unsigned firstline_indent); - option *getopt_short(pstring arg); - option *getopt_long(pstring arg); + void check_consistency(); + + template <typename T> + T *getopt_type() const + { + for (auto & optbase : m_opts ) + { + if (auto opt = dynamic_cast<T *>(optbase)) + return opt; + } + return nullptr; + } + + option *getopt_short(const pstring &arg) const; + option *getopt_long(const pstring &arg) const; std::vector<option_base *> m_opts; pstring m_app; + option_args * m_other_args; }; -} +} // namespace plib #endif /* POPTIONS_H_ */ |