1 //===-- Unittests for queue -----------------------------------------------===// 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 // SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/__support/CPP/string.h" 10 #include "src/__support/char_vector.h" 11 #include "test/UnitTest/Test.h" 12 13 #include "llvm-libc-macros/sys-queue-macros.h" 14 15 using LIBC_NAMESPACE::CharVector; 16 using LIBC_NAMESPACE::cpp::string; 17 18 namespace LIBC_NAMESPACE { 19 20 TEST(LlvmLibcQueueTest, SList) { 21 struct Entry { 22 char c; 23 SLIST_ENTRY(Entry) entries; 24 }; 25 26 SLIST_HEAD(Head, Entry); 27 28 Head head = SLIST_HEAD_INITIALIZER(head); 29 30 struct Contains : public testing::Matcher<Head> { 31 string s; 32 Contains(string s) : s(s) {} 33 bool match(Head head) { 34 Entry *e; 35 CharVector v; 36 SLIST_FOREACH(e, &head, entries) { v.append(e->c); } 37 return s == v.c_str(); 38 } 39 }; 40 41 Entry e1 = {'a', {NULL}}; 42 SLIST_INSERT_HEAD(&head, &e1, entries); 43 44 ASSERT_THAT(head, Contains("a")); 45 46 Entry e2 = {'b', {NULL}}; 47 SLIST_INSERT_AFTER(&e1, &e2, entries); 48 49 ASSERT_THAT(head, Contains("ab")); 50 51 Head head2 = SLIST_HEAD_INITIALIZER(head); 52 53 Entry e3 = {'c', {NULL}}; 54 SLIST_INSERT_HEAD(&head2, &e3, entries); 55 56 ASSERT_THAT(head2, Contains("c")); 57 58 SLIST_SWAP(&head, &head2, Entry); 59 60 ASSERT_THAT(head2, Contains("ab")); 61 62 SLIST_CONCAT(&head2, &head, Entry, entries); 63 64 ASSERT_THAT(head2, Contains("abc")); 65 66 SLIST_CONCAT(&head, &head2, Entry, entries); 67 68 ASSERT_THAT(head, Contains("abc")); 69 70 Entry *e = NULL, *tmp = NULL; 71 SLIST_FOREACH_SAFE(e, &head, entries, tmp) { 72 if (e == &e2) { 73 SLIST_REMOVE(&head, e, Entry, entries); 74 } 75 } 76 77 ASSERT_THAT(head, Contains("ac")); 78 79 while (!SLIST_EMPTY(&head)) { 80 e = SLIST_FIRST(&head); 81 SLIST_REMOVE_HEAD(&head, entries); 82 } 83 84 ASSERT_TRUE(SLIST_EMPTY(&head)); 85 } 86 87 TEST(LlvmLibcQueueTest, STailQ) { 88 struct Entry { 89 char c; 90 STAILQ_ENTRY(Entry) entries; 91 }; 92 93 STAILQ_HEAD(Head, Entry); 94 95 Head head = STAILQ_HEAD_INITIALIZER(head); 96 97 struct Contains : public testing::Matcher<Head> { 98 string s; 99 Contains(string s) : s(s) {} 100 bool match(Head head) { 101 Entry *e; 102 CharVector v; 103 STAILQ_FOREACH(e, &head, entries) { v.append(e->c); } 104 return s == v.c_str(); 105 } 106 }; 107 108 STAILQ_INIT(&head); 109 ASSERT_TRUE(STAILQ_EMPTY(&head)); 110 111 Entry e1 = {'a', {NULL}}; 112 STAILQ_INSERT_HEAD(&head, &e1, entries); 113 114 ASSERT_THAT(head, Contains("a")); 115 116 Entry e2 = {'b', {NULL}}; 117 STAILQ_INSERT_TAIL(&head, &e2, entries); 118 119 ASSERT_THAT(head, Contains("ab")); 120 121 Entry e3 = {'c', {NULL}}; 122 STAILQ_INSERT_AFTER(&head, &e2, &e3, entries); 123 124 ASSERT_THAT(head, Contains("abc")); 125 126 Head head2 = STAILQ_HEAD_INITIALIZER(head); 127 128 Entry e4 = {'d', {NULL}}; 129 STAILQ_INSERT_HEAD(&head2, &e4, entries); 130 131 ASSERT_THAT(head2, Contains("d")); 132 133 STAILQ_SWAP(&head, &head2, Entry); 134 135 ASSERT_THAT(head2, Contains("abc")); 136 137 STAILQ_CONCAT(&head2, &head, Entry, entries); 138 139 ASSERT_EQ(STAILQ_FIRST(&head2), &e1); 140 ASSERT_EQ(STAILQ_LAST(&head2, Entry, entries), &e4); 141 142 ASSERT_THAT(head2, Contains("abcd")); 143 144 STAILQ_CONCAT(&head, &head2, Entry, entries); 145 146 ASSERT_EQ(STAILQ_FIRST(&head), &e1); 147 ASSERT_EQ(STAILQ_LAST(&head, Entry, entries), &e4); 148 149 ASSERT_THAT(head, Contains("abcd")); 150 151 Entry *e = NULL, *tmp = NULL; 152 STAILQ_FOREACH_SAFE(e, &head, entries, tmp) { 153 if (e == &e2) { 154 STAILQ_REMOVE(&head, e, Entry, entries); 155 } 156 } 157 158 ASSERT_THAT(head, Contains("acd")); 159 160 while (!STAILQ_EMPTY(&head)) { 161 e = STAILQ_FIRST(&head); 162 STAILQ_REMOVE_HEAD(&head, entries); 163 } 164 165 ASSERT_TRUE(STAILQ_EMPTY(&head)); 166 } 167 168 } // namespace LIBC_NAMESPACE 169