Created
October 30, 2017 19:05
-
-
Save o11c/5a3b76e207d2f94ce5c287d10abd0c6d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Options | |
{ | |
bool debug_events; | |
bool dump; | |
bool hello; | |
bool info; | |
const char *output; | |
Options() | |
{ | |
memset(this, 0, sizeof(*this)); | |
} | |
}; | |
class AbstractOptionSetter | |
{ | |
public: | |
virtual bool set_option(Options *opts, const char *val) = 0; | |
// Not actually *necessary*, since I ended up using shared_ptr, | |
// but it's still polite. | |
virtual ~AbstractOptionSetter() {} | |
}; | |
template<class T> | |
class PmdOptionSetter : public AbstractOptionSetter | |
{ | |
T Options::*member_pointer; | |
public: | |
PmdOptionSetter(T Options::*mp) : member_pointer(mp) {} | |
virtual bool parse_option(T *out, const char *val) = 0; | |
virtual bool set_option(Options *opts, const char *val) override | |
{ | |
T *ptr = &(opts->*(this->member_pointer)); | |
return parse_option(ptr, val); | |
} | |
}; | |
class BoolOptionSetter : public PmdOptionSetter<bool> | |
{ | |
public: | |
template<class... A> | |
BoolOptionSetter(A&&... a) : PmdOptionSetter<bool>(std::forward<A>(a)...) {} | |
virtual bool parse_option(bool *out, const char *val) override | |
{ | |
if (val) | |
return false; | |
*out = true; | |
return true; | |
} | |
}; | |
static std::shared_ptr<BoolOptionSetter> make_option_setter(bool Options::*mp) | |
{ | |
return std::make_shared<BoolOptionSetter>(mp); | |
} | |
class StringOptionSetter : public PmdOptionSetter<const char *> | |
{ | |
public: | |
template<class... A> | |
StringOptionSetter(A&&... a) : PmdOptionSetter<const char *>(std::forward<A>(a)...) {} | |
virtual bool parse_option(const char **out, const char *val) override | |
{ | |
*out = val; | |
return true; | |
} | |
}; | |
static std::shared_ptr<StringOptionSetter> make_option_setter(const char *Options::*mp) | |
{ | |
return std::make_shared<StringOptionSetter>(mp); | |
} | |
class OptionSetter | |
{ | |
std::shared_ptr<AbstractOptionSetter> impl; | |
public: | |
template<class T> | |
OptionSetter(T v) : impl(make_option_setter(v)) {} | |
bool set_option(Options *opts, const char *val) | |
{ | |
return impl->set_option(opts, val); | |
} | |
}; | |
static std::map<std::string, OptionSetter> option_map = | |
{ | |
{"debug_events", &Options::debug_events}, | |
{"dump", &Options::dump}, | |
{"hello", &Options::hello}, | |
{"info", &Options::info}, | |
{"output", &Options::output}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment