Commit 3c73d91c0b04e2b59462f0a741be8c07024c1bc0
Committed by
jarro2783
1 parent
e6858d34
add_options variant with initializer list (#189)
Allow adding options with a single initializer list.
Showing
2 changed files
with
146 additions
and
1 deletions
include/cxxopts.hpp
| ... | ... | @@ -1220,6 +1220,28 @@ namespace cxxopts |
| 1220 | 1220 | |
| 1221 | 1221 | std::vector<KeyValue> m_sequential; |
| 1222 | 1222 | }; |
| 1223 | + | |
| 1224 | + struct Option | |
| 1225 | + { | |
| 1226 | + Option | |
| 1227 | + ( | |
| 1228 | + const std::string& opts, | |
| 1229 | + const std::string& desc, | |
| 1230 | + const std::shared_ptr<const Value>& value = ::cxxopts::value<bool>(), | |
| 1231 | + const std::string& arg_help = "" | |
| 1232 | + ) | |
| 1233 | + : opts_(opts) | |
| 1234 | + , desc_(desc) | |
| 1235 | + , value_(value) | |
| 1236 | + , arg_help_(arg_help) | |
| 1237 | + { | |
| 1238 | + } | |
| 1239 | + | |
| 1240 | + std::string opts_; | |
| 1241 | + std::string desc_; | |
| 1242 | + std::shared_ptr<const Value> value_; | |
| 1243 | + std::string arg_help_; | |
| 1244 | + }; | |
| 1223 | 1245 | |
| 1224 | 1246 | class Options |
| 1225 | 1247 | { |
| ... | ... | @@ -1272,6 +1294,20 @@ namespace cxxopts |
| 1272 | 1294 | |
| 1273 | 1295 | OptionAdder |
| 1274 | 1296 | add_options(std::string group = ""); |
| 1297 | + | |
| 1298 | + void | |
| 1299 | + add_options | |
| 1300 | + ( | |
| 1301 | + const std::string& group, | |
| 1302 | + std::initializer_list<Option> options | |
| 1303 | + ); | |
| 1304 | + | |
| 1305 | + void | |
| 1306 | + add_option | |
| 1307 | + ( | |
| 1308 | + const std::string& group, | |
| 1309 | + const Option& option | |
| 1310 | + ); | |
| 1275 | 1311 | |
| 1276 | 1312 | void |
| 1277 | 1313 | add_option |
| ... | ... | @@ -1512,6 +1548,21 @@ ParseResult::ParseResult |
| 1512 | 1548 | } |
| 1513 | 1549 | |
| 1514 | 1550 | inline |
| 1551 | +void | |
| 1552 | +Options::add_options | |
| 1553 | +( | |
| 1554 | + const std::string &group, | |
| 1555 | + std::initializer_list<Option> options | |
| 1556 | +) | |
| 1557 | +{ | |
| 1558 | + OptionAdder option_adder(*this, group); | |
| 1559 | + for (const auto &option: options) | |
| 1560 | + { | |
| 1561 | + option_adder(option.opts_, option.desc_, option.value_, option.arg_help_); | |
| 1562 | + } | |
| 1563 | +} | |
| 1564 | + | |
| 1565 | +inline | |
| 1515 | 1566 | OptionAdder |
| 1516 | 1567 | Options::add_options(std::string group) |
| 1517 | 1568 | { |
| ... | ... | @@ -1890,6 +1941,17 @@ void |
| 1890 | 1941 | Options::add_option |
| 1891 | 1942 | ( |
| 1892 | 1943 | const std::string& group, |
| 1944 | + const Option& option | |
| 1945 | +) | |
| 1946 | +{ | |
| 1947 | + add_options(group, {option}); | |
| 1948 | +} | |
| 1949 | + | |
| 1950 | +inline | |
| 1951 | +void | |
| 1952 | +Options::add_option | |
| 1953 | +( | |
| 1954 | + const std::string& group, | |
| 1893 | 1955 | const std::string& s, |
| 1894 | 1956 | const std::string& l, |
| 1895 | 1957 | std::string desc, | ... | ... |
test/options.cpp
| ... | ... | @@ -93,7 +93,7 @@ TEST_CASE("Basic options", "[options]") |
| 93 | 93 | CHECK(arguments[1].key() == "short"); |
| 94 | 94 | CHECK(arguments[2].key() == "value"); |
| 95 | 95 | CHECK(arguments[3].key() == "av"); |
| 96 | - | |
| 96 | + | |
| 97 | 97 | CHECK_THROWS_AS(result["nothing"].as<std::string>(), std::domain_error&); |
| 98 | 98 | } |
| 99 | 99 | |
| ... | ... | @@ -684,3 +684,86 @@ TEST_CASE("Invalid option syntax", "[options]") { |
| 684 | 684 | CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_syntax_exception&); |
| 685 | 685 | } |
| 686 | 686 | } |
| 687 | + | |
| 688 | +TEST_CASE("Options empty", "[options]") { | |
| 689 | + cxxopts::Options options("Options list empty", " - test empty option list"); | |
| 690 | + options.add_options(); | |
| 691 | + options.add_options(""); | |
| 692 | + options.add_options("", {}); | |
| 693 | + options.add_options("test"); | |
| 694 | + | |
| 695 | + Argv argv_({ | |
| 696 | + "test", | |
| 697 | + "--unknown" | |
| 698 | + }); | |
| 699 | + auto argc = argv_.argc(); | |
| 700 | + char** argv = argv_.argv(); | |
| 701 | + | |
| 702 | + CHECK(options.groups().empty()); | |
| 703 | + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception&); | |
| 704 | +} | |
| 705 | + | |
| 706 | +TEST_CASE("Initializer list with group", "[options]") { | |
| 707 | + cxxopts::Options options("Initializer list group", " - test initializer list with group"); | |
| 708 | + | |
| 709 | + options.add_options("", { | |
| 710 | + {"a, address", "server address", cxxopts::value<std::string>()->default_value("127.0.0.1")}, | |
| 711 | + {"p, port", "server port", cxxopts::value<std::string>()->default_value("7110"), "PORT"}, | |
| 712 | + }); | |
| 713 | + | |
| 714 | + cxxopts::Option help{"h,help", "Help"}; | |
| 715 | + | |
| 716 | + options.add_options("TEST_GROUP", { | |
| 717 | + {"t, test", "test option"}, | |
| 718 | + help | |
| 719 | + }); | |
| 720 | + | |
| 721 | + Argv argv({ | |
| 722 | + "test", | |
| 723 | + "--address", | |
| 724 | + "10.0.0.1", | |
| 725 | + "-p", | |
| 726 | + "8000", | |
| 727 | + "-t", | |
| 728 | + }); | |
| 729 | + char** actual_argv = argv.argv(); | |
| 730 | + auto argc = argv.argc(); | |
| 731 | + auto result = options.parse(argc, actual_argv); | |
| 732 | + | |
| 733 | + CHECK(options.groups().size() == 2); | |
| 734 | + CHECK(result.count("address") == 1); | |
| 735 | + CHECK(result.count("port") == 1); | |
| 736 | + CHECK(result.count("test") == 1); | |
| 737 | + CHECK(result.count("help") == 0); | |
| 738 | + CHECK(result["address"].as<std::string>() == "10.0.0.1"); | |
| 739 | + CHECK(result["port"].as<std::string>() == "8000"); | |
| 740 | + CHECK(result["test"].as<bool>() == true); | |
| 741 | +} | |
| 742 | + | |
| 743 | +TEST_CASE("Option add with add_option(string, Option)", "[options]") { | |
| 744 | + cxxopts::Options options("Option add with add_option", " - test Option add with add_option(string, Option)"); | |
| 745 | + | |
| 746 | + cxxopts::Option option_1("t,test", "test option", cxxopts::value<int>()->default_value("7"), "TEST"); | |
| 747 | + | |
| 748 | + options.add_option("", option_1); | |
| 749 | + options.add_option("TEST", {"a,aggregate", "test option 2", cxxopts::value<int>(), "AGGREGATE"}); | |
| 750 | + | |
| 751 | + Argv argv_({ | |
| 752 | + "test", | |
| 753 | + "--test", | |
| 754 | + "5", | |
| 755 | + "-a", | |
| 756 | + "4" | |
| 757 | + }); | |
| 758 | + auto argc = argv_.argc(); | |
| 759 | + char** argv = argv_.argv(); | |
| 760 | + auto result = options.parse(argc, argv); | |
| 761 | + | |
| 762 | + CHECK(result.arguments().size()==2); | |
| 763 | + CHECK(options.groups().size() == 2); | |
| 764 | + CHECK(result.count("address") == 0); | |
| 765 | + CHECK(result.count("aggregate") == 1); | |
| 766 | + CHECK(result.count("test") == 1); | |
| 767 | + CHECK(result["aggregate"].as<int>() == 4); | |
| 768 | + CHECK(result["test"].as<int>() == 5); | |
| 769 | +} | ... | ... |