Using Reflection For Parsing Command Line Arguments
I've been very excited about reflection so I built a small library to pass command line arguments
Basic example:
struct Args
{
std::string firstname;
int age;
bool active;
};
// ./program --first-name John --age 99 --active
const auto args = clap::parse<Args>(argc, argv);
assert(args.firstname == "John");
assert(args.age == 99);
assert(args.active);
More interesting example:
struct Args
{
[= clap::Description<"host to connecto to">{}]
std::string host = "localhost";
[=clap::ShortName<'p'>{}]
std::uint16t port;
[[=clap::Env<"RETRYCOUNT">{}]]
std::uint32t retrycount;
std::optional<std::string> logfile;
[[=clap::ShortName<'e'>{}]]
bool encrypted;
[[=clap::ShortName<'c'>{}]]
bool compressed;
[[=clap::ShortName<'h'>{}]]
bool hashed;
};
// ./program -p 8080 -ec
const auto args = clap::parse<Args>(argc, argv);
assert(args.host == "localhost");
assert(args.port == 8080);
assert(args.retrycount == std::stoul(std::getenv("RETRYCOUNT")));
assert(!args.logfile);
assert(args.encrypted);
assert(args.compressed);
assert(!args.hashed);
The amount of code to handle this is actually quite minimal < 500 lines.
There's a few modern goodies that make this code work:
Reflection \[[P2996](https://isocpp.org/files/papers/P2996R13.html)\]
Annotations for Reflection [P3394\]
Contracts \[[P2900](https://isocpp.org/files/papers/P2900R14.pdf)\]
constexpr exceptions [P3068\]
I guess we don't know what "idiomatic" reflection usage is like yet, I'm interested to come back to this code in a years time and see what mistakes I made!
Link to the code: https://github.com/nathan-baggs/clap
Any feedback, queries, questions are welcome!
https://redd.it/1sv4w78
@r_cpp
Post #25056
16