Boost program_options: multiple times use options with null parameter?
I am wondering if it is possible to use options with zero parameters multiple times with boost :: program_options.
I have something in mind:
mytool --load myfile --print_status --do-something 23 --print_status
It is easy to make this work with one parameter "print_status", but it is not clear to me how this option can be used twice (in my case, boost throws an exception if the parameter with a null parameter is specified more than once).
So the question is:
Is there any (easy) way to achieve this with functionality from program_options?
Right now this seems to be a flaw in the current program_options implementation.
PS :.
There have been similar questions in the past (both over four years old) where no solution has been found:
http://lists.boost.org/boost-users/2006/08/21631.php
http://benjaminwolsey.de/de/node/103
This thread contains a solution, but it is not obvious if it is working and it seems rather complicated for such a simple function:
Specifying levels (e.g. --verbose) with Boost program_options
source to share
If you don't have to count the number of options that have been specified, it's pretty easy (if a little weird); just declare the variable like vector<bool>
and set the following parameters:
std::vector<bool> example;
// ...
desc.add_options()
("example,e",
po::value(&example)
->default_value(std::vector<bool>(), "false")
->implicit_value(std::vector<bool>(1), "true")
->zero_tokens()
)
// ...
The hint vector
suppresses checking of multiple arguments; default_value
says the vector should be empty by default, implicit_value
says to set it to a 1-element vector if specified -e/--example
, and zero_tokens
says it doesn't consume any further tokens.
If -e
or is --example
specified at least once, it example.size()
will be exactly 1
; otherwise it will 0
.
If you want to count how many times this option occurs, you just need to write a custom type and validator:
struct counter { int count = 0; };
void validate(boost::any& v, std::vector<std::string> const& xs, counter*, long)
{
if (v.empty()) v = counter{1};
else ++boost::any_cast<counter&>(v).count;
}
Note that unlike the linked question, this does not allow you to specify a value additionally (e.g. --verbose 6
) - if you want to do something this complex, you will need to write a custom subclass value_semantic
as it is not supported by augmenting existing semantics.
source to share