diff --git a/include/argparse/argparse.hpp b/include/argparse/argparse.hpp index d855ee3..4789d7f 100644 --- a/include/argparse/argparse.hpp +++ b/include/argparse/argparse.hpp @@ -490,6 +490,11 @@ public: return *this; } + Argument &remaining() { + mAcceptsOptionalLikeValue = true; + return nargs(NArgsPattern::ANY); + } + template Iterator consume(Iterator start, Iterator end, std::string_view usedName = {}) { @@ -501,25 +506,21 @@ public: const auto numArgsMax = mNumArgsRange.get_max(); const auto numArgsMin = mNumArgsRange.get_min(); + std::size_t dist = 0; if (numArgsMax == 0) { mValues.emplace_back(mImplicitValue); return start; - } else if (static_cast(std::distance(start, end)) >= numArgsMin) { - - auto it = start; - for (std::size_t i = 0; it != end; ++it, ++i) { - if (Argument::is_optional(*it)) { - break; - } - if (i >= numArgsMax) { - break; + } else if ((dist = static_cast(std::distance(start, end))) >= numArgsMin) { + if (numArgsMax < dist) { + end = std::next(start, numArgsMax); + } + if (!mAcceptsOptionalLikeValue) { + end = std::find_if(start, end, Argument::is_optional); + dist = static_cast(std::distance(start, end)); + if (dist < numArgsMin) { + throw std::runtime_error("Too few arguments"); } } - auto dist = static_cast(std::distance(start, it)); - if (dist < numArgsMin) { - throw std::runtime_error("Too few arguments"); - } - end = it; struct action_apply { void operator()(valued_action &f) { @@ -529,7 +530,8 @@ public: void operator()(void_action &f) { std::for_each(start, end, f); if (!self.mDefaultValue.has_value()) { - self.mValues.resize(std::distance(start, end)); + if (!self.mAcceptsOptionalLikeValue) + self.mValues.resize(std::distance(start, end)); } } @@ -882,6 +884,7 @@ private: [](const std::string &aValue) { return aValue; }}; std::vector mValues; SizeRange mNumArgsRange {1, 1}; + bool mAcceptsOptionalLikeValue = false; bool mIsOptional : true; bool mIsRequired : true; bool mIsRepeatable : true;