xref: /aosp_15_r20/external/angle/src/common/CircularBuffer_unittest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // CircularBuffer_unittest:
7 //   Tests of the CircularBuffer class
8 //
9 
10 #include <gtest/gtest.h>
11 
12 #include "common/CircularBuffer.h"
13 
14 namespace angle
15 {
16 // Make sure the various constructors compile and do basic checks
TEST(CircularBuffer,Constructors)17 TEST(CircularBuffer, Constructors)
18 {
19     CircularBuffer<int, 5> defaultContructor;
20     EXPECT_EQ(5u, defaultContructor.size());
21 
22     CircularBuffer<int, 5> valueConstructor(3);
23     EXPECT_EQ(5u, valueConstructor.size());
24     EXPECT_EQ(3, valueConstructor.front());
25 
26     CircularBuffer<int, 5> copy(valueConstructor);
27     EXPECT_EQ(5u, copy.size());
28 
29     CircularBuffer<int, 5> copyRValue(std::move(valueConstructor));
30     EXPECT_EQ(5u, copyRValue.size());
31 }
32 
33 // Make sure the destructor destroys all elements.
TEST(CircularBuffer,Destructor)34 TEST(CircularBuffer, Destructor)
35 {
36     struct s
37     {
38         s() {}
39         s(int *c) : counter(c) {}
40         ~s()
41         {
42             if (counter)
43             {
44                 ++*counter;
45             }
46         }
47 
48         s(const s &) = default;
49         s &operator=(const s &) = default;
50 
51         int *counter;
52     };
53 
54     int destructorCount = 0;
55 
56     {
57         CircularBuffer<s, 11> buf((s(&destructorCount)));
58 
59         // Destructor called once for the temporary above.
60         EXPECT_EQ(destructorCount, 1);
61 
62         // Change front index to be non-zero.
63         buf.next();
64         buf.next();
65         buf.next();
66     }
67 
68     // Destructor should be called 11 more times, once for each element.
69     EXPECT_EQ(destructorCount, 12);
70 }
71 
72 // Test circulating behavior.
TEST(CircularBuffer,Circulate)73 TEST(CircularBuffer, Circulate)
74 {
75     CircularBuffer<int, 7> buf(128);
76 
77     for (int i = 0; i < 7; ++i)
78     {
79         int &value = buf.front();
80         EXPECT_EQ(value, 128);
81 
82         value = i + 10;
83 
84         buf.next();
85     }
86 
87     for (int i = 0; i < 93; ++i)
88     {
89         EXPECT_EQ(buf.front(), i % 7 + 10);
90         buf.next();
91     }
92 }
93 
94 // Test iteration.
TEST(CircularBuffer,Iterate)95 TEST(CircularBuffer, Iterate)
96 {
97     CircularBuffer<int, 3> buf(12);
98 
99     for (int i = 0; i < 3; ++i)
100     {
101         int &value = buf.front();
102         buf.next();
103 
104         EXPECT_EQ(value, 12);
105 
106         value = i;
107     }
108 
109     // Check that iteration returns all the values (with unknown order) regardless of where the
110     // front is pointing.
111     for (int i = 0; i < 10; ++i)
112     {
113         uint32_t valuesSeen = 0;
114         for (int value : buf)
115         {
116             valuesSeen |= 1 << value;
117         }
118         EXPECT_EQ(valuesSeen, 0x7u);
119 
120         // Make sure iteration hasn't affected the front index.
121         EXPECT_EQ(buf.front(), i % 3);
122 
123         buf.next();
124     }
125 }
126 
127 // Tests buffer operations with a non copyable type.
TEST(CircularBuffer,NonCopyable)128 TEST(CircularBuffer, NonCopyable)
129 {
130     struct s : angle::NonCopyable
131     {
132         s() : x(0) {}
133         s(s &&other) : x(other.x) {}
134         s &operator=(s &&other)
135         {
136             x = other.x;
137             return *this;
138         }
139         int x;
140     };
141 
142     CircularBuffer<s, 4> buf;
143 
144     for (int i = 0; i < 4; ++i)
145     {
146         s &value = buf.front();
147         value.x  = i;
148 
149         buf.next();
150     }
151 
152     // Make the front index non-zero.
153     buf.next();
154     EXPECT_EQ(buf.front().x, 1);
155 
156     CircularBuffer<s, 4> copy = std::move(buf);
157 
158     for (int i = 0; i < 4; ++i)
159     {
160         EXPECT_EQ(copy.front().x, (i + 1) % 4);
161         copy.next();
162     }
163 }
164 }  // namespace angle
165