[ADT] Generalize pointee_iterator to smart pointers by using decltype.

Based on review feedback from Dave on the original patch.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207146 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2014-04-24 21:10:35 +00:00
parent fda5e19b96
commit 01f21349f2
2 changed files with 45 additions and 4 deletions

View File

@ -163,10 +163,9 @@ public:
/// \code
/// typedef pointee_iterator<SmallVectorImpl<T *>::iterator> iterator;
/// \endcode
template <
typename WrappedIteratorT,
typename T = typename std::remove_pointer<
typename std::iterator_traits<WrappedIteratorT>::value_type>::type>
template <typename WrappedIteratorT,
typename T = typename std::remove_reference<
decltype(**std::declval<WrappedIteratorT>())>::type>
struct pointee_iterator
: iterator_adaptor_base<pointee_iterator<WrappedIteratorT>,
WrappedIteratorT, T> {

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "gtest/gtest.h"
@ -56,4 +57,45 @@ TEST(PointeeIteratorTest, Basic) {
EXPECT_EQ(End, I);
}
TEST(PointeeIteratorTest, SmartPointer) {
SmallVector<std::unique_ptr<int>, 4> V;
V.push_back(make_unique<int>(1));
V.push_back(make_unique<int>(2));
V.push_back(make_unique<int>(3));
V.push_back(make_unique<int>(4));
typedef pointee_iterator<
SmallVectorImpl<std::unique_ptr<int>>::const_iterator> test_iterator;
test_iterator Begin, End;
Begin = V.begin();
End = test_iterator(V.end());
test_iterator I = Begin;
for (int i = 0; i < 4; ++i) {
EXPECT_EQ(*V[i], *I);
EXPECT_EQ(I, Begin + i);
EXPECT_EQ(I, std::next(Begin, i));
test_iterator J = Begin;
J += i;
EXPECT_EQ(I, J);
EXPECT_EQ(*V[i], Begin[i]);
EXPECT_NE(I, End);
EXPECT_GT(End, I);
EXPECT_LT(I, End);
EXPECT_GE(I, Begin);
EXPECT_LE(Begin, I);
EXPECT_EQ(i, I - Begin);
EXPECT_EQ(i, std::distance(Begin, I));
EXPECT_EQ(Begin, I - i);
test_iterator K = I++;
EXPECT_EQ(K, std::prev(I));
}
EXPECT_EQ(End, I);
}
} // anonymous namespace