I am trying to validate command line input to an Enum that I've defined, but get compiler errors. I have used Handle complex options with Boost's program_options as an example to work from.
namespace po = boost::program_options;
namespace Length
{
enum UnitType
{
METER,
INCH
};
}
void validate(boost::any& v, const std::vector<std::string>& values, Length::UnitType*, int)
{
Length::UnitType unit;
if (values.size() < 1)
{
throw boost::program_options::validation_error("A unit must be specified");
}
// make sure no previous assignment was made
//po::validators::check_first_occurence(v); // tried this but compiler said it couldn't find it
std::string input = values.at(0);
//const std::string& input = po::validators::get_single_string(values); // tried this but compiler said it couldn't find it
// I'm just trying one for now
if (input.compare("inch") == 0)
{
unit = Length::INCH;
}
v = boost::any(unit);
}
// int main(int argc, char *argv[]) not included
And to spare including more code than what is necessary, I'm adding the option as follows:
po::options_description config("Configuration");
config.add_options()
("to-unit", po::value<std::vector<Length::UnitType> >(), "The unit(s) of length to convert to")
;
If the compiler error is needed I can post it, but was hoping to keep the question simple looking. I've tried looking for examples, but the only other example I could really find was the examples/regex.cpp from the Boost website.
In your case, you simply need to overload operator>>
to extract a Length::Unit
from an istream
, as shown here:
#include <iostream>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>
namespace Length
{
enum Unit {METER, INCH};
std::istream& operator>>(std::istream& in, Length::Unit& unit)
{
std::string token;
in >> token;
if (token == "inch")
unit = Length::INCH;
else if (token == "meter")
unit = Length::METER;
else
in.setstate(std::ios_base::failbit);
return in;
}
};
typedef std::vector<Length::Unit> UnitList;
int main(int argc, char* argv[])
{
UnitList units;
namespace po = boost::program_options;
po::options_description options("Program options");
options.add_options()
("to-unit",
po::value<UnitList>(&units)->multitoken(),
"The unit(s) of length to convert to")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, options), vm);
po::notify(vm);
BOOST_FOREACH(Length::Unit unit, units)
{
std::cout << unit << " ";
}
std::cout << "\n";
return 0;
}
A custom validator is not necessary.