xref: /llvm-project/libc/test/src/search/insque_test.cpp (revision 78a12f94904b69dd8b13f3e3fd258334b77ee7b8)
1*78a12f94SSirui Mu //===-- Unittests for insque ----------------------------------------------===//
2*78a12f94SSirui Mu //
3*78a12f94SSirui Mu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*78a12f94SSirui Mu // See https://llvm.org/LICENSE.txt for license information.
5*78a12f94SSirui Mu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*78a12f94SSirui Mu //
7*78a12f94SSirui Mu //===----------------------------------------------------------------------===//
8*78a12f94SSirui Mu 
9*78a12f94SSirui Mu #include "src/search/insque.h"
10*78a12f94SSirui Mu #include "src/search/remque.h"
11*78a12f94SSirui Mu #include "test/UnitTest/Test.h"
12*78a12f94SSirui Mu 
13*78a12f94SSirui Mu namespace {
14*78a12f94SSirui Mu 
15*78a12f94SSirui Mu struct Node {
16*78a12f94SSirui Mu   Node *next;
17*78a12f94SSirui Mu   Node *prev;
18*78a12f94SSirui Mu };
19*78a12f94SSirui Mu 
make_linear_links(Node (& nodes)[N])20*78a12f94SSirui Mu template <unsigned N> void make_linear_links(Node (&nodes)[N]) {
21*78a12f94SSirui Mu   for (unsigned i = 0; i < N; ++i) {
22*78a12f94SSirui Mu     if (i == N - 1)
23*78a12f94SSirui Mu       nodes[i].next = nullptr;
24*78a12f94SSirui Mu     else
25*78a12f94SSirui Mu       nodes[i].next = &nodes[i + 1];
26*78a12f94SSirui Mu 
27*78a12f94SSirui Mu     if (i == 0)
28*78a12f94SSirui Mu       nodes[i].prev = nullptr;
29*78a12f94SSirui Mu     else
30*78a12f94SSirui Mu       nodes[i].prev = &nodes[i - 1];
31*78a12f94SSirui Mu   }
32*78a12f94SSirui Mu }
33*78a12f94SSirui Mu 
make_circular_links(Node (& nodes)[N])34*78a12f94SSirui Mu template <unsigned N> void make_circular_links(Node (&nodes)[N]) {
35*78a12f94SSirui Mu   for (unsigned i = 0; i < N; ++i) {
36*78a12f94SSirui Mu     nodes[i].next = &nodes[(i + 1) % N];
37*78a12f94SSirui Mu     nodes[i].prev = &nodes[(i + N - 1) % N];
38*78a12f94SSirui Mu   }
39*78a12f94SSirui Mu }
40*78a12f94SSirui Mu 
41*78a12f94SSirui Mu } // namespace
42*78a12f94SSirui Mu 
43*78a12f94SSirui Mu class LlvmLibcInsqueTest : public LIBC_NAMESPACE::testing::Test {
44*78a12f94SSirui Mu protected:
45*78a12f94SSirui Mu   template <unsigned N>
check_linear(const Node * head,const Node * const (& nodes)[N])46*78a12f94SSirui Mu   void check_linear(const Node *head, const Node *const (&nodes)[N]) {
47*78a12f94SSirui Mu     // First make sure that the given N nodes form a valid linear list.
48*78a12f94SSirui Mu     for (unsigned i = 0; i < N; ++i) {
49*78a12f94SSirui Mu       const Node *next = nullptr;
50*78a12f94SSirui Mu       if (i + 1 < N)
51*78a12f94SSirui Mu         next = nodes[i + 1];
52*78a12f94SSirui Mu 
53*78a12f94SSirui Mu       const Node *prev = nullptr;
54*78a12f94SSirui Mu       if (i > 0)
55*78a12f94SSirui Mu         prev = nodes[i - 1];
56*78a12f94SSirui Mu 
57*78a12f94SSirui Mu       EXPECT_EQ(static_cast<const Node *>(nodes[i]->next), next);
58*78a12f94SSirui Mu       EXPECT_EQ(static_cast<const Node *>(nodes[i]->prev), prev);
59*78a12f94SSirui Mu     }
60*78a12f94SSirui Mu 
61*78a12f94SSirui Mu     // Then check the list nodes match.
62*78a12f94SSirui Mu     for (unsigned i = 0; i < N; ++i) {
63*78a12f94SSirui Mu       EXPECT_EQ(head, nodes[i]);
64*78a12f94SSirui Mu       // Traversal by head should always be OK since we have already confirmed
65*78a12f94SSirui Mu       // the validity of links.
66*78a12f94SSirui Mu       head = head->next;
67*78a12f94SSirui Mu     }
68*78a12f94SSirui Mu   }
69*78a12f94SSirui Mu 
70*78a12f94SSirui Mu   template <unsigned N>
check_circular(const Node * head,const Node * const (& nodes)[N])71*78a12f94SSirui Mu   void check_circular(const Node *head, const Node *const (&nodes)[N]) {
72*78a12f94SSirui Mu     // First make sure that the given N nodes form a valid linear list.
73*78a12f94SSirui Mu     for (unsigned i = 0; i < N; ++i) {
74*78a12f94SSirui Mu       auto next = nodes[(i + 1) % N];
75*78a12f94SSirui Mu       auto prev = nodes[(i + N - 1) % N];
76*78a12f94SSirui Mu 
77*78a12f94SSirui Mu       EXPECT_EQ(static_cast<const Node *>(nodes[i]->prev), prev);
78*78a12f94SSirui Mu       EXPECT_EQ(static_cast<const Node *>(nodes[i]->next), next);
79*78a12f94SSirui Mu     }
80*78a12f94SSirui Mu 
81*78a12f94SSirui Mu     // Then check the list nodes match.
82*78a12f94SSirui Mu     for (unsigned i = 0; i < N; ++i) {
83*78a12f94SSirui Mu       EXPECT_EQ(head, nodes[i]);
84*78a12f94SSirui Mu       // Traversal by head should always be OK since we have already confirmed
85*78a12f94SSirui Mu       // the validity of links.
86*78a12f94SSirui Mu       head = head->next;
87*78a12f94SSirui Mu     }
88*78a12f94SSirui Mu   }
89*78a12f94SSirui Mu };
90*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,InsertToNull)91*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, InsertToNull) {
92*78a12f94SSirui Mu   Node node{nullptr, nullptr};
93*78a12f94SSirui Mu   LIBC_NAMESPACE::insque(&node, nullptr);
94*78a12f94SSirui Mu   check_linear(&node, {&node});
95*78a12f94SSirui Mu }
96*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,InsertToLinearSingleton)97*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, InsertToLinearSingleton) {
98*78a12f94SSirui Mu   Node base[1];
99*78a12f94SSirui Mu   make_linear_links(base);
100*78a12f94SSirui Mu 
101*78a12f94SSirui Mu   Node incoming{nullptr, nullptr};
102*78a12f94SSirui Mu   LIBC_NAMESPACE::insque(&incoming, &base[0]);
103*78a12f94SSirui Mu   check_linear(base, {&base[0], &incoming});
104*78a12f94SSirui Mu }
105*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,InsertToLinearMiddle)106*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, InsertToLinearMiddle) {
107*78a12f94SSirui Mu   Node base[3];
108*78a12f94SSirui Mu   make_linear_links(base);
109*78a12f94SSirui Mu 
110*78a12f94SSirui Mu   Node incoming{nullptr, nullptr};
111*78a12f94SSirui Mu   LIBC_NAMESPACE::insque(&incoming, &base[1]);
112*78a12f94SSirui Mu   check_linear(base, {&base[0], &base[1], &incoming, &base[2]});
113*78a12f94SSirui Mu }
114*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,InsertToLinearBack)115*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, InsertToLinearBack) {
116*78a12f94SSirui Mu   Node base[3];
117*78a12f94SSirui Mu   make_linear_links(base);
118*78a12f94SSirui Mu 
119*78a12f94SSirui Mu   Node incoming{nullptr, nullptr};
120*78a12f94SSirui Mu   LIBC_NAMESPACE::insque(&incoming, &base[2]);
121*78a12f94SSirui Mu   check_linear(base, {&base[0], &base[1], &base[2], &incoming});
122*78a12f94SSirui Mu }
123*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,InsertToCircularSingleton)124*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, InsertToCircularSingleton) {
125*78a12f94SSirui Mu   Node base[1];
126*78a12f94SSirui Mu   make_circular_links(base);
127*78a12f94SSirui Mu 
128*78a12f94SSirui Mu   Node incoming{nullptr, nullptr};
129*78a12f94SSirui Mu   LIBC_NAMESPACE::insque(&incoming, &base[0]);
130*78a12f94SSirui Mu   check_circular(base, {&base[0], &incoming});
131*78a12f94SSirui Mu }
132*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,InsertToCircular)133*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, InsertToCircular) {
134*78a12f94SSirui Mu   Node base[3];
135*78a12f94SSirui Mu   make_circular_links(base);
136*78a12f94SSirui Mu 
137*78a12f94SSirui Mu   Node incoming{nullptr, nullptr};
138*78a12f94SSirui Mu   LIBC_NAMESPACE::insque(&incoming, &base[1]);
139*78a12f94SSirui Mu   check_circular(base, {&base[0], &base[1], &incoming, &base[2]});
140*78a12f94SSirui Mu }
141*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,RemoveFromLinearSingleton)142*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, RemoveFromLinearSingleton) {
143*78a12f94SSirui Mu   Node node{nullptr, nullptr};
144*78a12f94SSirui Mu   LIBC_NAMESPACE::remque(&node);
145*78a12f94SSirui Mu   ASSERT_EQ(node.next, static_cast<Node *>(nullptr));
146*78a12f94SSirui Mu   ASSERT_EQ(node.prev, static_cast<Node *>(nullptr));
147*78a12f94SSirui Mu }
148*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,RemoveFromLinearFront)149*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, RemoveFromLinearFront) {
150*78a12f94SSirui Mu   Node base[3];
151*78a12f94SSirui Mu   make_linear_links(base);
152*78a12f94SSirui Mu 
153*78a12f94SSirui Mu   LIBC_NAMESPACE::remque(&base[0]);
154*78a12f94SSirui Mu   check_linear(&base[1], {&base[1], &base[2]});
155*78a12f94SSirui Mu }
156*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,RemoveFromLinearMiddle)157*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, RemoveFromLinearMiddle) {
158*78a12f94SSirui Mu   Node base[3];
159*78a12f94SSirui Mu   make_linear_links(base);
160*78a12f94SSirui Mu 
161*78a12f94SSirui Mu   LIBC_NAMESPACE::remque(&base[1]);
162*78a12f94SSirui Mu   check_linear(&base[0], {&base[0], &base[2]});
163*78a12f94SSirui Mu }
164*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,RemoveFromLinearBack)165*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, RemoveFromLinearBack) {
166*78a12f94SSirui Mu   Node base[3];
167*78a12f94SSirui Mu   make_linear_links(base);
168*78a12f94SSirui Mu 
169*78a12f94SSirui Mu   LIBC_NAMESPACE::remque(&base[2]);
170*78a12f94SSirui Mu   check_linear(&base[0], {&base[0], &base[1]});
171*78a12f94SSirui Mu }
172*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,RemoveFromCircularSingleton)173*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, RemoveFromCircularSingleton) {
174*78a12f94SSirui Mu   Node node[1];
175*78a12f94SSirui Mu   make_circular_links(node);
176*78a12f94SSirui Mu 
177*78a12f94SSirui Mu   LIBC_NAMESPACE::remque(&node[0]);
178*78a12f94SSirui Mu }
179*78a12f94SSirui Mu 
TEST_F(LlvmLibcInsqueTest,RemoveFromCircular)180*78a12f94SSirui Mu TEST_F(LlvmLibcInsqueTest, RemoveFromCircular) {
181*78a12f94SSirui Mu   Node base[3];
182*78a12f94SSirui Mu   make_circular_links(base);
183*78a12f94SSirui Mu 
184*78a12f94SSirui Mu   LIBC_NAMESPACE::remque(&base[1]);
185*78a12f94SSirui Mu   check_circular(&base[0], {&base[0], &base[2]});
186*78a12f94SSirui Mu }
187