What I currently have is
("someOption,s", po::bool_switch(&variable)->default_value(false), "")
I would like to be able to specify the argument multiple times and each occurence would switch the value of this bool.
Examples:
default value = false
./program -s
value == true
./program -s -s
value == false
./program -s -s -s
value == true
Is there a way to use something like bool_switch multiple times so switch on/off repeatedly? Do I need my custom type and validator for that?
Maybe I can somehow allow specifying the option multiple times and then do vm.count("someOption") and based on its value (even/odd) switch my variable. But I would prefer to specify that behaviour right in the options descripton (add_options) without checking and modifying the values later.
So this is as close I got so far. It does not look very elegant, more like a workaround, I would be happy to know better ("shorter") solution. There could be also some problems with the code, feel free to correct me please. Currently it works only if default is treated as false. I don't know how to start with true, it would require to know the default value somehow in validate function. It is out of scope of this questions and hopefully solved here: boost::program_options custom validate and default value
// my custom class
class BoolOption {
public:
BoolOption(bool initialState = false) : state(initialState) {}
bool getState() const {return state;}
void switchState() {state = !state;}
private:
bool state;
};
// two variables
BoolOption test1;
BoolOption test2;
// validate
void validate(boost::any &v, std::vector<std::string> const &xs, BoolOption*, long)
{
if (v.empty()) {
v = BoolOption(true); // I don't know how to assign default here so this works only when default is false
} else {
boost::any_cast<BoolOption&>(v).switchState();
}
}
optionsDescription->add_options()
("test1,t", po::value<BoolOption>(&test1)->default_value(BoolOption(true), "true")->zero_tokens(), "")
("test2,T", po::value<BoolOption>(&test2)->default_value(BoolOption(false), "false")->zero_tokens(), "")
;
// output result
cout << test1.getState() << endl;
cout << test2.getState() << endl;
This seems to work correctly, I can call it in a way:
./program -t -t -T -t -T
and it switches the arguments.