mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 15:14:39 +00:00
Merge pull request #54 from lichray/less-sfinae
Finishing cleanup by refactoring SFINAE into constexpr-if
This commit is contained in:
commit
6ee8de5f4e
@ -70,10 +70,9 @@ template <typename T>
|
|||||||
static constexpr bool is_container_v = is_container<T>::value;
|
static constexpr bool is_container_v = is_container<T>::value;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using enable_if_container = std::enable_if_t<is_container_v<T>, T>;
|
struct is_string_like
|
||||||
|
: std::conjunction<std::is_constructible<std::string, T>,
|
||||||
template <typename T>
|
std::is_convertible<T, std::string_view>> {};
|
||||||
using enable_if_not_container = std::enable_if_t<!is_container_v<T>, T>;
|
|
||||||
|
|
||||||
template <class F, class Tuple, class Extra, size_t... I>
|
template <class F, class Tuple, class Extra, size_t... I>
|
||||||
constexpr decltype(auto) apply_plus_one_impl(F &&f, Tuple &&t, Extra &&x,
|
constexpr decltype(auto) apply_plus_one_impl(F &&f, Tuple &&t, Extra &&x,
|
||||||
@ -115,8 +114,7 @@ public:
|
|||||||
|
|
||||||
template <typename... Args,
|
template <typename... Args,
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
std::conjunction_v<std::is_constructible<std::string, Args>...>,
|
std::conjunction_v<details::is_string_like<Args>...>, int> = 0>
|
||||||
int> = 0>
|
|
||||||
explicit Argument(Args &&... args)
|
explicit Argument(Args &&... args)
|
||||||
: Argument({std::string(std::forward<Args>(args))...},
|
: Argument({std::string(std::forward<Args>(args))...},
|
||||||
std::make_index_sequence<sizeof...(Args)>{}) {}
|
std::make_index_sequence<sizeof...(Args)>{}) {}
|
||||||
@ -262,28 +260,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point for template non-container types
|
* Compare to an argument value of known type
|
||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T> bool operator==(const T &aRhs) const {
|
||||||
std::enable_if_t<!details::is_container_v<T>, bool>
|
if constexpr (!details::is_container_v<T>) {
|
||||||
operator==(const T &aRhs) const {
|
return get<T>() == aRhs;
|
||||||
return get<T>() == aRhs;
|
} else {
|
||||||
}
|
using ValueType = typename T::value_type;
|
||||||
|
auto tLhs = get<T>();
|
||||||
/*
|
return std::equal(std::begin(tLhs), std::end(tLhs), std::begin(aRhs),
|
||||||
* Template specialization for containers
|
std::end(aRhs), [](const auto &lhs, const auto &rhs) {
|
||||||
* @throws std::logic_error in case of incompatible types
|
return std::any_cast<const ValueType &>(lhs) == rhs;
|
||||||
*/
|
});
|
||||||
template <typename T>
|
}
|
||||||
std::enable_if_t<details::is_container_v<T>, bool>
|
|
||||||
operator==(const T &aRhs) const {
|
|
||||||
using ValueType = typename T::value_type;
|
|
||||||
auto tLhs = get<T>();
|
|
||||||
return std::equal(std::begin(tLhs), std::end(tLhs), std::begin(aRhs),
|
|
||||||
std::end(aRhs), [](const auto &lhs, const auto &rhs) {
|
|
||||||
return std::any_cast<const ValueType &>(lhs) == rhs;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -317,12 +307,15 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Getter for template non-container types
|
* Get argument value given a type
|
||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename T> details::enable_if_not_container<T> get() const {
|
template <typename T> T get() const {
|
||||||
if (!mValues.empty()) {
|
if (!mValues.empty()) {
|
||||||
return std::any_cast<T>(mValues.front());
|
if constexpr (details::is_container_v<T>)
|
||||||
|
return any_cast_container<T>(mValues);
|
||||||
|
else
|
||||||
|
return std::any_cast<T>(mValues.front());
|
||||||
}
|
}
|
||||||
if (mDefaultValue.has_value()) {
|
if (mDefaultValue.has_value()) {
|
||||||
return std::any_cast<T>(mDefaultValue);
|
return std::any_cast<T>(mDefaultValue);
|
||||||
@ -330,30 +323,15 @@ private:
|
|||||||
throw std::logic_error("No value provided");
|
throw std::logic_error("No value provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
template <typename T>
|
||||||
* Getter for container types
|
static auto any_cast_container(const std::vector<std::any> &aOperand) -> T {
|
||||||
* @throws std::logic_error in case of incompatible types
|
using ValueType = typename T::value_type;
|
||||||
*/
|
|
||||||
template <typename CONTAINER>
|
T tResult;
|
||||||
details::enable_if_container<CONTAINER> get() const {
|
std::transform(
|
||||||
using ValueType = typename CONTAINER::value_type;
|
begin(aOperand), end(aOperand), std::back_inserter(tResult),
|
||||||
CONTAINER tResult;
|
[](const auto &value) { return std::any_cast<ValueType>(value); });
|
||||||
if (!mValues.empty()) {
|
return tResult;
|
||||||
std::transform(
|
|
||||||
std::begin(mValues), std::end(mValues), std::back_inserter(tResult),
|
|
||||||
[](const auto &value) { return std::any_cast<ValueType>(value); });
|
|
||||||
return tResult;
|
|
||||||
}
|
|
||||||
if (mDefaultValue.has_value()) {
|
|
||||||
const auto &tDefaultValues =
|
|
||||||
std::any_cast<const CONTAINER &>(mDefaultValue);
|
|
||||||
std::transform(std::begin(tDefaultValues), std::end(tDefaultValues),
|
|
||||||
std::back_inserter(tResult), [](const auto &value) {
|
|
||||||
return std::any_cast<ValueType>(value);
|
|
||||||
});
|
|
||||||
return tResult;
|
|
||||||
}
|
|
||||||
throw std::logic_error("No value provided");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> mNames;
|
std::vector<std::string> mNames;
|
||||||
@ -561,11 +539,11 @@ private:
|
|||||||
tCompoundArgument[1] != '-') {
|
tCompoundArgument[1] != '-') {
|
||||||
++it;
|
++it;
|
||||||
for (size_t j = 1; j < tCompoundArgument.size(); j++) {
|
for (size_t j = 1; j < tCompoundArgument.size(); j++) {
|
||||||
auto tCurrentArgument = std::string{'-', tCompoundArgument[j]};
|
auto tHypotheticalArgument = std::string{'-', tCompoundArgument[j]};
|
||||||
if (auto tIterator = mArgumentMap.find(tCurrentArgument);
|
auto tIterator2 = mArgumentMap.find(tHypotheticalArgument);
|
||||||
tIterator != mArgumentMap.end()) {
|
if (tIterator2 != mArgumentMap.end()) {
|
||||||
auto tArgument = tIterator->second;
|
auto tArgument = tIterator2->second;
|
||||||
it = tArgument->consume(it, end, tCurrentArgument);
|
it = tArgument->consume(it, end, tHypotheticalArgument);
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Unknown argument");
|
throw std::runtime_error("Unknown argument");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user