diff --git a/CMakeLists.txt b/CMakeLists.txt index 7db33e6..60db2bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,7 @@ endif() # Build examples when requested by the user if (CXXOPTS_BUILD_EXAMPLES) add_subdirectory(src) + add_subdirectory(proposals-demo) endif() # Enable testing when requested by the user diff --git a/proposals-demo/CMakeLists.txt b/proposals-demo/CMakeLists.txt new file mode 100644 index 0000000..96f33af --- /dev/null +++ b/proposals-demo/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(objectification) \ No newline at end of file diff --git a/proposals-demo/objectification/CMakeLists.txt b/proposals-demo/objectification/CMakeLists.txt new file mode 100644 index 0000000..86de311 --- /dev/null +++ b/proposals-demo/objectification/CMakeLists.txt @@ -0,0 +1,7 @@ +PROJECT(ObjectificationDemo) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +ADD_EXECUTABLE(${PROJECT_NAME} + main.cpp + ) diff --git a/proposals-demo/objectification/main.cpp b/proposals-demo/objectification/main.cpp new file mode 100644 index 0000000..c317e65 --- /dev/null +++ b/proposals-demo/objectification/main.cpp @@ -0,0 +1,129 @@ +#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; +} \ No newline at end of file