[PATCH] D45853: [ADT] Teach reverse() about filter_iterator ranges
Vedant Kumar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 20 15:08:04 PDT 2018
vsk added inline comments.
================
Comment at: include/llvm/ADT/STLExtras.h:298
typename std::common_type<
- std::forward_iterator_tag,
+ typename detail::fwd_or_bidi_tag<WrappedIteratorT>::type,
typename std::iterator_traits<
----------------
timshen wrote:
> Would `std::bidirectional_iterator_tag` simply work?
Neat, it would've worked.
However, I did still need detail::fwd_or_bidi_tag to implement the specialized version of filter_iterator_impl you described. That's because you'd need to check if the wrapped iterator's category is derived from bidirectional_iterator_tag to make the specialization work.
================
Comment at: include/llvm/ADT/STLExtras.h:309
struct PayloadType {
+ WrappedIteratorT Begin;
WrappedIteratorT End;
----------------
timshen wrote:
> If WrappedIteratorT is not bidirectional, we don't need this data member. Maybe add a comment about this optimization opportunity?
As you pointed out, the Begin member isn't needed in the bidirectional case either, so I've removed it.
================
Comment at: include/llvm/ADT/STLExtras.h:324
+ assert(Payload && "Payload should be engaged when findPrevValid is called");
+ while (this->I != Payload->Begin && !Payload->Pred(*this->I))
+ BaseT::operator--();
----------------
timshen wrote:
> I think it's better to have:
> while (!Payload->Pred(*this->I))
>
> Notice that as it is described in http://en.cppreference.com/w/cpp/concept/BidirectionalIterator, the precondition is "a is decrementable (there exists such b that a == ++b)". Therefore, there must be an iterator value that satisfies `Payload->Pred(*this->I)`. If users wrote a bug by decrementing on begin, I'd rather keep looping and let sanitizers catch it.
I see, sounds good! That makes it possible to get rid of the Begin member.
================
Comment at: include/llvm/ADT/STLExtras.h:344
+ // TODO:
+ // typename std::enable_if<std::is_same<std::bidirectional_iterator_tag,
----------------
timshen wrote:
> SFINAE wouldn't work here unless you make operator--() a function template, which is an overkill.
>
> I suggest to specialize the class on bidirectional iterator. It might require some boilerplate. For example:
> template <typename Iter,
> typename Predicate,
> typename iter_tag = typename iterator_traits<Iter>::iterator_category>
> class filter_iterator_impl { ... };
>
> template <typename Iter, typename Predicate>
> class filter_iterator_impl<Iter, Predicate, std::bidrectional_iterator_tag> { ... };
>
> template <typename Iter, typename Predicate>
> using filter_iterator = filter_iterator_impl<Iter, Predicate>; // to hide template parameter "iter_tag".
Thanks, this worked out.
https://reviews.llvm.org/D45853
More information about the llvm-commits
mailing list