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 | // SPDX-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 | |
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 | |
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 | |