ImmutableListTest.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. //===--------- ImmutableListTest.cpp - ImmutableList unit tests --*- C++ -*-==//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/ADT/ImmutableList.h"
  9. #include "gtest/gtest.h"
  10. using namespace llvm;
  11. namespace {
  12. template <typename Fundamental> struct Wrapper : llvm::FoldingSetNode {
  13. Fundamental F;
  14. Wrapper(Fundamental F) : F(F) {}
  15. operator Fundamental() const { return F; }
  16. void Profile(FoldingSetNodeID &ID) const { ID.AddInteger(F); }
  17. };
  18. class ImmutableListTest : public testing::Test {};
  19. void concat(const ImmutableList<Wrapper<char>> &L, char *Buffer) {
  20. int Index = 0;
  21. for (ImmutableList<Wrapper<char>>::iterator It = L.begin(), End = L.end();
  22. It != End; ++It) {
  23. Buffer[Index++] = *It;
  24. }
  25. Buffer[Index] = '\0';
  26. }
  27. TEST_F(ImmutableListTest, EmptyIntListTest) {
  28. ImmutableList<Wrapper<int>>::Factory f;
  29. EXPECT_TRUE(f.getEmptyList() == f.getEmptyList());
  30. EXPECT_TRUE(f.getEmptyList().isEqual(f.getEmptyList()));
  31. EXPECT_TRUE(f.getEmptyList().isEmpty());
  32. ImmutableList<Wrapper<int>> L = f.getEmptyList();
  33. EXPECT_EQ(nullptr, L.getTail().getInternalPointer());
  34. EXPECT_TRUE(L.getTail().isEmpty());
  35. EXPECT_TRUE(L.begin() == L.end());
  36. }
  37. TEST_F(ImmutableListTest, OneElemIntListTest) {
  38. ImmutableList<Wrapper<int>>::Factory f;
  39. ImmutableList<Wrapper<int>> L = f.getEmptyList();
  40. ImmutableList<Wrapper<int>> L2 = f.add(3, L);
  41. EXPECT_TRUE(L.isEmpty());
  42. EXPECT_FALSE(L2.isEmpty());
  43. EXPECT_TRUE(L2.getTail().isEmpty());
  44. EXPECT_FALSE(L == L2);
  45. EXPECT_TRUE(L == L2.getTail());
  46. EXPECT_FALSE(L.isEqual(L2));
  47. EXPECT_TRUE(L.isEqual(L2.getTail()));
  48. EXPECT_FALSE(L2.begin() == L2.end());
  49. EXPECT_TRUE(L2.begin() != L2.end());
  50. EXPECT_FALSE(L.contains(3));
  51. EXPECT_EQ(3, L2.getHead());
  52. EXPECT_TRUE(L2.contains(3));
  53. ImmutableList<Wrapper<int>> L3 = f.add(2, L);
  54. EXPECT_TRUE(L.isEmpty());
  55. EXPECT_FALSE(L3.isEmpty());
  56. EXPECT_FALSE(L == L3);
  57. EXPECT_FALSE(L.contains(2));
  58. EXPECT_TRUE(L3.contains(2));
  59. EXPECT_EQ(2, L3.getHead());
  60. EXPECT_FALSE(L2 == L3);
  61. EXPECT_FALSE(L2.contains(2));
  62. }
  63. // We'll store references to objects of this type.
  64. struct Unmodifiable {
  65. Unmodifiable() = default;
  66. // We'll delete all of these special member functions to make sure no copy or
  67. // move happens during insertation.
  68. Unmodifiable(const Unmodifiable &) = delete;
  69. Unmodifiable(const Unmodifiable &&) = delete;
  70. Unmodifiable &operator=(const Unmodifiable &) = delete;
  71. Unmodifiable &operator=(const Unmodifiable &&) = delete;
  72. void doNothing() const {}
  73. void Profile(FoldingSetNodeID &ID) const { ID.AddPointer(this); }
  74. };
  75. // Mostly just a check whether ImmutableList::iterator can be instantiated
  76. // with a reference type as a template argument.
  77. TEST_F(ImmutableListTest, ReferenceStoringTest) {
  78. ImmutableList<const Unmodifiable &>::Factory f;
  79. Unmodifiable N;
  80. ImmutableList<const Unmodifiable &> L = f.create(N);
  81. for (ImmutableList<const Unmodifiable &>::iterator It = L.begin(),
  82. E = L.end();
  83. It != E; ++It) {
  84. It->doNothing();
  85. }
  86. }
  87. TEST_F(ImmutableListTest, CreatingIntListTest) {
  88. ImmutableList<Wrapper<int>>::Factory f;
  89. ImmutableList<Wrapper<int>> L = f.getEmptyList();
  90. ImmutableList<Wrapper<int>> L2 = f.create(3);
  91. EXPECT_FALSE(L2.isEmpty());
  92. EXPECT_TRUE(L2.getTail().isEmpty());
  93. EXPECT_EQ(3, L2.getHead());
  94. EXPECT_TRUE(L.isEqual(L2.getTail()));
  95. EXPECT_TRUE(L2.getTail().isEqual(L));
  96. }
  97. TEST_F(ImmutableListTest, MultiElemIntListTest) {
  98. ImmutableList<Wrapper<int>>::Factory f;
  99. ImmutableList<Wrapper<int>> L = f.getEmptyList();
  100. ImmutableList<Wrapper<int>> L2 = f.add(5, f.add(4, f.add(3, L)));
  101. ImmutableList<Wrapper<int>> L3 = f.add(43, f.add(20, f.add(9, L2)));
  102. ImmutableList<Wrapper<int>> L4 = f.add(9, L2);
  103. ImmutableList<Wrapper<int>> L5 = f.add(9, L2);
  104. EXPECT_TRUE(L.isEmpty());
  105. EXPECT_FALSE(L2.isEmpty());
  106. EXPECT_FALSE(L3.isEmpty());
  107. EXPECT_FALSE(L4.isEmpty());
  108. EXPECT_FALSE(L.contains(3));
  109. EXPECT_FALSE(L.contains(9));
  110. EXPECT_TRUE(L2.contains(3));
  111. EXPECT_TRUE(L2.contains(4));
  112. EXPECT_TRUE(L2.contains(5));
  113. EXPECT_FALSE(L2.contains(9));
  114. EXPECT_FALSE(L2.contains(0));
  115. EXPECT_EQ(5, L2.getHead());
  116. EXPECT_EQ(4, L2.getTail().getHead());
  117. EXPECT_EQ(3, L2.getTail().getTail().getHead());
  118. EXPECT_TRUE(L3.contains(43));
  119. EXPECT_TRUE(L3.contains(20));
  120. EXPECT_TRUE(L3.contains(9));
  121. EXPECT_TRUE(L3.contains(3));
  122. EXPECT_TRUE(L3.contains(4));
  123. EXPECT_TRUE(L3.contains(5));
  124. EXPECT_FALSE(L3.contains(0));
  125. EXPECT_EQ(43, L3.getHead());
  126. EXPECT_EQ(20, L3.getTail().getHead());
  127. EXPECT_EQ(9, L3.getTail().getTail().getHead());
  128. EXPECT_TRUE(L3.getTail().getTail().getTail() == L2);
  129. EXPECT_TRUE(L2 == L3.getTail().getTail().getTail());
  130. EXPECT_TRUE(L3.getTail().getTail().getTail().isEqual(L2));
  131. EXPECT_TRUE(L2.isEqual(L3.getTail().getTail().getTail()));
  132. EXPECT_TRUE(L4.contains(9));
  133. EXPECT_TRUE(L4.contains(3));
  134. EXPECT_TRUE(L4.contains(4));
  135. EXPECT_TRUE(L4.contains(5));
  136. EXPECT_FALSE(L4.contains(20));
  137. EXPECT_FALSE(L4.contains(43));
  138. EXPECT_TRUE(L4.isEqual(L4));
  139. EXPECT_TRUE(L4.isEqual(L5));
  140. EXPECT_TRUE(L5.isEqual(L4));
  141. EXPECT_TRUE(L5.isEqual(L5));
  142. }
  143. template <typename Fundamental>
  144. struct ExplicitCtorWrapper : public Wrapper<Fundamental> {
  145. explicit ExplicitCtorWrapper(Fundamental F) : Wrapper<Fundamental>(F) {}
  146. ExplicitCtorWrapper(const ExplicitCtorWrapper &) = delete;
  147. ExplicitCtorWrapper(ExplicitCtorWrapper &&) = default;
  148. ExplicitCtorWrapper &operator=(const ExplicitCtorWrapper &) = delete;
  149. ExplicitCtorWrapper &operator=(ExplicitCtorWrapper &&) = default;
  150. };
  151. TEST_F(ImmutableListTest, EmplaceIntListTest) {
  152. ImmutableList<ExplicitCtorWrapper<int>>::Factory f;
  153. ImmutableList<ExplicitCtorWrapper<int>> L = f.getEmptyList();
  154. ImmutableList<ExplicitCtorWrapper<int>> L2 = f.emplace(L, 3);
  155. ImmutableList<ExplicitCtorWrapper<int>> L3 =
  156. f.add(ExplicitCtorWrapper<int>(2), L2);
  157. ImmutableList<ExplicitCtorWrapper<int>> L4 =
  158. f.emplace(L3, ExplicitCtorWrapper<int>(1));
  159. ImmutableList<ExplicitCtorWrapper<int>> L5 =
  160. f.add(ExplicitCtorWrapper<int>(1), L3);
  161. EXPECT_FALSE(L2.isEmpty());
  162. EXPECT_TRUE(L2.getTail().isEmpty());
  163. EXPECT_EQ(3, L2.getHead());
  164. EXPECT_TRUE(L.isEqual(L2.getTail()));
  165. EXPECT_TRUE(L2.getTail().isEqual(L));
  166. EXPECT_FALSE(L3.isEmpty());
  167. EXPECT_FALSE(L2 == L3);
  168. EXPECT_EQ(2, L3.getHead());
  169. EXPECT_TRUE(L2 == L3.getTail());
  170. EXPECT_FALSE(L4.isEmpty());
  171. EXPECT_EQ(1, L4.getHead());
  172. EXPECT_TRUE(L3 == L4.getTail());
  173. EXPECT_TRUE(L4 == L5);
  174. EXPECT_TRUE(L3 == L5.getTail());
  175. }
  176. TEST_F(ImmutableListTest, CharListOrderingTest) {
  177. ImmutableList<Wrapper<char>>::Factory f;
  178. ImmutableList<Wrapper<char>> L = f.getEmptyList();
  179. ImmutableList<Wrapper<char>> L2 = f.add('i', f.add('e', f.add('a', L)));
  180. ImmutableList<Wrapper<char>> L3 = f.add('u', f.add('o', L2));
  181. char Buffer[10];
  182. concat(L3, Buffer);
  183. ASSERT_STREQ("uoiea", Buffer);
  184. }
  185. TEST_F(ImmutableListTest, LongListOrderingTest) {
  186. ImmutableList<Wrapper<long>>::Factory f;
  187. ImmutableList<Wrapper<long>> L = f.getEmptyList();
  188. ImmutableList<Wrapper<long>> L2 = f.add(3, f.add(4, f.add(5, L)));
  189. ImmutableList<Wrapper<long>> L3 = f.add(0, f.add(1, f.add(2, L2)));
  190. int i = 0;
  191. for (ImmutableList<Wrapper<long>>::iterator I = L.begin(), E = L.end();
  192. I != E; ++I) {
  193. ASSERT_EQ(i, *I);
  194. i++;
  195. }
  196. ASSERT_EQ(0, i);
  197. i = 3;
  198. for (ImmutableList<Wrapper<long>>::iterator I = L2.begin(), E = L2.end();
  199. I != E; ++I) {
  200. ASSERT_EQ(i, *I);
  201. i++;
  202. }
  203. ASSERT_EQ(6, i);
  204. i = 0;
  205. for (ImmutableList<Wrapper<long>>::iterator I = L3.begin(), E = L3.end();
  206. I != E; ++I) {
  207. ASSERT_EQ(i, *I);
  208. i++;
  209. }
  210. ASSERT_EQ(6, i);
  211. }
  212. static_assert(is_trivially_copyable<ImmutableList<Wrapper<long>>>::value,
  213. "trivially copyable");
  214. } // namespace