mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 15:14:39 +00:00
Add Argument::store_into() functions
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); ```
This commit is contained in:
parent
c69d8e1960
commit
8784cc8ddf
31
README.md
31
README.md
@ -26,6 +26,7 @@
|
||||
* [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)
|
||||
* [Mutually Exclusive Group](#mutually-exclusive-group)
|
||||
* [Storing values into variables](#store-into)
|
||||
* [Negative Numbers](#negative-numbers)
|
||||
* [Combining Positional and Optional Arguments](#combining-positional-and-optional-arguments)
|
||||
* [Printing Help](#printing-help)
|
||||
@ -315,6 +316,36 @@ foo@bar:/home/dev/$ ./main
|
||||
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
|
||||
|
||||
Optional arguments start with ```-```. Can ```argparse``` handle negative numbers? The answer is yes!
|
||||
|
@ -689,6 +689,57 @@ public:
|
||||
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() {
|
||||
m_is_repeatable = true;
|
||||
return *this;
|
||||
@ -852,7 +903,6 @@ public:
|
||||
if (!m_is_repeatable && m_is_used) {
|
||||
throw std::runtime_error("Duplicate argument");
|
||||
}
|
||||
m_is_used = true;
|
||||
m_used_name = used_name;
|
||||
|
||||
if (m_choices.has_value()) {
|
||||
@ -875,6 +925,7 @@ public:
|
||||
if (num_args_max == 0) {
|
||||
m_values.emplace_back(m_implicit_value);
|
||||
std::visit([](const auto &f) { f({}); }, m_action);
|
||||
m_is_used = true;
|
||||
return start;
|
||||
}
|
||||
if ((dist = static_cast<std::size_t>(std::distance(start, end))) >=
|
||||
@ -912,9 +963,11 @@ public:
|
||||
Argument &self;
|
||||
};
|
||||
std::visit(ActionApply{start, end, *this}, m_action);
|
||||
m_is_used = true;
|
||||
return end;
|
||||
}
|
||||
if (m_default_value.has_value()) {
|
||||
m_is_used = true;
|
||||
return start;
|
||||
}
|
||||
throw std::runtime_error("Too few arguments for '" +
|
||||
|
@ -49,6 +49,7 @@ file(GLOB ARGPARSE_TEST_SOURCES
|
||||
test_repr.cpp
|
||||
test_required_arguments.cpp
|
||||
test_scan.cpp
|
||||
test_store_into.cpp
|
||||
test_stringstream.cpp
|
||||
test_version.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