#include "cxxopts.hpp" namespace yaco { //=========================================================================== // applicator // The prototype of applicator. // This way of using static functions in a class enables partial specialization. template struct applicator { template static void apply(const Action &action, Opt &O) { action.Apply(O); } }; //=========================================================================== // ApplyAction template void ApplyAction(Obj &O, const Action & action) { applicator::apply(action, O); } template void ApplyAction(Obj &O, const Action & action, const Actions & ... actions) { ApplyAction(O, action); ApplyAction(O, actions...); } //=========================================================================== struct Opt : public cxxopts::Option { template explicit Opt(const Action & ... actions) : cxxopts::Option("", "") { ApplyAction(*this, actions...); Done(); } ~Opt() override = default; void Done() { } }; struct Parser : public cxxopts::Options { template explicit Parser(const Actions & ... actions) : cxxopts::Options("") { ApplyAction(*this, actions...); } ~Parser() override = default; Options &program_name(std::string name) { this->m_program = std::move(name); return *this; } }; } namespace yaco /// Applicators - the instance properties implicit modifier. { template struct applicator { static void apply(const char *str, Parser &Os) { Os.program_name(std::string(str)); } static void apply(const char *str, Opt &O) { O.opts_ = std::string(str); } }; } /// yaco namespace yaco /// The instance properties explicit modifier. { template struct type { void Apply(Opt &O) const { O.value_ = cxxopts::value(); } }; struct desc { desc(const char *str) : desc_(std::string(str)) {} void Apply(Opt &O) const { O.desc_ = desc_; } std::string desc_; }; struct inject { inject(Parser &Os) : Os_(Os) { } void Apply(Opt &O) const { Os_.add_option("", O); } Parser &Os_; }; } // namespace yaco yaco::Parser options("objectification-demo"); yaco::Opt help("h,help", yaco::desc("display help messages."), yaco::inject(options)); yaco::Opt job("j,job", "jobs", yaco::type(), yaco::inject(options)); int main(int argc, char **argv) { auto result = options.parse(argc, argv); if (result.count("help") > 0) { std::cout << options.help() << std::endl; exit(0); } return 0; }