From f5287e2f206658a459174fb11074b9e2a93ec410 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 13 Nov 2023 14:16:26 -0800 Subject: [PATCH] Closes #307 --- include/argparse/argparse.hpp | 12 +++++++++--- test/test_choices.cpp | 32 +++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/include/argparse/argparse.hpp b/include/argparse/argparse.hpp index 0c85127..c614b5e 100644 --- a/include/argparse/argparse.hpp +++ b/include/argparse/argparse.hpp @@ -657,7 +657,7 @@ public: } template - auto action(F &&callable, Args &&...bound_args) + auto action(F &&callable, Args &&... bound_args) -> std::enable_if_t, Argument &> { using action_type = std::conditional_t< @@ -783,7 +783,7 @@ public: } template - Argument &choices(T &&first, U &&...rest) { + Argument &choices(T &&first, U &&... rest) { add_choice(std::forward(first)); choices(std::forward(rest)...); return *this; @@ -845,8 +845,14 @@ public: if (m_choices.has_value()) { // Check each value in (start, end) and make sure // it is in the list of allowed choices/options + std::size_t i = 0; + auto max_number_of_args = m_num_args_range.get_max(); for (auto it = start; it != end; ++it) { + if (i == max_number_of_args) { + break; + } find_value_in_choices_or_throw(it); + i += 1; } } @@ -1546,7 +1552,7 @@ public: // Parameter packed add_parents method // Accepts a variadic number of ArgumentParser objects template - ArgumentParser &add_parents(const Targs &...f_args) { + ArgumentParser &add_parents(const Targs &... f_args) { for (const ArgumentParser &parent_parser : {std::ref(f_args)...}) { for (const auto &argument : parent_parser.m_positional_arguments) { auto it = m_positional_arguments.insert( diff --git a/test/test_choices.cpp b/test/test_choices.cpp index 678aba8..206ec89 100644 --- a/test/test_choices.cpp +++ b/test/test_choices.cpp @@ -23,6 +23,36 @@ TEST_CASE("Parse argument that is in the fixed number of allowed choices" * program.parse_args({"test", "red"}); } +TEST_CASE("Parse argument that is in the fixed number of allowed choices, with " + "other positional argument" * + test_suite("choices")) { + argparse::ArgumentParser program("test"); + program.add_argument("--input") + .default_value(std::string{"baz"}) + .choices("foo", "bar", "baz"); + program.add_argument("--value").scan<'i', int>().default_value(0); + + REQUIRE_NOTHROW( + program.parse_args({"test", "--input", "foo", "--value", "1"})); + REQUIRE(program.get("--input") == "foo"); + REQUIRE(program.get("--value") == 1); +} + +TEST_CASE("Parse argument that is in the fixed number of allowed choices, with " + "other positional argument (reversed)" * + test_suite("choices")) { + argparse::ArgumentParser program("test"); + program.add_argument("--input") + .default_value(std::string{"baz"}) + .choices("foo", "bar", "baz"); + program.add_argument("--value").scan<'i', int>().default_value(0); + + REQUIRE_NOTHROW( + program.parse_args({"test", "--value", "1", "--input", "foo"})); + REQUIRE(program.get("--input") == "foo"); + REQUIRE(program.get("--value") == 1); +} + TEST_CASE("Parse argument that is in the fixed number of allowed choices, with " "invalid default" * test_suite("choices")) { @@ -88,4 +118,4 @@ TEST_CASE("Parse multiple arguments that are not in fixed number of allowed " program.parse_args({"test", "6", "7"}), "Invalid argument \"6\" - allowed options: {1, 2, 3, 4, 5}", std::runtime_error); -} \ No newline at end of file +}