<p dir="ltr"><br>
On May 25, 2013 3:22 PM, "Rui Ueyama" <<a href="mailto:ruiu@google.com">ruiu@google.com</a>> wrote:<br>
><br>
> With this patch we can write a loop for command line options like this<br>
><br>
>   for (const auto &arg : args->filter(OPT_SOMETHING)<br>
>     ...<br>
><br>
> instead of<br>
><br>
>   for (auto it = args->filtered_begin(OPT_SOMETHING),<br>
>          ie = args->filtered_end(); it != ie; ++it) {<br>
>     ...<br>
><br>
> I plan to use this in lld in where range-based for loop is allowed.<br>
><br>
> <a href="http://llvm-reviews.chandlerc.com/D867">http://llvm-reviews.chandlerc.com/D867</a><br>
><br>
> Files:<br>
>   include/llvm/Option/ArgList.h<br>
>   lib/Option/ArgList.cpp<br>
><br>
> Index: include/llvm/Option/ArgList.h<br>
> ===================================================================<br>
> --- include/llvm/Option/ArgList.h<br>
> +++ include/llvm/Option/ArgList.h<br>
> @@ -22,6 +22,7 @@<br>
>  namespace opt {<br>
>  class Arg;<br>
>  class ArgList;<br>
> +class FilteredArgList;<br>
>  class Option;<br>
><br>
>  /// arg_iterator - Iterates through arguments stored inside an ArgList.<br>
> @@ -137,10 +138,14 @@<br>
>    const_reverse_iterator rbegin() const { return Args.rbegin(); }<br>
>    const_reverse_iterator rend() const { return Args.rend(); }<br>
><br>
> +  FilteredArgList filter(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,<br>
> +                         OptSpecifier Id2 = 0U) const;<br>
> +<br>
>    arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,<br>
>                                OptSpecifier Id2 = 0U) const {<br>
>      return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);<br>
>    }<br>
> +<br>
>    arg_iterator filtered_end() const {<br>
>      return arg_iterator(Args.end(), *this);<br>
>    }<br>
> @@ -275,6 +280,31 @@<br>
>    /// @}<br>
>  };<br>
><br>
> +/// FilteredArgList - ArgList with filters. Useful to be used in<br>
> +/// range-based for loop to iterate over filtered arguments.</p>
<p dir="ltr">Could we just have/use a generic range abstraction (essentially a simple class template with two iterator members, one returned by begin, the other by end) rather than writing a custom type here?</p>
<p dir="ltr">> +class FilteredArgList {<br>
> +private:<br>
> +  FilteredArgList(const ArgList &) LLVM_DELETED_FUNCTION;<br>
> +  void operator=(const ArgList &) LLVM_DELETED_FUNCTION;<br>
> +<br>
> +public:<br>
> +  FilteredArgList(const ArgList &_Args, OptSpecifier _Id0 = 0U,<br>
> +                  OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)<br>
> +    : Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {}<br>
> +<br>
> +  arg_iterator begin() {<br>
> +    return Args.filtered_begin(Id0, Id1, Id2);<br>
> +  }<br>
> +<br>
> +  arg_iterator end() {<br>
> +    return Args.filtered_end();<br>
> +  }<br>
> +<br>
> +private:<br>
> +  const ArgList &Args;<br>
> +  OptSpecifier Id0, Id1, Id2;<br>
> +};<br>
> +<br>
>  class InputArgList : public ArgList  {<br>
>  private:<br>
>    /// List of argument strings used by the contained Args.<br>
> Index: lib/Option/ArgList.cpp<br>
> ===================================================================<br>
> --- lib/Option/ArgList.cpp<br>
> +++ lib/Option/ArgList.cpp<br>
> @@ -44,6 +44,11 @@<br>
>    Args.push_back(A);<br>
>  }<br>
><br>
> +FilteredArgList ArgList::filter(OptSpecifier Id0, OptSpecifier Id1,<br>
> +                                OptSpecifier Id2) const {<br>
> +  return FilteredArgList(*this, Id0, Id1, Id2);<br>
> +}<br>
> +<br>
>  void ArgList::eraseArg(OptSpecifier Id) {<br>
>    for (iterator it = begin(), ie = end(); it != ie; ) {<br>
>      if ((*it)->getOption().matches(Id)) {<br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
><br>
</p>