mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 07:04:39 +00:00
Merge pull request #331 from rouault/store_into
Add Argument::store_into() functions
This commit is contained in:
commit
874b939f13
31
README.md
31
README.md
@ -26,6 +26,7 @@
|
|||||||
* [Joining values of repeated optional arguments](#joining-values-of-repeated-optional-arguments)
|
* [Joining values of repeated optional arguments](#joining-values-of-repeated-optional-arguments)
|
||||||
* [Repeating an argument to increase a value](#repeating-an-argument-to-increase-a-value)
|
* [Repeating an argument to increase a value](#repeating-an-argument-to-increase-a-value)
|
||||||
* [Mutually Exclusive Group](#mutually-exclusive-group)
|
* [Mutually Exclusive Group](#mutually-exclusive-group)
|
||||||
|
* [Storing values into variables](#store-into)
|
||||||
* [Negative Numbers](#negative-numbers)
|
* [Negative Numbers](#negative-numbers)
|
||||||
* [Combining Positional and Optional Arguments](#combining-positional-and-optional-arguments)
|
* [Combining Positional and Optional Arguments](#combining-positional-and-optional-arguments)
|
||||||
* [Printing Help](#printing-help)
|
* [Printing Help](#printing-help)
|
||||||
@ -316,6 +317,36 @@ foo@bar:/home/dev/$ ./main
|
|||||||
One of the arguments '--first VAR' or '--second VAR' is required
|
One of the arguments '--first VAR' or '--second VAR' is required
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Storing values into variables
|
||||||
|
|
||||||
|
It is possible to bind arguments to a variable storing their value, as an
|
||||||
|
alternative to explicitly calling ``program.get<T>(arg_name)`` or ``program[arg_name]``
|
||||||
|
|
||||||
|
This is currently implementeted for variables of type ``bool`` (this also
|
||||||
|
implicitly calls ``flag()``), ``int``, ``double``, ``std::string`` and
|
||||||
|
``std::vector<std::string>``. If the argument is not specified in the command
|
||||||
|
line, the default value (if set) is set into the variable.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
bool flagvar = false;
|
||||||
|
program.add_argument("--flagvar").store_into(flagvar);
|
||||||
|
|
||||||
|
int intvar = 0;
|
||||||
|
program.add_argument("--intvar").store_into(intvar);
|
||||||
|
|
||||||
|
double doublevar = 0;
|
||||||
|
program.add_argument("--doublevar").store_into(doublevar);
|
||||||
|
|
||||||
|
std::string strvar;
|
||||||
|
program.add_argument("--strvar").store_into(strvar);
|
||||||
|
|
||||||
|
std::vector<std::string> strvar_repeated;
|
||||||
|
program.add_argument("--strvar-repeated").append().store_into(strvar_repeated);
|
||||||
|
|
||||||
|
std::vector<std::string> strvar_multi_valued;
|
||||||
|
program.add_argument("--strvar-multi-valued").nargs(2).store_into(strvar_multi_valued);
|
||||||
|
```
|
||||||
|
|
||||||
### Negative Numbers
|
### Negative Numbers
|
||||||
|
|
||||||
Optional arguments start with ```-```. Can ```argparse``` handle negative numbers? The answer is yes!
|
Optional arguments start with ```-```. Can ```argparse``` handle negative numbers? The answer is yes!
|
||||||
|
@ -689,6 +689,57 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &store_into(bool &var) {
|
||||||
|
flag();
|
||||||
|
if (m_default_value.has_value()) {
|
||||||
|
var = std::any_cast<bool>(m_default_value);
|
||||||
|
}
|
||||||
|
action([&var](const auto & /*unused*/) { var = true; });
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &store_into(int &var) {
|
||||||
|
if (m_default_value.has_value()) {
|
||||||
|
var = std::any_cast<int>(m_default_value);
|
||||||
|
}
|
||||||
|
action([&var](const auto &s) {
|
||||||
|
var = details::parse_number<int, details::radix_10>()(s);
|
||||||
|
});
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &store_into(double &var) {
|
||||||
|
if (m_default_value.has_value()) {
|
||||||
|
var = std::any_cast<double>(m_default_value);
|
||||||
|
}
|
||||||
|
action([&var](const auto &s) {
|
||||||
|
var = details::parse_number<double, details::chars_format::general>()(s);
|
||||||
|
});
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &store_into(std::string &var) {
|
||||||
|
if (m_default_value.has_value()) {
|
||||||
|
var = std::any_cast<std::string>(m_default_value);
|
||||||
|
}
|
||||||
|
action([&var](const std::string &s) { var = s; });
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &store_into(std::vector<std::string> &var) {
|
||||||
|
if (m_default_value.has_value()) {
|
||||||
|
var = std::any_cast<std::vector<std::string>>(m_default_value);
|
||||||
|
}
|
||||||
|
action([this, &var](const std::string &s) {
|
||||||
|
if (!m_is_used) {
|
||||||
|
var.clear();
|
||||||
|
}
|
||||||
|
m_is_used = true;
|
||||||
|
var.push_back(s);
|
||||||
|
});
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
auto &append() {
|
auto &append() {
|
||||||
m_is_repeatable = true;
|
m_is_repeatable = true;
|
||||||
return *this;
|
return *this;
|
||||||
@ -852,7 +903,6 @@ public:
|
|||||||
if (!m_is_repeatable && m_is_used) {
|
if (!m_is_repeatable && m_is_used) {
|
||||||
throw std::runtime_error("Duplicate argument");
|
throw std::runtime_error("Duplicate argument");
|
||||||
}
|
}
|
||||||
m_is_used = true;
|
|
||||||
m_used_name = used_name;
|
m_used_name = used_name;
|
||||||
|
|
||||||
if (m_choices.has_value()) {
|
if (m_choices.has_value()) {
|
||||||
@ -875,6 +925,7 @@ public:
|
|||||||
if (num_args_max == 0) {
|
if (num_args_max == 0) {
|
||||||
m_values.emplace_back(m_implicit_value);
|
m_values.emplace_back(m_implicit_value);
|
||||||
std::visit([](const auto &f) { f({}); }, m_action);
|
std::visit([](const auto &f) { f({}); }, m_action);
|
||||||
|
m_is_used = true;
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
if ((dist = static_cast<std::size_t>(std::distance(start, end))) >=
|
if ((dist = static_cast<std::size_t>(std::distance(start, end))) >=
|
||||||
@ -912,9 +963,11 @@ public:
|
|||||||
Argument &self;
|
Argument &self;
|
||||||
};
|
};
|
||||||
std::visit(ActionApply{start, end, *this}, m_action);
|
std::visit(ActionApply{start, end, *this}, m_action);
|
||||||
|
m_is_used = true;
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
if (m_default_value.has_value()) {
|
if (m_default_value.has_value()) {
|
||||||
|
m_is_used = true;
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Too few arguments for '" +
|
throw std::runtime_error("Too few arguments for '" +
|
||||||
|
@ -49,6 +49,7 @@ file(GLOB ARGPARSE_TEST_SOURCES
|
|||||||
test_repr.cpp
|
test_repr.cpp
|
||||||
test_required_arguments.cpp
|
test_required_arguments.cpp
|
||||||
test_scan.cpp
|
test_scan.cpp
|
||||||
|
test_store_into.cpp
|
||||||
test_stringstream.cpp
|
test_stringstream.cpp
|
||||||
test_version.cpp
|
test_version.cpp
|
||||||
test_subparsers.cpp
|
test_subparsers.cpp
|
||||||
|
161
test/test_store_into.cpp
Normal file
161
test/test_store_into.cpp
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#ifdef WITH_MODULE
|
||||||
|
import argparse;
|
||||||
|
#else
|
||||||
|
#include <argparse/argparse.hpp>
|
||||||
|
#endif
|
||||||
|
#include <doctest.hpp>
|
||||||
|
|
||||||
|
using doctest::test_suite;
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(bool), flag not specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
bool flag;
|
||||||
|
program.add_argument("--flag").store_into(flag);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(flag == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(bool), flag specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
bool flag;
|
||||||
|
program.add_argument("--flag").store_into(flag);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe", "--flag"});
|
||||||
|
REQUIRE(flag == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(int), no default value, non specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
int res = -1;
|
||||||
|
program.add_argument("--int-opt").store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(res == -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(int), default value, non specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
int res = -1;
|
||||||
|
program.add_argument("--int-opt").default_value(3).store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(res == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(int), default value, specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
int res = -1;
|
||||||
|
program.add_argument("--int-opt").default_value(3).store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe", "--int-opt", "5"});
|
||||||
|
REQUIRE(res == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(double), no default value, non specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
double res = -1;
|
||||||
|
program.add_argument("--double-opt").store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(res == -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(double), default value, non specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
double res = -1;
|
||||||
|
program.add_argument("--double-opt").default_value(3.5).store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(res == 3.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(double), default value, specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
double res = -1;
|
||||||
|
program.add_argument("--double-opt").default_value(3.5).store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe", "--double-opt", "5.5"});
|
||||||
|
REQUIRE(res == 5.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(string), no default value, non specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
std::string res = "init";
|
||||||
|
program.add_argument("--str-opt").store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(res == "init");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(string), default value, non specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
std::string res;
|
||||||
|
program.add_argument("--str-opt").default_value("default").store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(res == "default");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(string), default value, specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
std::string res;
|
||||||
|
program.add_argument("--str-opt").default_value("default").store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe", "--str-opt", "foo"});
|
||||||
|
REQUIRE(res == "foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(vector of string), no default value, non specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
std::vector<std::string> res;
|
||||||
|
program.add_argument("--strvector-opt").append().store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(res == std::vector<std::string>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(vector of string), default value, non specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
std::vector<std::string> res;
|
||||||
|
program.add_argument("--strvector-opt").append().default_value(
|
||||||
|
std::vector<std::string>{"a", "b"}).store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe"});
|
||||||
|
REQUIRE(res == std::vector<std::string>{"a", "b"});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(vector of string), default value, specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
std::vector<std::string> res;
|
||||||
|
program.add_argument("--strvector-opt").append().default_value(
|
||||||
|
std::vector<std::string>{"a", "b"}).store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe", "--strvector-opt", "foo", "--strvector-opt", "bar"});
|
||||||
|
REQUIRE(res == std::vector<std::string>{"foo", "bar"});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test store_into(vector of string), default value, multi valued, specified" *
|
||||||
|
test_suite("store_into")) {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
std::vector<std::string> res;
|
||||||
|
program.add_argument("--strvector-opt").nargs(2).default_value(
|
||||||
|
std::vector<std::string>{"a", "b"}).store_into(res);
|
||||||
|
|
||||||
|
program.parse_args({"./test.exe", "--strvector-opt", "foo", "bar"});
|
||||||
|
REQUIRE(res == std::vector<std::string>{"foo", "bar"});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user