From f7dae0d93d07b5845b1bd5e2347318eec8e1dc88 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Sun, 17 Nov 2019 20:16:52 -0600 Subject: [PATCH] Refactor some uses of SFINAE into constexpr-if --- include/argparse.hpp | 62 +++++++++++++------------------------------- 1 file changed, 18 insertions(+), 44 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index 9321a93..400718e 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -74,12 +74,6 @@ struct is_string_like : std::conjunction, std::is_convertible> {}; -template -using enable_if_container = std::enable_if_t, T>; - -template -using enable_if_not_container = std::enable_if_t, T>; - template constexpr decltype(auto) apply_plus_one_impl(F &&f, Tuple &&t, Extra &&x, std::index_sequence) { @@ -266,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 */ - template - std::enable_if_t, bool> - operator==(const T &aRhs) const { - return get() == aRhs; - } - - /* - * Template specialization for containers - * @throws std::logic_error in case of incompatible types - */ - template - std::enable_if_t, bool> - operator==(const T &aRhs) const { - using ValueType = typename T::value_type; - auto tLhs = get(); - 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(lhs) == rhs; - }); + template bool operator==(const T &aRhs) const { + if constexpr (!details::is_container_v) { + return get() == aRhs; + } else { + using ValueType = typename T::value_type; + auto tLhs = get(); + 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(lhs) == rhs; + }); + } } private: @@ -321,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 */ - template details::enable_if_not_container get() const { + template T get() const { if (!mValues.empty()) { - return std::any_cast(mValues.front()); + if constexpr (details::is_container_v) + return any_cast_container(mValues); + else + return std::any_cast(mValues.front()); } if (mDefaultValue.has_value()) { return std::any_cast(mDefaultValue); @@ -334,21 +323,6 @@ private: throw std::logic_error("No value provided"); } - /* - * Getter for container types - * @throws std::logic_error in case of incompatible types - */ - template - details::enable_if_container get() const { - if (!mValues.empty()) { - return any_cast_container(mValues); - } - if (mDefaultValue.has_value()) { - return std::any_cast(mDefaultValue); - } - throw std::logic_error("No value provided"); - } - template static auto any_cast_container(const std::vector &aOperand) -> T { using ValueType = typename T::value_type;