Added parsing of general types. (#63)
Adds generic parsing of types using `operator>>`, in particular allows parsing of floats and doubles.
This commit is contained in:
parent
da9210d41e
commit
2aed1ce41b
@ -533,6 +533,16 @@ namespace cxxopts
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void stringstream_parser(const std::string& text, T& value)
|
||||
{
|
||||
std::stringstream in(text);
|
||||
in >> value;
|
||||
if (!in) {
|
||||
throw argument_incorrect_type(text);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
parse_value(const std::string& text, uint8_t& value)
|
||||
@ -605,6 +615,15 @@ namespace cxxopts
|
||||
value = text;
|
||||
}
|
||||
|
||||
// The fallback parser. It uses the stringstream parser to parse all types
|
||||
// that have not been overloaded explicitly. It has to be placed in the
|
||||
// source code before all other more specialized templates.
|
||||
template <typename T>
|
||||
void
|
||||
parse_value(const std::string& text, T& value) {
|
||||
stringstream_parser(text, value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
parse_value(const std::string& text, std::vector<T>& value)
|
||||
|
@ -49,6 +49,7 @@ int main(int argc, char* argv[])
|
||||
"thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace")
|
||||
("help", "Print help")
|
||||
("int", "An integer", cxxopts::value<int>(), "N")
|
||||
("float", "A floating point number", cxxopts::value<float>())
|
||||
("option_that_is_too_long_for_the_help", "A very long option")
|
||||
#ifdef CXXOPTS_USE_UNICODE
|
||||
("unicode", u8"A help option with non-ascii: à. Here the size of the"
|
||||
@ -118,6 +119,11 @@ int main(int argc, char* argv[])
|
||||
std::cout << "int = " << options["int"].as<int>() << std::endl;
|
||||
}
|
||||
|
||||
if (options.count("float"))
|
||||
{
|
||||
std::cout << "float = " << options["float"].as<float>() << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "Arguments remain = " << argc << std::endl;
|
||||
|
||||
} catch (const cxxopts::OptionException& e)
|
||||
|
@ -336,3 +336,31 @@ TEST_CASE("Integer overflow", "[options]")
|
||||
options.parse_positional("positional");
|
||||
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type);
|
||||
}
|
||||
|
||||
TEST_CASE("Floats", "[options]")
|
||||
{
|
||||
cxxopts::Options options("parses_floats", "parses floats correctly");
|
||||
options.add_options()
|
||||
("double", "Double precision", cxxopts::value<double>())
|
||||
("positional", "Floats", cxxopts::value<std::vector<float>>());
|
||||
|
||||
Argv av({"floats", "--double", "0.5", "--", "4", "-4", "1.5e6", "-1.5e6"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
options.parse_positional("positional");
|
||||
options.parse(argc, argv);
|
||||
|
||||
REQUIRE(options.count("double") == 1);
|
||||
REQUIRE(options.count("positional") == 4);
|
||||
|
||||
CHECK(options["double"].as<double>() == 0.5);
|
||||
|
||||
auto& positional = options["positional"].as<std::vector<float>>();
|
||||
CHECK(positional[0] == 4);
|
||||
CHECK(positional[1] == -4);
|
||||
CHECK(positional[2] == 1.5e6);
|
||||
CHECK(positional[3] == -1.5e6);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user