Skip to content

Commit

Permalink
cmdline: Support a different end for optional args
Browse files Browse the repository at this point in the history
  • Loading branch information
dscharrer committed Jul 3, 2013
1 parent 99f1e7c commit fc94ea5
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
21 changes: 20 additions & 1 deletion src/util/cmdline/Interpreter.h
Expand Up @@ -148,6 +148,25 @@ class interpreter : detail::interpreter<key_type<StringType>, TypeCast> {
super_t::visit(visitor);
}

/*!
* Invokes handler by option name with parameters [args_begin, args_end).
*
* @param option_name Name of an option
*
* @param args_begin Iterator referring to the first argument for the option.
* @param args_optend Iterator referring to the end of arguments to be consumed by \ref optional.
* @param args_end Iterator referring to the past-the-end argument for the option.
*
* @throws If option isn't found or the handler of this options takes more
* than required arguments or they can't be converted, an exception
* will be thrown.
*/
template<typename It>
void invoke(const string_type & option_name, It & args_begin, It args_opend, It args_end,
type_cast_t & type_cast) const {
super_t::invoke(option_name, args_begin, args_end, type_cast);
}

/*!
* Invokes handler by option name with parameters [args_begin, args_end).
*
Expand All @@ -163,7 +182,7 @@ class interpreter : detail::interpreter<key_type<StringType>, TypeCast> {
template<typename It>
void invoke(const string_type & option_name, It & args_begin, It args_end,
type_cast_t & type_cast) const {
super_t::invoke(option_name, args_begin, args_end, type_cast);
super_t::invoke(option_name, args_begin, args_end, args_end, type_cast);
}

interpreter() : super_t() { }
Expand Down
4 changes: 2 additions & 2 deletions src/util/cmdline/detail/Construct.h
Expand Up @@ -64,7 +64,7 @@ ellipsis<P, Alloc> construct(SourceType & arg, const ellipsis<P, Alloc> * = 0) {

ellipsis<P, Alloc> ret;

while(!arg.empty()) {
while(!arg.opt_empty()) {
ret.push_back(construct(arg, static_cast<const P *>(0)));
}

Expand All @@ -74,7 +74,7 @@ ellipsis<P, Alloc> construct(SourceType & arg, const ellipsis<P, Alloc> * = 0) {
template<typename SourceType, typename T>
optional<T> construct(SourceType & arg, const optional<T> * = 0) {

if(arg.empty()) {
if(arg.opt_empty()) {
return optional<T>();
}

Expand Down
12 changes: 9 additions & 3 deletions src/util/cmdline/detail/Interpreter.h
Expand Up @@ -58,9 +58,15 @@ class interpreter {
void erase(const string_type & option_name);

template<typename It>
void invoke(const string_type & option_name, It & args_begin, It args_end,
void invoke(const string_type & option_name, It & args_begin, It args_optend, It args_end,
type_cast_t &) const;

template<typename It>
void invoke(const string_type & option_name, It & args_begin, It args_end,
type_cast_t & type_cast) const {
invoke(option_name, args_begin, args_end, args_end, type_cast);
}

template<typename Visitor>
void visit(Visitor & visitor) const {
do_visit(storage.begin(), storage.end(), visitor);
Expand Down Expand Up @@ -179,7 +185,7 @@ void interpreter<StringType, TypeCast>::do_add(const function_type & handler,
template<typename StringType, typename TypeCast>
template<typename It>
void interpreter<StringType, TypeCast>::invoke(const string_type & key,
It & args_begin, It args_end,
It & args_begin, It args_optend, It args_end,
type_cast_t & type_cast) const {

typename alt_name_t::const_iterator primary_key = alt_name.find(key);
Expand All @@ -189,7 +195,7 @@ void interpreter<StringType, TypeCast>::invoke(const string_type & key,
}

typename storage_t::const_iterator it(storage.find(primary_key->second));
it->second.function(args_begin, args_end, type_cast);
it->second.function(args_begin, args_optend, args_end, type_cast);
}

} } } // namespace util::cmdline::detail
Expand Down
32 changes: 26 additions & 6 deletions src/util/cmdline/detail/LexicalCall.h
Expand Up @@ -142,7 +142,8 @@ class lexical_call_t<_Result(_ValueType, _ValueType, _TypeCast)> {

virtual _ValueType v_front() const = 0;
virtual void pop() {}
virtual bool empty() const=0;
virtual bool empty() const = 0;
virtual bool opt_empty() const = 0;

virtual ~Args() {}

Expand All @@ -152,12 +153,16 @@ class lexical_call_t<_Result(_ValueType, _ValueType, _TypeCast)> {
struct VArgs : Args {

Iterator & m_begin;
Iterator m_optend;
Iterator m_end;
bool m_is_optend;

VArgs(type_cast_t & cast, Iterator & begin, Iterator end)
VArgs(type_cast_t & cast, Iterator & begin, Iterator optend, Iterator end)
: Args(cast)
, m_begin(begin)
, m_optend(optend)
, m_end(end)
, m_is_optend(begin == optend)
{ }

virtual _ValueType v_front() const {
Expand All @@ -166,12 +171,17 @@ class lexical_call_t<_Result(_ValueType, _ValueType, _TypeCast)> {

virtual void pop() {
++m_begin;
m_is_optend = m_is_optend || (m_begin == m_optend);
}

virtual bool empty() const {
return m_begin == m_end;
}

virtual bool opt_empty() const {
return m_is_optend;
}

};

typedef lexical_call_t<_Result(Args &)> impl_t;
Expand Down Expand Up @@ -199,16 +209,26 @@ class lexical_call_t<_Result(_ValueType, _ValueType, _TypeCast)> {
return self_t(impl_t::construct(fn));
}

template<typename Iterator>
_Result operator()(Iterator & begin, Iterator optend, Iterator end, _TypeCast & cast) {
VArgs<Iterator> args(cast, begin, optend, end);
return m_impl(args);
}

template<typename Iterator>
_Result operator()(Iterator & begin, Iterator optend, Iterator end, _TypeCast & cast) const {
VArgs<Iterator> args(cast, begin, optend, end);
return m_impl(args);
}

template<typename Iterator>
_Result operator()(Iterator & begin, Iterator end, _TypeCast & cast) {
VArgs<Iterator> args(cast, begin, end);
m_impl(args);
return operator()(begin, end, end, cast);
}

template<typename Iterator>
_Result operator()(Iterator & begin, Iterator end, _TypeCast & cast) const {
VArgs<Iterator> args(cast, begin, end);
m_impl(args);
return operator()(begin, end, end, cast);
}

};
Expand Down

0 comments on commit fc94ea5

Please sign in to comment.