Index: include/llvm/ADT/iterator.h =================================================================== --- include/llvm/ADT/iterator.h +++ include/llvm/ADT/iterator.h @@ -361,6 +361,34 @@ } }; +// Iterator to convert std::unique_ptr to raw pointers. +template ())>::type::pointer> +class raw_pointer_iterator + : public iterator_adaptor_base< + raw_pointer_iterator, WrappedIteratorT, + typename std::iterator_traits::iterator_category, + T> { + mutable T Ptr; + +public: + raw_pointer_iterator() = default; + + explicit raw_pointer_iterator(WrappedIteratorT u) + : raw_pointer_iterator::iterator_adaptor_base(std::move(u)) {} + + T &operator*() { return Ptr = this->I->get(); } + const T &operator*() const { return Ptr = this->I->get(); } +}; + +template ()))> +iterator_range> +make_raw_pointer_range(RangeT &&Range) { + using RawPointerIteratorT = raw_pointer_iterator; + return make_range(RawPointerIteratorT(std::begin(std::forward(Range))), + RawPointerIteratorT(std::end(std::forward(Range)))); +} } // end namespace llvm #endif // LLVM_ADT_ITERATOR_H Index: unittests/ADT/IteratorTest.cpp =================================================================== --- unittests/ADT/IteratorTest.cpp +++ unittests/ADT/IteratorTest.cpp @@ -297,6 +297,38 @@ EXPECT_EQ(A + I++, P); } +TEST(RawPointerIterator, Basic) { + std::unique_ptr A[] = { + make_unique(1), + make_unique(2), + make_unique(3), + make_unique(4), + }; + raw_pointer_iterator *> Begin(std::begin(A)), + End(std::end(A)); + EXPECT_EQ(A->get(), *Begin); + ++Begin; + EXPECT_EQ((A + 1)->get(), *Begin); + ++Begin; + EXPECT_EQ((A + 2)->get(), *Begin); + ++Begin; + EXPECT_EQ((A + 3)->get(), *Begin); + ++Begin; + EXPECT_EQ(Begin, End); +} + +TEST(RawPointerIterator, Range) { + std::unique_ptr A[] = { + make_unique(1), + make_unique(2), + make_unique(3), + make_unique(4), + }; + int I = 0; + for (int *P : make_raw_pointer_range(A)) + EXPECT_EQ((A + I++)->get(), P); +} + TEST(ZipIteratorTest, Basic) { using namespace std; const SmallVector pi{3, 1, 4, 1, 5, 9};