From 03a0ce831df13741451ae4c985e1fccaa2ffa8fa Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Wed, 1 Jan 2020 16:09:27 -0600 Subject: [PATCH 1/2] Simplify Argument exposition-only constructors Although they are public, they are not meant for end-users to use, so we can change its interface to use less sfinae. --- include/argparse.hpp | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index fa10a06..b0c82ac 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -73,11 +73,6 @@ struct is_container< template static constexpr bool is_container_v = is_container::value; -template -struct is_string_like - : std::conjunction, - std::is_convertible> {}; - template constexpr bool standard_signed_integer = false; template <> constexpr bool standard_signed_integer = true; template <> constexpr bool standard_signed_integer = true; @@ -271,10 +266,10 @@ class Argument { -> std::ostream &; template - explicit Argument(std::string(&&a)[N], std::index_sequence) + explicit Argument(std::string_view(&&a)[N], std::index_sequence) : mIsOptional((is_optional(a[I]) || ...)), mIsRequired(false), mIsUsed(false) { - ((void)mNames.push_back(std::move(a[I])), ...); + ((void)mNames.emplace_back(a[I]), ...); std::sort( mNames.begin(), mNames.end(), [](const auto &lhs, const auto &rhs) { return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size(); @@ -282,14 +277,9 @@ class Argument { } public: - Argument() = default; - - template ...>, int> = 0> - explicit Argument(Args &&... args) - : Argument({std::string(std::forward(args))...}, - std::make_index_sequence{}) {} + template + explicit Argument(std::string_view(&&a)[N]) + : Argument(std::move(a), std::make_index_sequence{}) {} Argument &help(std::string aHelp) { mHelp = std::move(aHelp); @@ -780,8 +770,9 @@ public: // Parameter packing // Call add_argument with variadic number of string arguments template Argument &add_argument(Targs... Fargs) { + using array_of_sv = std::string_view[sizeof...(Targs)]; auto tArgument = mOptionalArguments.emplace(cend(mOptionalArguments), - std::move(Fargs)...); + array_of_sv{Fargs...}); if (!tArgument->mIsOptional) mPositionalArguments.splice(cend(mPositionalArguments), From 7c57e1e852fdeac7b6e9edda5334ae75f49f3b6a Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Thu, 2 Jan 2020 01:56:31 -0600 Subject: [PATCH 2/2] Record used names with copies of string_view --- include/argparse.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index b0c82ac..109d6cb 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -373,12 +373,13 @@ public: } template - Iterator consume(Iterator start, Iterator end, std::string usedName = {}) { + Iterator consume(Iterator start, Iterator end, + std::string_view usedName = {}) { if (mIsUsed) { throw std::runtime_error("Duplicate argument"); } mIsUsed = true; - mUsedName = std::move(usedName); + mUsedName = usedName; if (mNumArgs == 0) { mValues.emplace_back(mImplicitValue); return start; @@ -721,7 +722,7 @@ private: } std::vector mNames; - std::string mUsedName; + std::string_view mUsedName; std::string mHelp; std::any mDefaultValue; std::any mImplicitValue; @@ -932,7 +933,7 @@ private: std::exit(0); } - it = tArgument->consume(std::next(it), end, tCurrentArgument); + it = tArgument->consume(std::next(it), end, tIterator->first); } else if (const auto &tCompoundArgument = tCurrentArgument; tCompoundArgument.size() > 1 && tCompoundArgument[0] == '-' && tCompoundArgument[1] != '-') { @@ -942,7 +943,7 @@ private: auto tIterator2 = mArgumentMap.find(tHypotheticalArgument); if (tIterator2 != mArgumentMap.end()) { auto tArgument = tIterator2->second; - it = tArgument->consume(it, end, tHypotheticalArgument); + it = tArgument->consume(it, end, tIterator2->first); } else { throw std::runtime_error("Unknown argument"); }