In order to improve ease of use, a new usage is demonstrated in the proposals-demo/objectification. It looks like LLVM CommandLine2.0.

This commit is contained in:
RonxBulld 2021-04-26 15:08:24 +08:00
parent 491cad95de
commit e6d0b30f37
4 changed files with 138 additions and 0 deletions

View File

@ -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

View File

@ -0,0 +1 @@
add_subdirectory(objectification)

View File

@ -0,0 +1,7 @@
PROJECT(ObjectificationDemo)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
ADD_EXECUTABLE(${PROJECT_NAME}
main.cpp
)

View File

@ -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 <class Action> struct applicator
{
template <class Opt>
static void apply(const Action &action, Opt &O) { action.Apply(O); }
};
//===========================================================================
// ApplyAction
template <typename Obj, typename Action>
void ApplyAction(Obj &O, const Action & action)
{
applicator<Action>::apply(action, O);
}
template <typename Obj, typename Action, typename ... Actions>
void ApplyAction(Obj &O, const Action & action, const Actions & ... actions)
{
ApplyAction(O, action);
ApplyAction(O, actions...);
}
//===========================================================================
struct Opt : public cxxopts::Option
{
template <class ... Action>
explicit Opt(const Action & ... actions) : cxxopts::Option("", "")
{
ApplyAction(*this, actions...);
Done();
}
~Opt() override = default;
void Done()
{
}
};
struct Parser : public cxxopts::Options
{
template <typename ... Actions>
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 <unsigned N> struct applicator <char[N]>
{
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 <class T> struct type
{
void Apply(Opt &O) const
{
O.value_ = cxxopts::value<T>();
}
};
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<int>(), 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;
}