mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 07:04:39 +00:00
Support for std::list in ArgumentParser
This commit is contained in:
parent
050309cd7c
commit
34c9ec8a97
@ -2,6 +2,7 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <functional>
|
||||
#include <any>
|
||||
#include <memory>
|
||||
@ -38,6 +39,16 @@ bool starts_with(const std::string& haystack, const std::string& needle) {
|
||||
&& std::equal(needle.begin(), needle.end(), haystack.begin());
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T get_from_list(const std::list<T>& aList, size_t aIndex) {
|
||||
if (aList.size() > aIndex) {
|
||||
auto tIterator = aList.begin();
|
||||
std::advance(tIterator, aIndex);
|
||||
return *tIterator;
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
struct Argument {
|
||||
std::vector<std::string> mNames;
|
||||
std::string mHelp;
|
||||
@ -142,11 +153,46 @@ struct Argument {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_list() {
|
||||
T tResult;
|
||||
if (mValues.size() == 0) {
|
||||
if (mDefaultValue.has_value()) {
|
||||
T tDefaultValues = std::any_cast<T>(mDefaultValue);
|
||||
for (size_t i = 0; i < tDefaultValues.size(); i++) {
|
||||
tResult.push_back(std::any_cast<typename T::value_type>(get_from_list(tDefaultValues, i)));
|
||||
}
|
||||
return tResult;
|
||||
}
|
||||
else
|
||||
return T();
|
||||
}
|
||||
else {
|
||||
if (mRawValues.size() > 0) {
|
||||
for (size_t i = 0; i < mValues.size(); i++) {
|
||||
tResult.push_back(std::any_cast<typename T::value_type>(mValues[i]));
|
||||
}
|
||||
return tResult;
|
||||
}
|
||||
else {
|
||||
if (mDefaultValue.has_value()) {
|
||||
std::list<T> tDefaultValues = std::any_cast<std::list<T>>(mDefaultValue);
|
||||
for (size_t i = 0; i < tDefaultValues.size(); i++) {
|
||||
tResult.push_back(std::any_cast<typename T::value_type>(get_from_list(tDefaultValues, i)));
|
||||
}
|
||||
return tResult;
|
||||
}
|
||||
else
|
||||
return T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ArgumentParser {
|
||||
public:
|
||||
ArgumentParser(const std::string& aProgramName) :
|
||||
ArgumentParser(const std::string& aProgramName = "") :
|
||||
mProgramName(aProgramName),
|
||||
mNextPositionalArgument(0) {}
|
||||
|
||||
@ -179,6 +225,8 @@ class ArgumentParser {
|
||||
}
|
||||
|
||||
void parse_args(int argc, char * argv[]) {
|
||||
if (mProgramName == "" && argc > 0)
|
||||
mProgramName = argv[0];
|
||||
for (int i = 1; i < argc; i++) {
|
||||
auto tCurrentArgument = argv[i];
|
||||
std::map<std::string, std::shared_ptr<Argument>>::iterator tIterator = mArgumentMap.find(argv[i]);
|
||||
@ -270,7 +318,8 @@ class ArgumentParser {
|
||||
}
|
||||
|
||||
template <typename T = std::string>
|
||||
typename std::enable_if<is_specialization<T, std::vector>::value == false, T>::type
|
||||
typename std::enable_if<is_specialization<T, std::vector>::value == false &&
|
||||
is_specialization<T, std::list>::value == false, T>::type
|
||||
get(const char * aArgumentName) {
|
||||
std::map<std::string, std::shared_ptr<Argument>>::iterator tIterator = mArgumentMap.find(aArgumentName);
|
||||
if (tIterator != mArgumentMap.end()) {
|
||||
@ -289,6 +338,16 @@ class ArgumentParser {
|
||||
return T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<is_specialization<T, std::list>::value, T>::type
|
||||
get(const char * aArgumentName) {
|
||||
std::map<std::string, std::shared_ptr<Argument>>::iterator tIterator = mArgumentMap.find(aArgumentName);
|
||||
if (tIterator != mArgumentMap.end()) {
|
||||
return tIterator->second->get_list<T>();
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
std::map<std::string, std::shared_ptr<Argument>> get_arguments() const {
|
||||
return mArgumentMap;
|
||||
}
|
||||
|
@ -7,3 +7,4 @@
|
||||
#include <test_optional_arguments.hpp>
|
||||
#include <test_compound_arguments.hpp>
|
||||
#include <test_actions.hpp>
|
||||
#include <test_vector_list_arguments.hpp>
|
53
tests/test_vector_list_arguments.hpp
Normal file
53
tests/test_vector_list_arguments.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include <catch.hpp>
|
||||
#include <argparse.hpp>
|
||||
|
||||
TEST_CASE("Parse vector of arguments", "[vector]") {
|
||||
argparse::ArgumentParser program("test");
|
||||
program.add_argument("input")
|
||||
.nargs(2);
|
||||
|
||||
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv" });
|
||||
|
||||
auto arguments = program.get_arguments();
|
||||
REQUIRE(arguments.size() == 1);
|
||||
|
||||
auto inputs = program.get<std::vector<std::string>>("input");
|
||||
REQUIRE(inputs.size() == 2);
|
||||
REQUIRE(inputs[0] == "rocket.mesh");
|
||||
REQUIRE(inputs[1] == "thrust_profile.csv");
|
||||
}
|
||||
|
||||
TEST_CASE("Parse list of arguments", "[vector]") {
|
||||
argparse::ArgumentParser program("test");
|
||||
program.add_argument("input")
|
||||
.nargs(2);
|
||||
|
||||
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv" });
|
||||
|
||||
auto arguments = program.get_arguments();
|
||||
REQUIRE(arguments.size() == 1);
|
||||
auto inputs = program.get<std::list<std::string>>("input");
|
||||
REQUIRE(inputs.size() == 2);
|
||||
REQUIRE(argparse::get_from_list(inputs, 0) == "rocket.mesh");
|
||||
REQUIRE(argparse::get_from_list(inputs, 1) == "thrust_profile.csv");
|
||||
}
|
||||
|
||||
TEST_CASE("Parse list of arguments with default values", "[vector]") {
|
||||
argparse::ArgumentParser program("test");
|
||||
program.add_argument("input")
|
||||
.default_value(std::list<int>{1, 2, 3, 4, 5})
|
||||
.nargs(2);
|
||||
|
||||
program.parse_args({ "test" });
|
||||
|
||||
auto arguments = program.get_arguments();
|
||||
REQUIRE(arguments.size() == 1);
|
||||
auto inputs = program.get<std::list<int>>("input");
|
||||
REQUIRE(inputs.size() == 5);
|
||||
REQUIRE(argparse::get_from_list(inputs, 0) == 1);
|
||||
REQUIRE(argparse::get_from_list(inputs, 1) == 2);
|
||||
REQUIRE(argparse::get_from_list(inputs, 2) == 3);
|
||||
REQUIRE(argparse::get_from_list(inputs, 3) == 4);
|
||||
REQUIRE(argparse::get_from_list(inputs, 4) == 5);
|
||||
}
|
Loading…
Reference in New Issue
Block a user