Skip to content

Commit

Permalink
Revive remaining method
Browse files Browse the repository at this point in the history
I reimplemented remaining() method for backward compatibility.

It consumes "all" remaining args.

So, I added mAcceptsOptionalLikeValue flag and handle it by using this
flag.

Currently, remaining() behavior is slightly different from the original when no
args are provided and get<Container<T>>() method is called.
Originally it raises an exception. But current implementation returns
an empty container instead of exception.

It is possible to implement complete backward compatibility by
referencing mAcceptsOptionalLikeValue flag and raises an exception in get() method,
but I did not do this.
I think that is too much.
  • Loading branch information
hokacci committed Sep 15, 2021
1 parent c6c3be0 commit 3d559d3
Showing 1 changed file with 18 additions and 15 deletions.
33 changes: 18 additions & 15 deletions include/argparse/argparse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,11 @@ class Argument {
return *this;
}

Argument &remaining() {
mAcceptsOptionalLikeValue = true;
return nargs(NArgsPattern::ANY);
}

template <typename Iterator>
Iterator consume(Iterator start, Iterator end,
std::string_view usedName = {}) {
Expand All @@ -501,25 +506,21 @@ class Argument {

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::size_t>(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::size_t>(std::distance(start, end))) >= numArgsMin) {
if (numArgsMax < dist) {
end = std::next(start, numArgsMax);
}
auto dist = static_cast<std::size_t>(std::distance(start, it));
if (dist < numArgsMin) {
throw std::runtime_error("Too few arguments");
if (!mAcceptsOptionalLikeValue) {
end = std::find_if(start, end, Argument::is_optional);
dist = static_cast<std::size_t>(std::distance(start, end));
if (dist < numArgsMin) {
throw std::runtime_error("Too few arguments");
}
}
end = it;

struct action_apply {
void operator()(valued_action &f) {
Expand All @@ -529,7 +530,8 @@ class Argument {
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));
}
}

Expand Down Expand Up @@ -882,6 +884,7 @@ class Argument {
[](const std::string &aValue) { return aValue; }};
std::vector<std::any> mValues;
SizeRange mNumArgsRange {1, 1};
bool mAcceptsOptionalLikeValue = false;
bool mIsOptional : true;
bool mIsRequired : true;
bool mIsRepeatable : true;
Expand Down

0 comments on commit 3d559d3

Please sign in to comment.