Removed get_arguments API from ArgumentParser. Improved print_help

This commit is contained in:
Pranav Srinivas Kumar 2019-03-31 20:28:22 -04:00
parent 96e9bc33b9
commit 6a4c92726b
9 changed files with 20 additions and 98 deletions

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <iostream>
#include <string> #include <string>
#include <map> #include <map>
#include <vector> #include <vector>
@ -242,7 +243,14 @@ class ArgumentParser {
public: public:
ArgumentParser(const std::string& aProgramName = "") : ArgumentParser(const std::string& aProgramName = "") :
mProgramName(aProgramName), mProgramName(aProgramName),
mNextPositionalArgument(0) {} mNextPositionalArgument(0) {
std::shared_ptr<Argument> tArgument = std::make_shared<Argument>();
tArgument->mNames = { "-h", "--help" };
tArgument->mHelp = "show this help message and exit";
mOptionalArguments.push_back(tArgument);
upsert(mArgumentMap, std::string("-h"), tArgument);
upsert(mArgumentMap, std::string("--help"), tArgument);
}
template<typename T, typename... Targs> template<typename T, typename... Targs>
Argument& add_argument(T value, Targs... Fargs) { Argument& add_argument(T value, Targs... Fargs) {
@ -278,7 +286,11 @@ class ArgumentParser {
if (mProgramName == "" && argc > 0) if (mProgramName == "" && argc > 0)
mProgramName = argv[0]; mProgramName = argv[0];
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
auto tCurrentArgument = argv[i]; auto tCurrentArgument = std::string(argv[i]);
if (tCurrentArgument == "-h" || tCurrentArgument == "--help") {
print_help();
exit(0);
}
std::map<std::string, std::shared_ptr<Argument>>::iterator tIterator = mArgumentMap.find(argv[i]); std::map<std::string, std::shared_ptr<Argument>>::iterator tIterator = mArgumentMap.find(argv[i]);
if (tIterator != mArgumentMap.end()) { if (tIterator != mArgumentMap.end()) {
// Start parsing optional argument // Start parsing optional argument
@ -398,10 +410,6 @@ class ArgumentParser {
return T(); return T();
} }
std::map<std::string, std::shared_ptr<Argument>> get_arguments() const {
return mArgumentMap;
}
Argument& operator[](const std::string& aArgumentName) { Argument& operator[](const std::string& aArgumentName) {
std::map<std::string, std::shared_ptr<Argument>>::iterator tIterator = mArgumentMap.find(aArgumentName); std::map<std::string, std::shared_ptr<Argument>>::iterator tIterator = mArgumentMap.find(aArgumentName);
if (tIterator != mArgumentMap.end()) { if (tIterator != mArgumentMap.end()) {
@ -423,7 +431,8 @@ class ArgumentParser {
} }
stream << "\n\n"; stream << "\n\n";
stream << "Positional arguments:\n"; if (mPositionalArguments.size() > 0)
stream << "Positional arguments:\n";
for (size_t i = 0; i < mPositionalArguments.size(); i++) { for (size_t i = 0; i < mPositionalArguments.size(); i++) {
size_t tCurrentLength = 0; size_t tCurrentLength = 0;
auto tNames = mPositionalArguments[i]->mNames; auto tNames = mPositionalArguments[i]->mNames;
@ -445,7 +454,10 @@ class ArgumentParser {
stream << mPositionalArguments[i]->mHelp << "\n"; stream << mPositionalArguments[i]->mHelp << "\n";
} }
stream << "\nOptional arguments:\n"; if (mOptionalArguments.size() > 0 && mPositionalArguments.size() > 0)
stream << "\nOptional arguments:\n";
else if (mOptionalArguments.size() > 0)
stream << "Optional arguments:\n";
for (size_t i = 0; i < mOptionalArguments.size(); i++) { for (size_t i = 0; i < mOptionalArguments.size(); i++) {
size_t tCurrentLength = 0; size_t tCurrentLength = 0;
auto tNames = mOptionalArguments[i]->mNames; auto tNames = mOptionalArguments[i]->mNames;

View File

@ -1,7 +1,6 @@
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include <iostream> #include <iostream>
#include <argparse.hpp> #include <argparse.hpp>
#include <test_add_argument.hpp>
#include <test_parse_args.hpp> #include <test_parse_args.hpp>
#include <test_positional_arguments.hpp> #include <test_positional_arguments.hpp>
#include <test_optional_arguments.hpp> #include <test_optional_arguments.hpp>

View File

@ -15,7 +15,5 @@ TEST_CASE("Users can use defaul value inside actions", "[actions]") {
}); });
program.parse_args({ "test", "fez" }); program.parse_args({ "test", "fez" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get("input") == "bar"); REQUIRE(program.get("input") == "bar");
} }

View File

@ -1,32 +0,0 @@
#pragma once
#include <catch.hpp>
#include <argparse.hpp>
TEST_CASE("Add a simple argument", "[add_argument]") {
argparse::ArgumentParser program("test");
program.add_argument("--foo");
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(arguments["--foo"] != nullptr);
REQUIRE(arguments["--foo"]->mNames == std::vector<std::string>{"--foo"});
REQUIRE(arguments["--foo"]->mHelp == "");
REQUIRE(arguments["--foo"]->mNumArgs == 1);
REQUIRE(arguments["--foo"]->mRawValues.size() == 0);
REQUIRE(arguments["--foo"]->mValues.size() == 0);
}
TEST_CASE("Add a simple argument with help", "[add_argument]") {
argparse::ArgumentParser program("test");
program.add_argument("--foo")
.help("input file");
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(arguments["--foo"] != nullptr);
REQUIRE(arguments["--foo"]->mNames == std::vector<std::string>{"--foo"});
REQUIRE(arguments["--foo"]->mHelp == "input file");
REQUIRE(arguments["--foo"]->mNumArgs == 1);
REQUIRE(arguments["--foo"]->mRawValues.size() == 0);
REQUIRE(arguments["--foo"]->mValues.size() == 0);
}

View File

@ -17,8 +17,6 @@ TEST_CASE("Parse compound toggle arguments with implicit values", "[compound_arg
.implicit_value(true); .implicit_value(true);
program.parse_args({ "./test.exe", "-aux" }); program.parse_args({ "./test.exe", "-aux" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 3);
REQUIRE(program.get<bool>("-a") == true); REQUIRE(program.get<bool>("-a") == true);
REQUIRE(program.get<bool>("-u") == true); REQUIRE(program.get<bool>("-u") == true);
REQUIRE(program.get<bool>("-x") == true); REQUIRE(program.get<bool>("-x") == true);
@ -43,8 +41,6 @@ TEST_CASE("Parse compound toggle arguments with implicit values and nargs", "[co
program.parse_args({ "./test.exe", "-abc", "3.14", "2.718", "--input_files", program.parse_args({ "./test.exe", "-abc", "3.14", "2.718", "--input_files",
"a.txt", "b.txt", "c.txt" }); "a.txt", "b.txt", "c.txt" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 4);
REQUIRE(program.get<bool>("-a") == true); REQUIRE(program.get<bool>("-a") == true);
REQUIRE(program.get<bool>("-b") == true); REQUIRE(program.get<bool>("-b") == true);
auto c = program.get<std::vector<float>>("-c"); auto c = program.get<std::vector<float>>("-c");
@ -83,8 +79,6 @@ TEST_CASE("Parse compound toggle arguments with implicit values and nargs and ot
program.parse_args({ "./test.exe", "1", "-abc", "3.14", "2.718", "2", "--input_files", program.parse_args({ "./test.exe", "1", "-abc", "3.14", "2.718", "2", "--input_files",
"a.txt", "b.txt", "c.txt", "3" }); "a.txt", "b.txt", "c.txt", "3" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 5);
REQUIRE(program.get<bool>("-a") == true); REQUIRE(program.get<bool>("-a") == true);
REQUIRE(program.get<bool>("-b") == true); REQUIRE(program.get<bool>("-b") == true);
auto c = program.get<std::vector<float>>("-c"); auto c = program.get<std::vector<float>>("-c");

View File

@ -9,9 +9,6 @@ TEST_CASE("Parse vector of arguments", "[vector]") {
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv" }); 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"); auto inputs = program.get<std::vector<std::string>>("input");
REQUIRE(inputs.size() == 2); REQUIRE(inputs.size() == 2);
REQUIRE(inputs[0] == "rocket.mesh"); REQUIRE(inputs[0] == "rocket.mesh");
@ -25,8 +22,6 @@ TEST_CASE("Parse list of arguments", "[vector]") {
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv" }); 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"); auto inputs = program.get<std::list<std::string>>("input");
REQUIRE(inputs.size() == 2); REQUIRE(inputs.size() == 2);
REQUIRE(argparse::get_from_list(inputs, 0) == "rocket.mesh"); REQUIRE(argparse::get_from_list(inputs, 0) == "rocket.mesh");
@ -41,8 +36,6 @@ TEST_CASE("Parse list of arguments with default values", "[vector]") {
program.parse_args({ "test" }); program.parse_args({ "test" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
auto inputs = program.get<std::list<int>>("input"); auto inputs = program.get<std::list<int>>("input");
REQUIRE(inputs.size() == 5); REQUIRE(inputs.size() == 5);
REQUIRE(argparse::get_from_list(inputs, 0) == 1); REQUIRE(argparse::get_from_list(inputs, 0) == 1);

View File

@ -9,8 +9,6 @@ TEST_CASE("Parse toggle arguments with default value", "[optional_arguments]") {
.implicit_value(true); .implicit_value(true);
program.parse_args({ "./test.exe" }); program.parse_args({ "./test.exe" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 2);
REQUIRE(program.get<bool>("--verbose") == false); REQUIRE(program.get<bool>("--verbose") == false);
REQUIRE(program["--verbose"] == false); REQUIRE(program["--verbose"] == false);
} }
@ -22,8 +20,6 @@ TEST_CASE("Parse toggle arguments with implicit value", "[optional_arguments]")
.implicit_value(true); .implicit_value(true);
program.parse_args({ "./test.exe", "--verbose" }); program.parse_args({ "./test.exe", "--verbose" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get<bool>("--verbose") == true); REQUIRE(program.get<bool>("--verbose") == true);
REQUIRE(program["--verbose"] == true); REQUIRE(program["--verbose"] == true);
REQUIRE(program["--verbose"] != false); REQUIRE(program["--verbose"] != false);
@ -44,8 +40,6 @@ TEST_CASE("Parse multiple toggle arguments with implicit values", "[optional_arg
.implicit_value(true); .implicit_value(true);
program.parse_args({ "./test.exe", "-a", "-x" }); program.parse_args({ "./test.exe", "-a", "-x" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 3);
REQUIRE(program.get<bool>("-a") == true); REQUIRE(program.get<bool>("-a") == true);
REQUIRE(program.get<bool>("-u") == false); REQUIRE(program.get<bool>("-u") == false);
REQUIRE(program.get<bool>("-x") == true); REQUIRE(program.get<bool>("-x") == true);

View File

@ -6,8 +6,6 @@ TEST_CASE("Parse a string argument with value", "[parse_args]") {
argparse::ArgumentParser program("test"); argparse::ArgumentParser program("test");
program.add_argument("--config"); program.add_argument("--config");
program.parse_args({ "test", "--config", "config.yml"}); program.parse_args({ "test", "--config", "config.yml"});
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get("--config") == "config.yml"); REQUIRE(program.get("--config") == "config.yml");
} }
@ -16,8 +14,6 @@ TEST_CASE("Parse a string argument with default value", "[parse_args]") {
program.add_argument("--config") program.add_argument("--config")
.default_value(std::string("foo.yml")); .default_value(std::string("foo.yml"));
program.parse_args({ "test", "--config" }); program.parse_args({ "test", "--config" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get("--config") == "foo.yml"); REQUIRE(program.get("--config") == "foo.yml");
} }
@ -26,8 +22,6 @@ TEST_CASE("Parse an int argument with value", "[parse_args]") {
program.add_argument("--count") program.add_argument("--count")
.action([](const std::string& value) { return std::stoi(value); }); .action([](const std::string& value) { return std::stoi(value); });
program.parse_args({ "test", "--count", "5" }); program.parse_args({ "test", "--count", "5" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get<int>("--count") == 5); REQUIRE(program.get<int>("--count") == 5);
} }
@ -37,8 +31,6 @@ TEST_CASE("Parse an int argument with default value", "[parse_args]") {
.default_value(2) .default_value(2)
.action([](const std::string& value) { return std::stoi(value); }); .action([](const std::string& value) { return std::stoi(value); });
program.parse_args({ "test", "--count" }); program.parse_args({ "test", "--count" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get<int>("--count") == 2); REQUIRE(program.get<int>("--count") == 2);
} }
@ -47,8 +39,6 @@ TEST_CASE("Parse a float argument with value", "[parse_args]") {
program.add_argument("--ratio") program.add_argument("--ratio")
.action([](const std::string& value) { return std::stof(value); }); .action([](const std::string& value) { return std::stof(value); });
program.parse_args({ "test", "--ratio", "5.6645" }); program.parse_args({ "test", "--ratio", "5.6645" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get<float>("--ratio") == 5.6645f); REQUIRE(program.get<float>("--ratio") == 5.6645f);
} }
@ -58,8 +48,6 @@ TEST_CASE("Parse a float argument with default value", "[parse_args]") {
.default_value(3.14f) .default_value(3.14f)
.action([](const std::string& value) { return std::stof(value); }); .action([](const std::string& value) { return std::stof(value); });
program.parse_args({ "test", "--ratio" }); program.parse_args({ "test", "--ratio" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get<float>("--ratio") == 3.14f); REQUIRE(program.get<float>("--ratio") == 3.14f);
} }
@ -68,8 +56,6 @@ TEST_CASE("Parse a double argument with value", "[parse_args]") {
program.add_argument("--ratio") program.add_argument("--ratio")
.action([](const std::string& value) { return std::stod(value); }); .action([](const std::string& value) { return std::stod(value); });
program.parse_args({ "test", "--ratio", "5.6645" }); program.parse_args({ "test", "--ratio", "5.6645" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get<double>("--ratio") == 5.6645); REQUIRE(program.get<double>("--ratio") == 5.6645);
} }
@ -79,8 +65,6 @@ TEST_CASE("Parse a double argument with default value", "[parse_args]") {
.default_value(3.14) .default_value(3.14)
.action([](const std::string& value) { return std::stod(value); }); .action([](const std::string& value) { return std::stod(value); });
program.parse_args({ "test", "--ratio" }); program.parse_args({ "test", "--ratio" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
REQUIRE(program.get<double>("--ratio") == 3.14); REQUIRE(program.get<double>("--ratio") == 3.14);
} }
@ -90,8 +74,6 @@ TEST_CASE("Parse a vector of integer arguments", "[parse_args]") {
.nargs(5) .nargs(5)
.action([](const std::string& value) { return std::stoi(value); }); .action([](const std::string& value) { return std::stoi(value); });
program.parse_args({ "test", "--vector", "1", "2", "3", "4", "5" }); program.parse_args({ "test", "--vector", "1", "2", "3", "4", "5" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
auto vector = program.get<std::vector<int>>("--vector"); auto vector = program.get<std::vector<int>>("--vector");
REQUIRE(vector.size() == 5); REQUIRE(vector.size() == 5);
REQUIRE(vector[0] == 1); REQUIRE(vector[0] == 1);
@ -107,8 +89,6 @@ TEST_CASE("Parse a vector of float arguments", "[parse_args]") {
.nargs(5) .nargs(5)
.action([](const std::string& value) { return std::stof(value); }); .action([](const std::string& value) { return std::stof(value); });
program.parse_args({ "test", "--vector", "1.1", "2.2", "3.3", "4.4", "5.5" }); program.parse_args({ "test", "--vector", "1.1", "2.2", "3.3", "4.4", "5.5" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
auto vector = program.get<std::vector<float>>("--vector"); auto vector = program.get<std::vector<float>>("--vector");
REQUIRE(vector.size() == 5); REQUIRE(vector.size() == 5);
REQUIRE(vector[0] == 1.1f); REQUIRE(vector[0] == 1.1f);
@ -124,8 +104,6 @@ TEST_CASE("Parse a vector of double arguments", "[parse_args]") {
.nargs(5) .nargs(5)
.action([](const std::string& value) { return std::stod(value); }); .action([](const std::string& value) { return std::stod(value); });
program.parse_args({ "test", "--vector", "1.1", "2.2", "3.3", "4.4", "5.5" }); program.parse_args({ "test", "--vector", "1.1", "2.2", "3.3", "4.4", "5.5" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
auto vector = program.get<std::vector<double>>("--vector"); auto vector = program.get<std::vector<double>>("--vector");
REQUIRE(vector.size() == 5); REQUIRE(vector.size() == 5);
REQUIRE(vector[0] == 1.1); REQUIRE(vector[0] == 1.1);
@ -141,8 +119,6 @@ TEST_CASE("Parse a vector of string arguments", "[parse_args]") {
.nargs(5) .nargs(5)
.action([](const std::string& value) { return value; }); .action([](const std::string& value) { return value; });
program.parse_args({ "test", "--vector", "abc", "def", "ghi", "jkl", "mno" }); program.parse_args({ "test", "--vector", "abc", "def", "ghi", "jkl", "mno" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
auto vector = program.get<std::vector<std::string>>("--vector"); auto vector = program.get<std::vector<std::string>>("--vector");
REQUIRE(vector.size() == 5); REQUIRE(vector.size() == 5);
REQUIRE(vector[0] == "abc"); REQUIRE(vector[0] == "abc");
@ -158,8 +134,6 @@ TEST_CASE("Parse a vector of character arguments", "[parse_args]") {
.nargs(5) .nargs(5)
.action([](const std::string& value) { return value[0]; }); .action([](const std::string& value) { return value[0]; });
program.parse_args({ "test", "--vector", "a", "b", "c", "d", "e" }); program.parse_args({ "test", "--vector", "a", "b", "c", "d", "e" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
auto vector = program.get<std::vector<char>>("--vector"); auto vector = program.get<std::vector<char>>("--vector");
REQUIRE(vector.size() == 5); REQUIRE(vector.size() == 5);
REQUIRE(vector[0] == 'a'); REQUIRE(vector[0] == 'a');
@ -182,8 +156,6 @@ TEST_CASE("Parse a vector of string arguments and construct objects", "[parse_ar
.nargs(5) .nargs(5)
.action([](const std::string& value) { return Foo(value); }); .action([](const std::string& value) { return Foo(value); });
program.parse_args({ "test", "--vector", "abc", "def", "ghi", "jkl", "mno" }); program.parse_args({ "test", "--vector", "abc", "def", "ghi", "jkl", "mno" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1);
auto vector = program.get<std::vector<Foo>>("--vector"); auto vector = program.get<std::vector<Foo>>("--vector");
REQUIRE(vector.size() == 5); REQUIRE(vector.size() == 5);
REQUIRE(vector[0].value == Foo("abc").value); REQUIRE(vector[0].value == Foo("abc").value);

View File

@ -7,8 +7,6 @@ TEST_CASE("Parse positional arguments", "[positional_arguments]") {
program.add_argument("input"); program.add_argument("input");
program.add_argument("output"); program.add_argument("output");
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv" }); program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 2);
REQUIRE(program.get("input") == "rocket.mesh"); REQUIRE(program.get("input") == "rocket.mesh");
REQUIRE(program.get("output") == "thrust_profile.csv"); REQUIRE(program.get("output") == "thrust_profile.csv");
} }
@ -18,8 +16,6 @@ TEST_CASE("Parse positional arguments with fixed nargs", "[positional_arguments]
program.add_argument("input"); program.add_argument("input");
program.add_argument("output").nargs(2); program.add_argument("output").nargs(2);
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv", "output.mesh" }); program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv", "output.mesh" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 2);
REQUIRE(program.get("input") == "rocket.mesh"); REQUIRE(program.get("input") == "rocket.mesh");
auto outputs = program.get<std::vector<std::string>>("output"); auto outputs = program.get<std::vector<std::string>>("output");
REQUIRE(outputs.size() == 2); REQUIRE(outputs.size() == 2);
@ -34,8 +30,6 @@ TEST_CASE("Parse positional arguments with optional arguments", "[positional_arg
program.add_argument("--num_iterations") program.add_argument("--num_iterations")
.action([](const std::string& value) { return std::stoi(value); }); .action([](const std::string& value) { return std::stoi(value); });
program.parse_args({ "test", "rocket.mesh", "--num_iterations", "15", "thrust_profile.csv", "output.mesh" }); program.parse_args({ "test", "rocket.mesh", "--num_iterations", "15", "thrust_profile.csv", "output.mesh" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 3);
REQUIRE(program.get<int>("--num_iterations") == 15); REQUIRE(program.get<int>("--num_iterations") == 15);
REQUIRE(program.get("input") == "rocket.mesh"); REQUIRE(program.get("input") == "rocket.mesh");
auto outputs = program.get<std::vector<std::string>>("output"); auto outputs = program.get<std::vector<std::string>>("output");
@ -51,8 +45,6 @@ TEST_CASE("Parse positional arguments with optional arguments in the middle", "[
program.add_argument("--num_iterations") program.add_argument("--num_iterations")
.action([](const std::string& value) { return std::stoi(value); }); .action([](const std::string& value) { return std::stoi(value); });
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv", "--num_iterations", "15", "output.mesh" }); program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv", "--num_iterations", "15", "output.mesh" });
auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 3);
REQUIRE(program.get<int>("--num_iterations") == 15); REQUIRE(program.get<int>("--num_iterations") == 15);
REQUIRE(program.get("input") == "rocket.mesh"); REQUIRE(program.get("input") == "rocket.mesh");
auto outputs = program.get<std::vector<std::string>>("output"); auto outputs = program.get<std::vector<std::string>>("output");