| //===- llvm/unittest/Support/ReverseIterationTest.cpp ---------------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===---------------------------------------------------------------------===// | |
| // | |
| // Reverse Iteration unit tests. | |
| // | |
| //===---------------------------------------------------------------------===// | |
| #include "llvm/Support/ReverseIteration.h" | |
| #include "llvm/ADT/DenseMap.h" | |
| #include "llvm/ADT/DenseMapInfo.h" | |
| #include "gtest/gtest.h" | |
| using namespace llvm; | |
| TEST(ReverseIterationTest, DenseMapTest1) { | |
| static_assert(detail::IsPointerLike<int *>::value, | |
| "int * is pointer-like"); | |
| static_assert(detail::IsPointerLike<uintptr_t>::value, | |
| "uintptr_t is pointer-like"); | |
| static_assert(!detail::IsPointerLike<int>::value, | |
| "int is not pointer-like"); | |
| static_assert(detail::IsPointerLike<void *>::value, | |
| "void * is pointer-like"); | |
| struct IncompleteType; | |
| static_assert(detail::IsPointerLike<IncompleteType *>::value, | |
| "incomplete * is pointer-like"); | |
| // For a DenseMap with non-pointer-like keys, forward iteration equals | |
| // reverse iteration. | |
| DenseMap<int, int> Map; | |
| int Keys[] = { 1, 2, 3, 4 }; | |
| // Insert keys into the DenseMap. | |
| for (auto Key: Keys) | |
| Map[Key] = 0; | |
| // Note: This is the observed order of keys in the DenseMap. | |
| // If there is any change in the behavior of the DenseMap, this order | |
| // would need to be adjusted accordingly. | |
| int IterKeys[] = { 2, 4, 1, 3 }; | |
| // Check that the DenseMap is iterated in the expected order. | |
| for (const auto &Tuple : zip(Map, IterKeys)) | |
| ASSERT_EQ(std::get<0>(Tuple).first, std::get<1>(Tuple)); | |
| // Check operator++ (post-increment). | |
| int i = 0; | |
| for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i) | |
| ASSERT_EQ(iter->first, IterKeys[i]); | |
| } | |
| // Define a pointer-like int. | |
| struct PtrLikeInt { int value; }; | |
| namespace llvm { | |
| template<> struct DenseMapInfo<PtrLikeInt *> { | |
| static PtrLikeInt *getEmptyKey() { | |
| static PtrLikeInt EmptyKey; | |
| return &EmptyKey; | |
| } | |
| static PtrLikeInt *getTombstoneKey() { | |
| static PtrLikeInt TombstoneKey; | |
| return &TombstoneKey; | |
| } | |
| static int getHashValue(const PtrLikeInt *P) { | |
| return P->value; | |
| } | |
| static bool isEqual(const PtrLikeInt *LHS, const PtrLikeInt *RHS) { | |
| return LHS == RHS; | |
| } | |
| }; | |
| } // end namespace llvm | |
| TEST(ReverseIterationTest, DenseMapTest2) { | |
| static_assert(detail::IsPointerLike<PtrLikeInt *>::value, | |
| "PtrLikeInt * is pointer-like"); | |
| PtrLikeInt a = {4}, b = {8}, c = {12}, d = {16}; | |
| PtrLikeInt *Keys[] = { &a, &b, &c, &d }; | |
| // Insert keys into the DenseMap. | |
| DenseMap<PtrLikeInt *, int> Map; | |
| for (auto *Key : Keys) | |
| Map[Key] = Key->value; | |
| // Note: If there is any change in the behavior of the DenseMap, | |
| // the observed order of keys would need to be adjusted accordingly. | |
| if (shouldReverseIterate<PtrLikeInt *>()) | |
| std::reverse(&Keys[0], &Keys[4]); | |
| // Check that the DenseMap is iterated in the expected order. | |
| for (const auto &Tuple : zip(Map, Keys)) | |
| ASSERT_EQ(std::get<0>(Tuple).second, std::get<1>(Tuple)->value); | |
| // Check operator++ (post-increment). | |
| int i = 0; | |
| for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i) | |
| ASSERT_EQ(iter->second, Keys[i]->value); | |
| } |