Skip to content

Instantly share code, notes, and snippets.

@o11c
Created October 30, 2017 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save o11c/5a3b76e207d2f94ce5c287d10abd0c6d to your computer and use it in GitHub Desktop.
Save o11c/5a3b76e207d2f94ce5c287d10abd0c6d to your computer and use it in GitHub Desktop.
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