[llvm] r207072 - [ADT] Factor out the facade aspect of the iterator_adaptor_base into its

Duncan P. N. Exon Smith dexonsmith at apple.com
Thu Apr 24 21:25:58 PDT 2014


On 2014-Apr-23, at 21:07, Chandler Carruth <chandlerc at gmail.com> wrote:

> Author: chandlerc
> Date: Wed Apr 23 23:07:06 2014
> New Revision: 207072
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=207072&view=rev
> Log:
> [ADT] Factor out the facade aspect of the iterator_adaptor_base into its
> own CRTP base class for more general purpose use. Add some clarifying
> comments for the exact way in which the adaptor uses it. Hopefully this
> will help us write increasingly full featured iterators. This is
> becoming important as they start to be used heavily inside of ranges.
> 
> Modified:
>    llvm/trunk/include/llvm/ADT/iterator.h
> 
> Modified: llvm/trunk/include/llvm/ADT/iterator.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/iterator.h?rev=207072&r1=207071&r2=207072&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/iterator.h (original)
> +++ llvm/trunk/include/llvm/ADT/iterator.h Wed Apr 23 23:07:06 2014
> @@ -14,22 +14,96 @@
> 
> namespace llvm {
> 
> +/// \brief CRTP base class which implements the entire standard iterator facade
> +/// in terms of a minimal subset of the interface.
> +///
> +/// Use this when it is reasonable to implement most of the iterator
> +/// functionality in terms of a core subset. If you need special behavior or
> +/// there are performance implications for this, you may want to override the
> +/// relevant members instead.
> +///
> +/// Note, one abstraction that this does *not* provide is implementing
> +/// subtraction in terms of addition by negating the difference. Negation isn't
> +/// always information preserving, and I can see very reasonable iterator
> +/// designs where this doesn't work well. It doesn't really force much added
> +/// boilerplate anyways.
> +///
> +/// Another abstraction that this doesn't provide is implementing increment in
> +/// terms of addition of one. These aren't equivalent for all iterator
> +/// categories, and respecting that adds a lot of complexity for little gain.
> +template <typename DerivedT, typename IteratorCategoryT, typename T,
> +          typename DifferenceTypeT, typename PointerT = T *,
> +          typename ReferenceT = T &>
> +struct iterator_facade_base
> +    : std::iterator<IteratorCategoryT, T, DifferenceTypeT, PointerT,
> +                    ReferenceT> {
> +  DerivedT operator+(DifferenceTypeT n) const {
> +    DerivedT tmp = *static_cast<const DerivedT *>(this);
> +    tmp += n;
> +    return tmp;
> +  }
> +  friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i) {
> +    return i + n;
> +  }
> +  DerivedT operator-(DifferenceTypeT n) const {
> +    DerivedT tmp = *static_cast<const DerivedT *>(this);
> +    tmp -= n;
> +    return tmp;
> +  }
> +
> +  DerivedT &operator++() {
> +    return static_cast<DerivedT *>(this)->operator+=(1);

This is nice.  I thought this was bad API at first (I was still thinking
`iterator_adaptor_base<>`), but it's great here.

> +  }
> +  DerivedT operator++(int) {
> +    DerivedT tmp = *static_cast<DerivedT *>(this);
> +    ++*static_cast<DerivedT *>(this);
> +    return tmp;
> +  }



More information about the llvm-commits mailing list