[PATCH] D58088: [adt] Add raw_pointer_iterator to iterate over std::unique_ptr<> collections
Daniel Sanders via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 11 16:36:24 PST 2019
dsanders created this revision.
dsanders added reviewers: bogner, volkan, aditya_nandakumar, paquette, aemerson.
Herald added subscribers: kristina, dexonsmith.
Herald added a project: LLVM.
raw_pointer_iterator adapts the usual iterator by calling get() on the
value when being dereferenced. This allows users to iterate over things
like std::vector<std::unique_ptr<foo>> while preserving ownership and not
calling the deleted copy constructor.
This is similar to pointer_iterator except that pointer_iterator will attempt
to copy the pointer which is not possible for unique_ptr.
Repository:
rL LLVM
https://reviews.llvm.org/D58088
Files:
include/llvm/ADT/iterator.h
unittests/ADT/IteratorTest.cpp
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<int> A[] = {
+ make_unique<int>(1),
+ make_unique<int>(2),
+ make_unique<int>(3),
+ make_unique<int>(4),
+ };
+ raw_pointer_iterator<std::unique_ptr<int> *> 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<int> A[] = {
+ make_unique<int>(1),
+ make_unique<int>(2),
+ make_unique<int>(3),
+ make_unique<int>(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<unsigned, 6> pi{3, 1, 4, 1, 5, 9};
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 <typename WrappedIteratorT,
+ typename T = typename std::remove_reference<decltype(*std::declval<WrappedIteratorT>())>::type::pointer>
+class raw_pointer_iterator
+ : public iterator_adaptor_base<
+ raw_pointer_iterator<WrappedIteratorT, T>, WrappedIteratorT,
+ typename std::iterator_traits<WrappedIteratorT>::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 <typename RangeT, typename WrappedIteratorT =
+ decltype(std::begin(std::declval<RangeT>()))>
+iterator_range<raw_pointer_iterator<WrappedIteratorT>>
+make_raw_pointer_range(RangeT &&Range) {
+ using RawPointerIteratorT = raw_pointer_iterator<WrappedIteratorT>;
+ return make_range(RawPointerIteratorT(std::begin(std::forward<RangeT>(Range))),
+ RawPointerIteratorT(std::end(std::forward<RangeT>(Range))));
+}
} // end namespace llvm
#endif // LLVM_ADT_ITERATOR_H
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58088.186368.patch
Type: text/x-patch
Size: 2616 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190212/10f178ff/attachment.bin>
More information about the llvm-commits
mailing list