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 "include/llvm-libc-macros/sys-queue-macros.h"
14
15using LIBC_NAMESPACE::CharVector;
16using LIBC_NAMESPACE::cpp::string;
17
18namespace LIBC_NAMESPACE {
19
20TEST(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(new_char: e->c); }
37 return s == v.c_str();
38 }
39 };
40
41 Entry e1 = {.c: 'a', .entries: {NULL}};
42 SLIST_INSERT_HEAD(&head, &e1, entries);
43
44 ASSERT_THAT(head, Contains("a"));
45
46 Entry e2 = {.c: 'b', .entries: {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: 'c', .entries: {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
87TEST(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(new_char: 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 = {.c: 'a', .entries: {NULL}};
112 STAILQ_INSERT_HEAD(&head, &e1, entries);
113
114 ASSERT_THAT(head, Contains("a"));
115
116 Entry e2 = {.c: 'b', .entries: {NULL}};
117 STAILQ_INSERT_TAIL(&head, &e2, entries);
118
119 ASSERT_THAT(head, Contains("ab"));
120
121 Entry e3 = {.c: 'c', .entries: {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 = {.c: 'd', .entries: {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

source code of libc/test/include/sys/queue_test.cpp