Implemented Argument::operator== and Argument::operator!= with specializations for std::vector and std::list

This commit is contained in:
Pranav Srinivas Kumar 2019-03-31 16:27:18 -04:00
parent 28e084dfd8
commit 02f40c3721
3 changed files with 60 additions and 6 deletions

View File

@ -49,6 +49,11 @@ T get_from_list(const std::list<T>& aList, size_t aIndex) {
return T(); return T();
} }
template <typename T>
T get_from_list(const std::vector<T>& aList, size_t aIndex) {
return aList[aIndex];
}
struct Argument { struct Argument {
std::vector<std::string> mNames; std::vector<std::string> mNames;
std::string mHelp; std::string mHelp;
@ -96,7 +101,7 @@ struct Argument {
} }
template <typename T> template <typename T>
T get() { T get() const {
if (mValues.size() == 0) { if (mValues.size() == 0) {
if (mDefaultValue.has_value()) { if (mDefaultValue.has_value()) {
return std::any_cast<T>(mDefaultValue); return std::any_cast<T>(mDefaultValue);
@ -117,7 +122,7 @@ struct Argument {
} }
template <typename T> template <typename T>
T get_vector() { T get_vector() const {
T tResult; T tResult;
if (mValues.size() == 0) { if (mValues.size() == 0) {
if (mDefaultValue.has_value()) { if (mDefaultValue.has_value()) {
@ -152,7 +157,7 @@ struct Argument {
} }
template <typename T> template <typename T>
T get_list() { T get_list() const {
T tResult; T tResult;
if (mValues.size() == 0) { if (mValues.size() == 0) {
if (mDefaultValue.has_value()) { if (mDefaultValue.has_value()) {
@ -186,6 +191,50 @@ struct Argument {
} }
} }
template <typename T>
bool operator!=(const T& aRhs) const {
return !(*this == aRhs);
}
template <typename T>
typename std::enable_if<is_specialization<T, std::vector>::value == false &&
is_specialization<T, std::list>::value == false, bool>::type
operator==(const T& aRhs) const {
return get<T>() == aRhs;
}
template <typename T>
typename std::enable_if<is_specialization<T, std::vector>::value, bool>::type
operator==(const T& aRhs) const {
T tLhs = get_vector<T>();
if (tLhs.size() != aRhs.size())
return false;
else {
for (size_t i = 0; i < tLhs.size(); i++) {
auto tValueAtIndex = std::any_cast<typename T::value_type>(tLhs[i]);
if (tValueAtIndex != aRhs[i])
return false;
}
return true;
}
}
template <typename T>
typename std::enable_if<is_specialization<T, std::list>::value, bool>::type
operator==(const T& aRhs) const {
T tLhs = get_list<T>();
if (tLhs.size() != aRhs.size())
return false;
else {
for (size_t i = 0; i < tLhs.size(); i++) {
auto tValueAtIndex = std::any_cast<typename T::value_type>(get_from_list(tLhs, i));
if (tValueAtIndex != get_from_list(aRhs, i))
return false;
}
return true;
}
}
}; };
class ArgumentParser { class ArgumentParser {
@ -350,13 +399,13 @@ class ArgumentParser {
return mArgumentMap; return mArgumentMap;
} }
std::shared_ptr<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()) {
return tIterator->second; return *(tIterator->second);
} }
else { else {
return nullptr; throw std::runtime_error("Argument " + aArgumentName + " not found");
} }
} }

View File

@ -50,6 +50,7 @@ TEST_CASE("Parse list of arguments with default values", "[vector]") {
REQUIRE(argparse::get_from_list(inputs, 2) == 3); REQUIRE(argparse::get_from_list(inputs, 2) == 3);
REQUIRE(argparse::get_from_list(inputs, 3) == 4); REQUIRE(argparse::get_from_list(inputs, 3) == 4);
REQUIRE(argparse::get_from_list(inputs, 4) == 5); REQUIRE(argparse::get_from_list(inputs, 4) == 5);
REQUIRE(program["input"] == std::list<int>{1, 2, 3, 4, 5});
} }
TEST_CASE("Parse list of arguments and save in an object", "[vector]") { TEST_CASE("Parse list of arguments and save in an object", "[vector]") {
@ -78,4 +79,5 @@ TEST_CASE("Parse list of arguments and save in an object", "[vector]") {
REQUIRE(config_manager.files.size() == 2); REQUIRE(config_manager.files.size() == 2);
REQUIRE(config_manager.files[0] == "config.xml"); REQUIRE(config_manager.files[0] == "config.xml");
REQUIRE(config_manager.files[1] == "system.json"); REQUIRE(config_manager.files[1] == "system.json");
REQUIRE(program["--input_files"] == std::vector<std::string>{"config.xml", "system.json"});
} }

View File

@ -12,6 +12,7 @@ TEST_CASE("Parse toggle arguments with default value", "[optional_arguments]") {
auto arguments = program.get_arguments(); auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 2); REQUIRE(arguments.size() == 2);
REQUIRE(program.get<bool>("--verbose") == false); REQUIRE(program.get<bool>("--verbose") == false);
REQUIRE(program["--verbose"] == false);
} }
TEST_CASE("Parse toggle arguments with implicit value", "[optional_arguments]") { TEST_CASE("Parse toggle arguments with implicit value", "[optional_arguments]") {
@ -24,6 +25,8 @@ TEST_CASE("Parse toggle arguments with implicit value", "[optional_arguments]")
auto arguments = program.get_arguments(); auto arguments = program.get_arguments();
REQUIRE(arguments.size() == 1); REQUIRE(arguments.size() == 1);
REQUIRE(program.get<bool>("--verbose") == true); REQUIRE(program.get<bool>("--verbose") == true);
REQUIRE(program["--verbose"] == true);
REQUIRE(program["--verbose"] != false);
} }
TEST_CASE("Parse multiple toggle arguments with implicit values", "[optional_arguments]") { TEST_CASE("Parse multiple toggle arguments with implicit values", "[optional_arguments]") {