xref: /aosp_15_r20/external/skia/tests/LListTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/base/SkTInternalLList.h"
9 #include "tests/Test.h"
10 
11 #include <utility>
12 
13 class ListElement {
14 public:
ListElement(int id)15     ListElement(int id) : fID(id) {
16     }
operator ==(const ListElement & other)17     bool operator== (const ListElement& other) { return fID == other.fID; }
18 
19     int fID;
20 
21 private:
22 
23     SK_DECLARE_INTERNAL_LLIST_INTERFACE(ListElement);
24 };
25 
check_list(const SkTInternalLList<ListElement> & list,skiatest::Reporter * reporter,bool empty,int numElements,bool in0,bool in1,bool in2,bool in3,ListElement elements[4])26 static void check_list(const SkTInternalLList<ListElement>& list,
27                        skiatest::Reporter* reporter,
28                        bool empty,
29                        int numElements,
30                        bool in0, bool in1, bool in2, bool in3,
31                        ListElement elements[4]) {
32 
33     REPORTER_ASSERT(reporter, empty == list.isEmpty());
34 #ifdef SK_DEBUG
35     list.validate();
36     REPORTER_ASSERT(reporter, numElements == list.countEntries());
37     REPORTER_ASSERT(reporter, in0 == list.isInList(&elements[0]));
38     REPORTER_ASSERT(reporter, in1 == list.isInList(&elements[1]));
39     REPORTER_ASSERT(reporter, in2 == list.isInList(&elements[2]));
40     REPORTER_ASSERT(reporter, in3 == list.isInList(&elements[3]));
41 #endif
42 }
43 
DEF_TEST(InternalLList,reporter)44 DEF_TEST(InternalLList, reporter) {
45     SkTInternalLList<ListElement> list;
46     ListElement elements[4] = {
47         ListElement(0),
48         ListElement(1),
49         ListElement(2),
50         ListElement(3),
51     };
52 
53     // list should be empty to start with
54     check_list(list, reporter, true, 0, false, false, false, false, elements);
55 
56     list.addToHead(&elements[0]);
57 
58     check_list(list, reporter, false, 1, true, false, false, false, elements);
59 
60     list.addToHead(&elements[1]);
61     list.addToHead(&elements[2]);
62     list.addToHead(&elements[3]);
63 
64     check_list(list, reporter, false, 4, true, true, true, true, elements);
65 
66     // test out iterators
67     typedef SkTInternalLList<ListElement>::Iter Iter;
68     Iter iter;
69 
70     ListElement* cur = iter.init(list, Iter::kHead_IterStart);
71     for (int i = 0; cur; ++i, cur = iter.next()) {
72         REPORTER_ASSERT(reporter, cur->fID == 3-i);
73     }
74 
75     cur = iter.init(list, Iter::kTail_IterStart);
76     for (int i = 0; cur; ++i, cur = iter.prev()) {
77         REPORTER_ASSERT(reporter, cur->fID == i);
78     }
79 
80     // remove middle, frontmost then backmost
81     list.remove(&elements[1]);
82     list.remove(&elements[3]);
83     list.remove(&elements[0]);
84 
85     check_list(list, reporter, false, 1, false, false, true, false, elements);
86 
87     // remove last element
88     list.remove(&elements[2]);
89 
90     // list should be empty again
91     check_list(list, reporter, true, 0, false, false, false, false, elements);
92 
93     // test out methods that add to the middle of the list.
94     list.addAfter(&elements[1], nullptr);
95     check_list(list, reporter, false, 1, false, true, false, false, elements);
96 
97     list.remove(&elements[1]);
98 
99     list.addBefore(&elements[1], nullptr);
100     check_list(list, reporter, false, 1, false, true, false, false, elements);
101 
102     list.addBefore(&elements[0], &elements[1]);
103     check_list(list, reporter, false, 2, true, true, false, false, elements);
104 
105     list.addAfter(&elements[3], &elements[1]);
106     check_list(list, reporter, false, 3, true, true, false, true, elements);
107 
108     list.addBefore(&elements[2], &elements[3]);
109     check_list(list, reporter, false, 4, true, true, true, true, elements);
110 
111     cur = iter.init(list, Iter::kHead_IterStart);
112     for (int i = 0; cur; ++i, cur = iter.next()) {
113         REPORTER_ASSERT(reporter, cur->fID == i);
114     }
115     while (!list.isEmpty()) {
116         list.remove(list.tail());
117     }
118 
119     // test concat.
120     SkTInternalLList<ListElement> listA, listB;
121     listA.concat(std::move(listB));
122     check_list(listA, reporter, true, 0, false, false, false, false, elements);
123     // NOLINTNEXTLINE(bugprone-use-after-move)
124     check_list(listB, reporter, true, 0, false, false, false, false, elements);
125 
126     listB.addToTail(&elements[0]);
127     listA.concat(std::move(listB));
128     check_list(listA, reporter, false, 1, true, false, false, false, elements);
129     // NOLINTNEXTLINE(bugprone-use-after-move)
130     check_list(listB, reporter, true, 0, false, false, false, false, elements);
131 
132     listB.addToTail(&elements[1]);
133     listA.concat(std::move(listB));
134     check_list(listA, reporter, false, 2, true, true, false, false, elements);
135     // NOLINTNEXTLINE(bugprone-use-after-move)
136     check_list(listB, reporter, true, 0, false, false, false, false, elements);
137 
138     listA.concat(std::move(listB));
139     check_list(listA, reporter, false, 2, true, true, false, false, elements);
140     // NOLINTNEXTLINE(bugprone-use-after-move)
141     check_list(listB, reporter, true, 0, false, false, false, false, elements);
142 
143     listB.addToTail(&elements[2]);
144     listB.addToTail(&elements[3]);
145     listA.concat(std::move(listB));
146     check_list(listA, reporter, false, 4, true, true, true, true, elements);
147     // NOLINTNEXTLINE(bugprone-use-after-move)
148     check_list(listB, reporter, true, 0, false, false, false, false, elements);
149 
150     cur = iter.init(listA, Iter::kHead_IterStart);
151     for (int i = 0; cur; ++i, cur = iter.next()) {
152         REPORTER_ASSERT(reporter, cur->fID == i);
153     }
154 }
155