xref: /llvm-project/libc/test/include/sys/queue_test.cpp (revision dbc09553149dee5ff5d4a8f544f56df5f01c584a)
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