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