Open johschmitz opened 5 years ago
Use a struct
if you make your own struct, you can set default arguments for each of the values.
namespace fs = std::filesystem;
struct cli_args {
bool help{false};
fs::path filename{"/some/default/path/location/file.txt"}
// ...
};
auto cli_parser(cli_args& args) {
return clara::Help(args.help)
| clara::Opt(args.filename, "filename")[-f][--file]("filename of something")
| // ...
}
int main(int argc, char* argv[]) {
auto args = cli_args{};
auto parser = cli_parser(args);
auto const parsed = args.parse(clara::Args(argc, argv));
// ...
}
For more control, I use a class with const accessors, which also has some private only variables used for lifetime of some things; and I make cli_parser
a member function, and have a parse
member function too.
For example; here is a simple one I am using myself:
class cli_args {
public:
auto parser() noexcept -> clara::Parser& { return m_parser; }
template <typename... Args>
auto parse(Args&&... args) -> decltype(auto) {
return m_parser.parse(std::forward<Args>(args)...);
}
bool constexpr help() const noexcept { return m_help; }
auto constexpr tree() const noexcept -> std::string const& { return m_tree; }
auto constexpr list_dir() const noexcept -> fs::path const& { return m_list_dir; }
auto constexpr workers() const noexcept { return m_workers; }
auto constexpr log() noexcept -> std::ostream& { return m_log; }
auto constexpr output_dir() const noexcept -> fs::path const& { return m_output_dir; }
private:
bool m_help{false};
std::string m_tree{"output"};
fs::path m_list_dir{data_dir};
unsigned int m_workers{std::max(std::thread::hardware_concurrency(), 1u)};
std::ostream m_log{std::clog.rdbuf()};
std::ofstream m_log_{};
fs::path m_output_dir{data_dir};
clara::Parser m_parser{clara::Help(m_help)
| clara::Opt(m_tree, "tree-name")["-t"]["--tree"]("name of the TTree to use")
| clara::Opt(m_list_dir, "dirname")["-i"]["--list-dir"]("directory of list files")
| clara::Opt(m_workers, "number")["-j"]["--workers"]("number of parallel workers")
| clara::Opt(
[&](fs::path const& filename) {
m_log_.open(filename);
m_log.rdbuf(m_log_.rdbuf());
return clara::ParserResult::ok(clara::ParseResultType::Matched);
},
"filename")["-l"]["--log"]("set log file")
| clara::Opt(m_output_dir, "dirname")["-o"]["--output"]("output directory")};
};
One example for this is a default output filename if none is provided.