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
|
inline
|
||||||
void
|
void
|
||||||
parse_value(const std::string& text, uint8_t& value)
|
parse_value(const std::string& text, uint8_t& value)
|
||||||
@ -605,6 +615,15 @@ namespace cxxopts
|
|||||||
value = text;
|
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>
|
template <typename T>
|
||||||
void
|
void
|
||||||
parse_value(const std::string& text, std::vector<T>& value)
|
parse_value(const std::string& text, std::vector<T>& value)
|
||||||
|
@ -49,6 +49,7 @@ int main(int argc, char* argv[])
|
|||||||
"thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace")
|
"thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace")
|
||||||
("help", "Print help")
|
("help", "Print help")
|
||||||
("int", "An integer", cxxopts::value<int>(), "N")
|
("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")
|
("option_that_is_too_long_for_the_help", "A very long option")
|
||||||
#ifdef CXXOPTS_USE_UNICODE
|
#ifdef CXXOPTS_USE_UNICODE
|
||||||
("unicode", u8"A help option with non-ascii: à. Here the size of the"
|
("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;
|
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;
|
std::cout << "Arguments remain = " << argc << std::endl;
|
||||||
|
|
||||||
} catch (const cxxopts::OptionException& e)
|
} catch (const cxxopts::OptionException& e)
|
||||||
|
@ -336,3 +336,31 @@ TEST_CASE("Integer overflow", "[options]")
|
|||||||
options.parse_positional("positional");
|
options.parse_positional("positional");
|
||||||
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type);
|
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