Added support for list of arguments per parameter. Added nargs method

This commit is contained in:
Pranav Srinivas Kumar 2019-03-30 12:58:28 -04:00
parent 57778cb3a6
commit 16e3f58ce9
2 changed files with 71 additions and 18 deletions

View File

@ -29,8 +29,8 @@ struct Argument {
std::string mHelp; std::string mHelp;
std::function<std::any()> mDefaultValue; std::function<std::any()> mDefaultValue;
std::function<std::any(const std::string&)> mAction; std::function<std::any(const std::string&)> mAction;
std::any mValue; std::vector<std::any> mValues;
std::string mRawValue; std::vector<std::string> mRawValues;
size_t mNumArgs; size_t mNumArgs;
Argument() : Argument() :
@ -38,8 +38,8 @@ struct Argument {
mHelp(""), mHelp(""),
mDefaultValue(nullptr), mDefaultValue(nullptr),
mAction([](const std::string& aValue) { return aValue; }), mAction([](const std::string& aValue) { return aValue; }),
mValue(nullptr), mValues({}),
mRawValue(""), mRawValues({}),
mNumArgs(1) {} mNumArgs(1) {}
Argument& help(const std::string& aHelp) { Argument& help(const std::string& aHelp) {
@ -64,7 +64,7 @@ struct Argument {
template <typename T> template <typename T>
T get() { T get() {
if (!mValue.has_value()) { if (mValues.size() == 0) {
if (mDefaultValue != nullptr) { if (mDefaultValue != nullptr) {
return std::any_cast<T>(mDefaultValue()); return std::any_cast<T>(mDefaultValue());
} }
@ -72,8 +72,8 @@ struct Argument {
return T(); return T();
} }
else { else {
if (mRawValue != "") if (mRawValues.size() > 0)
return std::any_cast<T>(mValue); return std::any_cast<T>(mValues[0]);
else { else {
if (mDefaultValue != nullptr) if (mDefaultValue != nullptr)
return std::any_cast<T>(mDefaultValue()); return std::any_cast<T>(mDefaultValue());
@ -83,6 +83,43 @@ struct Argument {
} }
} }
template <typename T>
std::vector<T> get_list() {
std::vector<T> tResult;
if (mValues.size() == 0) {
if (mDefaultValue != nullptr) {
std::any tDefaultValueLambdaResult = mDefaultValue();
std::vector<T> tDefaultValues = std::any_cast<std::vector<T>>(tDefaultValueLambdaResult);
for (size_t i = 0; i < tDefaultValues.size(); i++) {
tResult.push_back(std::any_cast<T>(tDefaultValues[i]));
}
return tResult;
}
else
return std::vector<T>();
}
else {
if (mRawValues.size() > 0) {
for (size_t i = 0; i < mValues.size(); i++) {
tResult.push_back(std::any_cast<T>(mValues[i]));
}
return tResult;
}
else {
if (mDefaultValue != nullptr) {
std::any tDefaultValueLambdaResult = mDefaultValue();
std::vector<T> tDefaultValues = std::any_cast<std::vector<T>>(tDefaultValueLambdaResult);
for (size_t i = 0; i < tDefaultValues.size(); i++) {
tResult.push_back(std::any_cast<T>(tDefaultValues[i]));
}
return tResult;
}
else
return std::vector<T>();
}
}
}
}; };
class ArgumentParser { class ArgumentParser {
@ -112,14 +149,14 @@ class ArgumentParser {
while (tCount > 0) { while (tCount > 0) {
i = i + 1; i = i + 1;
if (i < argc) { if (i < argc) {
tArgument->mRawValue = argv[i]; tArgument->mRawValues.push_back(argv[i]);
if (tArgument->mAction != nullptr) if (tArgument->mAction != nullptr)
tArgument->mValue = tArgument->mAction(argv[i]); tArgument->mValues.push_back(tArgument->mAction(argv[i]));
else { else {
if (tArgument->mDefaultValue != nullptr) if (tArgument->mDefaultValue != nullptr)
tArgument->mValue = tArgument->mDefaultValue(); tArgument->mValues.push_back(tArgument->mDefaultValue());
else else
tArgument->mValue = std::string(argv[i]); tArgument->mValues.push_back(std::string(argv[i]));
} }
} }
tCount -= 1; tCount -= 1;
@ -139,15 +176,22 @@ class ArgumentParser {
template <typename T = std::string> template <typename T = std::string>
T get(const char * aArgumentName) { T get(const char * aArgumentName) {
for (auto& tArgument : mArguments) { std::map<std::string, std::shared_ptr<Argument>>::iterator tIterator = mArgumentMap.find(aArgumentName);
auto tIndex = std::find(tArgument->mNames.begin(), tArgument->mNames.end(), aArgumentName); if (tIterator != mArgumentMap.end()) {
if (tIndex != tArgument->mNames.end()) { return tIterator->second->get<T>();
return tArgument->get<T>();
}
} }
return T(); return T();
} }
template <typename T>
std::vector<T> get_list(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 std::vector<T>();
}
private: private:
Argument& add_argument_internal(std::shared_ptr<Argument> aArgument) { Argument& add_argument_internal(std::shared_ptr<Argument> aArgument) {
return *aArgument; return *aArgument;

View File

@ -11,20 +11,29 @@ int main(int argc, char * argv[]) {
program.add_argument("-n", "--num_iterations") program.add_argument("-n", "--num_iterations")
.help("Number of iterations") .help("Number of iterations")
.nargs(2)
.action([](const std::string& value) { return std::stoi(value); }); .action([](const std::string& value) { return std::stoi(value); });
program.add_argument("-v", "--verbose", "VERBOSE") program.add_argument("-v", "--verbose", "VERBOSE")
.default_value([]() { return true; }); .nargs(0)
.default_value([]() { return false; });
program.add_argument("--test_inputs")
.nargs(3)
.default_value([]() { return std::vector<int>{ 1, 2, 3 }; })
.action([](const std::string& value) { return std::stoi(value); });
program.parse_args(argc, argv); program.parse_args(argc, argv);
auto config_file = program.get<std::string>("--config"); auto config_file = program.get<std::string>("--config");
auto num_iters = program.get<int>("-n"); auto num_iters = program.get<int>("-n");
auto verbose = program.get<bool>("-v"); auto verbose = program.get<bool>("-v");
auto test_inputs = program.get_list<int>("--test_inputs");
std::cout << config_file << std::endl; std::cout << config_file << std::endl;
std::cout << num_iters << std::endl; std::cout << num_iters << std::endl;
std::cout << verbose << std::endl; std::cout << verbose << std::endl;
for (auto& input : test_inputs)
std::cout << input << std::endl;
return 0; return 0;
} }