diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -272,20 +272,22 @@ // be applied whenever operator* is invoked on the iterator. template ()(*std::declval()))> + typename ReferenceTy = + decltype(std::declval()(*std::declval()))> class mapped_iterator : public iterator_adaptor_base< - mapped_iterator, ItTy, - typename std::iterator_traits::iterator_category, - typename std::remove_reference::type> { + mapped_iterator, ItTy, + typename std::iterator_traits::iterator_category, + std::remove_reference_t, + typename std::iterator_traits::difference_type, + std::remove_reference_t *, ReferenceTy> { public: mapped_iterator(ItTy U, FuncTy F) : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {} ItTy getCurrent() { return this->I; } - FuncReturnTy operator*() const { return F(*this->I); } + ReferenceTy operator*() const { return F(*this->I); } private: FuncTy F; diff --git a/llvm/include/llvm/ADT/iterator.h b/llvm/include/llvm/ADT/iterator.h --- a/llvm/include/llvm/ADT/iterator.h +++ b/llvm/include/llvm/ADT/iterator.h @@ -95,6 +95,22 @@ operator ReferenceT() const { return *I; } }; + /// A proxy object for computing a pointer via indirecting a copy of a + /// reference. This is used in APIs which need to produce a pointer but for + /// which the reference might be a temporary. The proxy preserves the + /// reference internally and exposes the pointer via a arrow operator. + class PointerProxy { + friend iterator_facade_base; + + ReferenceT R; + + template + PointerProxy(RefT &&R) : R(std::forward(R)) {} + + public: + PointerT operator->() const { return &R; } + }; + public: DerivedT operator+(DifferenceTypeT n) const { static_assert(std::is_base_of::value, @@ -172,19 +188,21 @@ return !(static_cast(*this) < RHS); } - PointerT operator->() { return &static_cast(this)->operator*(); } - PointerT operator->() const { - return &static_cast(this)->operator*(); + PointerProxy operator->() { + return static_cast(this)->operator*(); + } + PointerProxy operator->() const { + return static_cast(this)->operator*(); } ReferenceProxy operator[](DifferenceTypeT n) { static_assert(IsRandomAccess, "Subscripting is only defined for random access iterators."); - return ReferenceProxy(static_cast(this)->operator+(n)); + return static_cast(this)->operator+(n); } ReferenceProxy operator[](DifferenceTypeT n) const { static_assert(IsRandomAccess, "Subscripting is only defined for random access iterators."); - return ReferenceProxy(static_cast(this)->operator+(n)); + return static_cast(this)->operator+(n); } }; diff --git a/mlir/include/mlir/IR/BlockSupport.h b/mlir/include/mlir/IR/BlockSupport.h --- a/mlir/include/mlir/IR/BlockSupport.h +++ b/mlir/include/mlir/IR/BlockSupport.h @@ -151,7 +151,7 @@ &filter) {} /// Allow implicit conversion to the underlying iterator. - operator IteratorT() const { return this->wrapped(); } + operator const IteratorT &() const { return this->wrapped(); } }; /// This class provides iteration over the held operations of a block for a @@ -163,7 +163,6 @@ static OpT unwrap(Operation &op) { return cast(op); } public: - using reference = OpT; /// Initializes the iterator to the specified filter iterator. op_iterator(op_filter_iterator it) @@ -171,7 +170,7 @@ OpT (*)(Operation &)>(it, &unwrap) {} /// Allow implicit conversion to the underlying block iterator. - operator IteratorT() const { return this->wrapped(); } + operator const IteratorT &() const { return this->wrapped(); } }; } // end namespace detail } // end namespace mlir