mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 07:04:39 +00:00
Unify container operations
This commit is contained in:
parent
cddde9f1b7
commit
94ca8e2552
@ -57,17 +57,6 @@ bool starts_with(const std::string& haystack, const std::string& needle) {
|
|||||||
return needle.length() <= haystack.length()
|
return needle.length() <= haystack.length()
|
||||||
&& std::equal(needle.begin(), needle.end(), haystack.begin());
|
&& std::equal(needle.begin(), needle.end(), haystack.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value at index from std::list
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Argument {
|
class Argument {
|
||||||
@ -150,33 +139,29 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<is_specialization<T, std::vector>::value, bool>::type
|
typename std::enable_if<is_specialization<T, std::vector>::value, bool>::type
|
||||||
operator==(const T& aRhs) const {
|
operator==(const T& aRhs) const {
|
||||||
|
using ValueType = typename T::value_type;
|
||||||
T tLhs = get<T>();
|
T tLhs = get<T>();
|
||||||
if (tLhs.size() != aRhs.size())
|
if (tLhs.size() != aRhs.size())
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
for (size_t i = 0; i < tLhs.size(); i++) {
|
return std::equal(std::begin(tLhs), std::begin(tLhs), std::begin(aRhs), [](const auto& lhs, const auto& rhs) {
|
||||||
auto tValueAtIndex = std::any_cast<typename T::value_type>(tLhs[i]);
|
return std::any_cast<ValueType>(lhs) == rhs;
|
||||||
if (tValueAtIndex != aRhs[i])
|
});
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Template specialization for std::list<...>
|
// Template specialization for std::list<...>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<is_specialization<T, std::list>::value, bool>::type
|
typename std::enable_if<is_specialization<T, std::list>::value, bool>::type
|
||||||
operator==(const T& aRhs) const {
|
operator==(const T& aRhs) const {
|
||||||
|
using ValueType = typename T::value_type;
|
||||||
T tLhs = get<T>();
|
T tLhs = get<T>();
|
||||||
if (tLhs.size() != aRhs.size())
|
if (tLhs.size() != aRhs.size())
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
for (size_t i = 0; i < tLhs.size(); i++) {
|
return std::equal(std::begin(tLhs), std::begin(tLhs), std::begin(aRhs), [](const auto& lhs, const auto& rhs) {
|
||||||
auto tValueAtIndex = std::any_cast<typename T::value_type>(get_from_list(tLhs, i));
|
return std::any_cast<ValueType>(lhs) == rhs;
|
||||||
if (tValueAtIndex != get_from_list(aRhs, i))
|
});
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,13 +199,13 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<is_specialization<T, std::vector>::value, T>::type
|
typename std::enable_if<is_specialization<T, std::vector>::value, T>::type
|
||||||
get() const {
|
get() const {
|
||||||
|
using ValueType = typename T::value_type;
|
||||||
T tResult;
|
T tResult;
|
||||||
if (mValues.empty()) {
|
if (mValues.empty()) {
|
||||||
if (mDefaultValue.has_value()) {
|
if (mDefaultValue.has_value()) {
|
||||||
T tDefaultValues = std::any_cast<T>(mDefaultValue);
|
T tDefaultValues = std::any_cast<T>(mDefaultValue);
|
||||||
for (size_t i = 0; i < tDefaultValues.size(); i++) {
|
std::transform(std::begin(tDefaultValues), std::end(tDefaultValues),
|
||||||
tResult.emplace_back(std::any_cast<typename T::value_type>(tDefaultValues[i]));
|
std::back_inserter(tResult), std::any_cast<ValueType>);
|
||||||
}
|
|
||||||
return tResult;
|
return tResult;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -229,16 +214,15 @@ public:
|
|||||||
else {
|
else {
|
||||||
if (!mRawValues.empty()) {
|
if (!mRawValues.empty()) {
|
||||||
for (const auto& mValue : mValues) {
|
for (const auto& mValue : mValues) {
|
||||||
tResult.emplace_back(std::any_cast<typename T::value_type>(mValue));
|
tResult.emplace_back(std::any_cast<ValueType>(mValue));
|
||||||
}
|
}
|
||||||
return tResult;
|
return tResult;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (mDefaultValue.has_value()) {
|
if (mDefaultValue.has_value()) {
|
||||||
std::vector<T> tDefaultValues = std::any_cast<std::vector<T>>(mDefaultValue);
|
auto tDefaultValues = std::any_cast<std::vector<T>>(mDefaultValue);
|
||||||
for (size_t i = 0; i < tDefaultValues.size(); i++) {
|
std::transform(std::begin(tDefaultValues), std::end(tDefaultValues),
|
||||||
tResult.emplace_back(std::any_cast<typename T::value_type>(tDefaultValues[i]));
|
std::back_inserter(tResult), std::any_cast<ValueType>);
|
||||||
}
|
|
||||||
return tResult;
|
return tResult;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -251,13 +235,13 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<is_specialization<T, std::list>::value, T>::type
|
typename std::enable_if<is_specialization<T, std::list>::value, T>::type
|
||||||
get() const {
|
get() const {
|
||||||
|
using ValueType = typename T::value_type;
|
||||||
T tResult;
|
T tResult;
|
||||||
if (mValues.empty()) {
|
if (mValues.empty()) {
|
||||||
if (mDefaultValue.has_value()) {
|
if (mDefaultValue.has_value()) {
|
||||||
T tDefaultValues = std::any_cast<T>(mDefaultValue);
|
T tDefaultValues = std::any_cast<T>(mDefaultValue);
|
||||||
for (size_t i = 0; i < tDefaultValues.size(); i++) {
|
std::transform(std::begin(tDefaultValues), std::end(tDefaultValues),
|
||||||
tResult.emplace_back(std::any_cast<typename T::value_type>(get_from_list(tDefaultValues, i)));
|
std::back_inserter(tResult), std::any_cast<ValueType>);
|
||||||
}
|
|
||||||
return tResult;
|
return tResult;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -266,16 +250,15 @@ public:
|
|||||||
else {
|
else {
|
||||||
if (!mRawValues.empty()) {
|
if (!mRawValues.empty()) {
|
||||||
for (const auto& mValue : mValues) {
|
for (const auto& mValue : mValues) {
|
||||||
tResult.emplace_back(std::any_cast<typename T::value_type>(mValue));
|
tResult.emplace_back(std::any_cast<ValueType>(mValue));
|
||||||
}
|
}
|
||||||
return tResult;
|
return tResult;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (mDefaultValue.has_value()) {
|
if (mDefaultValue.has_value()) {
|
||||||
std::list<T> tDefaultValues = std::any_cast<std::list<T>>(mDefaultValue);
|
auto tDefaultValues = std::any_cast<std::list<T>>(mDefaultValue);
|
||||||
for (size_t i = 0; i < tDefaultValues.size(); i++) {
|
std::transform(std::begin(tDefaultValues), std::end(tDefaultValues),
|
||||||
tResult.emplace_back(std::any_cast<typename T::value_type>(get_from_list(tDefaultValues, i)));
|
std::back_inserter(tResult), std::any_cast<ValueType>);
|
||||||
}
|
|
||||||
return tResult;
|
return tResult;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
#include <argparse.hpp>
|
#include <argparse.hpp>
|
||||||
|
#include <test_utility.hpp>
|
||||||
|
|
||||||
TEST_CASE("Parse compound toggle arguments with implicit values", "[compound_arguments]") {
|
TEST_CASE("Parse compound toggle arguments with implicit values", "[compound_arguments]") {
|
||||||
argparse::ArgumentParser program("test");
|
argparse::ArgumentParser program("test");
|
||||||
@ -97,9 +98,9 @@ TEST_CASE("Parse compound toggle arguments with implicit values and nargs and ot
|
|||||||
REQUIRE(numbers[2] == 3);
|
REQUIRE(numbers[2] == 3);
|
||||||
auto numbers_list = program.get<std::list<int>>("numbers");
|
auto numbers_list = program.get<std::list<int>>("numbers");
|
||||||
REQUIRE(numbers.size() == 3);
|
REQUIRE(numbers.size() == 3);
|
||||||
REQUIRE(argparse::get_from_list(numbers_list, 0) == 1);
|
REQUIRE(testutility::get_from_list(numbers_list, 0) == 1);
|
||||||
REQUIRE(argparse::get_from_list(numbers_list, 1) == 2);
|
REQUIRE(testutility::get_from_list(numbers_list, 1) == 2);
|
||||||
REQUIRE(argparse::get_from_list(numbers_list, 2) == 3);
|
REQUIRE(testutility::get_from_list(numbers_list, 2) == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Parse out-of-order compound arguments", "[compound_arguments]") {
|
TEST_CASE("Parse out-of-order compound arguments", "[compound_arguments]") {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
#include <argparse.hpp>
|
#include <argparse.hpp>
|
||||||
|
#include <test_utility.hpp>
|
||||||
|
|
||||||
TEST_CASE("Parse vector of arguments", "[vector]") {
|
TEST_CASE("Parse vector of arguments", "[vector]") {
|
||||||
argparse::ArgumentParser program("test");
|
argparse::ArgumentParser program("test");
|
||||||
@ -24,8 +25,8 @@ TEST_CASE("Parse list of arguments", "[vector]") {
|
|||||||
|
|
||||||
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(testutility::get_from_list(inputs, 0) == "rocket.mesh");
|
||||||
REQUIRE(argparse::get_from_list(inputs, 1) == "thrust_profile.csv");
|
REQUIRE(testutility::get_from_list(inputs, 1) == "thrust_profile.csv");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Parse list of arguments with default values", "[vector]") {
|
TEST_CASE("Parse list of arguments with default values", "[vector]") {
|
||||||
@ -38,11 +39,11 @@ TEST_CASE("Parse list of arguments with default values", "[vector]") {
|
|||||||
|
|
||||||
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(testutility::get_from_list(inputs, 0) == 1);
|
||||||
REQUIRE(argparse::get_from_list(inputs, 1) == 2);
|
REQUIRE(testutility::get_from_list(inputs, 1) == 2);
|
||||||
REQUIRE(argparse::get_from_list(inputs, 2) == 3);
|
REQUIRE(testutility::get_from_list(inputs, 2) == 3);
|
||||||
REQUIRE(argparse::get_from_list(inputs, 3) == 4);
|
REQUIRE(testutility::get_from_list(inputs, 3) == 4);
|
||||||
REQUIRE(argparse::get_from_list(inputs, 4) == 5);
|
REQUIRE(testutility::get_from_list(inputs, 4) == 5);
|
||||||
REQUIRE(program["--input"] == std::list<int>{1, 2, 3, 4, 5});
|
REQUIRE(program["--input"] == std::list<int>{1, 2, 3, 4, 5});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
test/test_utility.hpp
Normal file
17
test/test_utility.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef ARGPARSE_TEST_UTILITY_HPP
|
||||||
|
#define ARGPARSE_TEST_UTILITY_HPP
|
||||||
|
|
||||||
|
namespace testutility {
|
||||||
|
// Get value at index from std::list
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //ARGPARSE_TEST_UTILITY_HPP
|
Loading…
Reference in New Issue
Block a user