1*09537850SAkhilesh Sanikop // Copyright 2021 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop // http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop
15*09537850SAkhilesh Sanikop #include "src/utils/unbounded_queue.h"
16*09537850SAkhilesh Sanikop
17*09537850SAkhilesh Sanikop #include <new>
18*09537850SAkhilesh Sanikop #include <utility>
19*09537850SAkhilesh Sanikop
20*09537850SAkhilesh Sanikop #include "gtest/gtest.h"
21*09537850SAkhilesh Sanikop
22*09537850SAkhilesh Sanikop namespace libgav1 {
23*09537850SAkhilesh Sanikop namespace {
24*09537850SAkhilesh Sanikop
25*09537850SAkhilesh Sanikop class Integer {
26*09537850SAkhilesh Sanikop public:
Integer(int value)27*09537850SAkhilesh Sanikop explicit Integer(int value) : value_(new (std::nothrow) int{value}) {}
28*09537850SAkhilesh Sanikop
29*09537850SAkhilesh Sanikop // Move only.
Integer(Integer && other)30*09537850SAkhilesh Sanikop Integer(Integer&& other) : value_(other.value_) { other.value_ = nullptr; }
operator =(Integer && other)31*09537850SAkhilesh Sanikop Integer& operator=(Integer&& other) {
32*09537850SAkhilesh Sanikop if (this != &other) {
33*09537850SAkhilesh Sanikop delete value_;
34*09537850SAkhilesh Sanikop value_ = other.value_;
35*09537850SAkhilesh Sanikop other.value_ = nullptr;
36*09537850SAkhilesh Sanikop }
37*09537850SAkhilesh Sanikop return *this;
38*09537850SAkhilesh Sanikop }
39*09537850SAkhilesh Sanikop
~Integer()40*09537850SAkhilesh Sanikop ~Integer() { delete value_; }
41*09537850SAkhilesh Sanikop
value() const42*09537850SAkhilesh Sanikop int value() const { return *value_; }
43*09537850SAkhilesh Sanikop
44*09537850SAkhilesh Sanikop private:
45*09537850SAkhilesh Sanikop int* value_;
46*09537850SAkhilesh Sanikop };
47*09537850SAkhilesh Sanikop
TEST(UnboundedQueueTest,Basic)48*09537850SAkhilesh Sanikop TEST(UnboundedQueueTest, Basic) {
49*09537850SAkhilesh Sanikop UnboundedQueue<int> queue;
50*09537850SAkhilesh Sanikop ASSERT_TRUE(queue.Init());
51*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.Empty());
52*09537850SAkhilesh Sanikop
53*09537850SAkhilesh Sanikop for (int i = 0; i < 8; ++i) {
54*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.GrowIfNeeded());
55*09537850SAkhilesh Sanikop queue.Push(i);
56*09537850SAkhilesh Sanikop EXPECT_FALSE(queue.Empty());
57*09537850SAkhilesh Sanikop }
58*09537850SAkhilesh Sanikop
59*09537850SAkhilesh Sanikop for (int i = 0; i < 8; ++i) {
60*09537850SAkhilesh Sanikop EXPECT_FALSE(queue.Empty());
61*09537850SAkhilesh Sanikop EXPECT_EQ(queue.Front(), i);
62*09537850SAkhilesh Sanikop queue.Pop();
63*09537850SAkhilesh Sanikop }
64*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.Empty());
65*09537850SAkhilesh Sanikop }
66*09537850SAkhilesh Sanikop
TEST(UnboundedQueueTest,WrapAround)67*09537850SAkhilesh Sanikop TEST(UnboundedQueueTest, WrapAround) {
68*09537850SAkhilesh Sanikop UnboundedQueue<int> queue;
69*09537850SAkhilesh Sanikop ASSERT_TRUE(queue.Init());
70*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.Empty());
71*09537850SAkhilesh Sanikop
72*09537850SAkhilesh Sanikop for (int i = 0; i < 1000; ++i) {
73*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.GrowIfNeeded());
74*09537850SAkhilesh Sanikop queue.Push(i);
75*09537850SAkhilesh Sanikop EXPECT_FALSE(queue.Empty());
76*09537850SAkhilesh Sanikop EXPECT_EQ(queue.Front(), i);
77*09537850SAkhilesh Sanikop queue.Pop();
78*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.Empty());
79*09537850SAkhilesh Sanikop }
80*09537850SAkhilesh Sanikop }
81*09537850SAkhilesh Sanikop
TEST(UnboundedQueueTest,EmptyBeforeInit)82*09537850SAkhilesh Sanikop TEST(UnboundedQueueTest, EmptyBeforeInit) {
83*09537850SAkhilesh Sanikop UnboundedQueue<int> queue;
84*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.Empty());
85*09537850SAkhilesh Sanikop }
86*09537850SAkhilesh Sanikop
TEST(UnboundedQueueTest,LotsOfElements)87*09537850SAkhilesh Sanikop TEST(UnboundedQueueTest, LotsOfElements) {
88*09537850SAkhilesh Sanikop UnboundedQueue<Integer> queue;
89*09537850SAkhilesh Sanikop ASSERT_TRUE(queue.Init());
90*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.Empty());
91*09537850SAkhilesh Sanikop
92*09537850SAkhilesh Sanikop for (int i = 0; i < 10000; ++i) {
93*09537850SAkhilesh Sanikop Integer integer(i);
94*09537850SAkhilesh Sanikop EXPECT_EQ(integer.value(), i);
95*09537850SAkhilesh Sanikop EXPECT_TRUE(queue.GrowIfNeeded());
96*09537850SAkhilesh Sanikop queue.Push(std::move(integer));
97*09537850SAkhilesh Sanikop EXPECT_FALSE(queue.Empty());
98*09537850SAkhilesh Sanikop }
99*09537850SAkhilesh Sanikop
100*09537850SAkhilesh Sanikop for (int i = 0; i < 5000; ++i) {
101*09537850SAkhilesh Sanikop EXPECT_FALSE(queue.Empty());
102*09537850SAkhilesh Sanikop const Integer& integer = queue.Front();
103*09537850SAkhilesh Sanikop EXPECT_EQ(integer.value(), i);
104*09537850SAkhilesh Sanikop queue.Pop();
105*09537850SAkhilesh Sanikop }
106*09537850SAkhilesh Sanikop // Leave some elements in the queue to test destroying a nonempty queue.
107*09537850SAkhilesh Sanikop EXPECT_FALSE(queue.Empty());
108*09537850SAkhilesh Sanikop }
109*09537850SAkhilesh Sanikop
110*09537850SAkhilesh Sanikop // Copy constructor and assignment are deleted, but move constructor and
111*09537850SAkhilesh Sanikop // assignment are OK.
TEST(UnboundedQueueTest,Move)112*09537850SAkhilesh Sanikop TEST(UnboundedQueueTest, Move) {
113*09537850SAkhilesh Sanikop UnboundedQueue<int> ints1;
114*09537850SAkhilesh Sanikop ASSERT_TRUE(ints1.Init());
115*09537850SAkhilesh Sanikop EXPECT_TRUE(ints1.GrowIfNeeded());
116*09537850SAkhilesh Sanikop ints1.Push(2);
117*09537850SAkhilesh Sanikop EXPECT_TRUE(ints1.GrowIfNeeded());
118*09537850SAkhilesh Sanikop ints1.Push(3);
119*09537850SAkhilesh Sanikop EXPECT_TRUE(ints1.GrowIfNeeded());
120*09537850SAkhilesh Sanikop ints1.Push(5);
121*09537850SAkhilesh Sanikop EXPECT_TRUE(ints1.GrowIfNeeded());
122*09537850SAkhilesh Sanikop ints1.Push(7);
123*09537850SAkhilesh Sanikop
124*09537850SAkhilesh Sanikop // Move constructor.
125*09537850SAkhilesh Sanikop UnboundedQueue<int> ints2(std::move(ints1));
126*09537850SAkhilesh Sanikop EXPECT_EQ(ints2.Front(), 2);
127*09537850SAkhilesh Sanikop ints2.Pop();
128*09537850SAkhilesh Sanikop EXPECT_EQ(ints2.Front(), 3);
129*09537850SAkhilesh Sanikop ints2.Pop();
130*09537850SAkhilesh Sanikop EXPECT_EQ(ints2.Front(), 5);
131*09537850SAkhilesh Sanikop ints2.Pop();
132*09537850SAkhilesh Sanikop EXPECT_EQ(ints2.Front(), 7);
133*09537850SAkhilesh Sanikop ints2.Pop();
134*09537850SAkhilesh Sanikop EXPECT_TRUE(ints2.Empty());
135*09537850SAkhilesh Sanikop
136*09537850SAkhilesh Sanikop EXPECT_TRUE(ints2.GrowIfNeeded());
137*09537850SAkhilesh Sanikop ints2.Push(11);
138*09537850SAkhilesh Sanikop EXPECT_TRUE(ints2.GrowIfNeeded());
139*09537850SAkhilesh Sanikop ints2.Push(13);
140*09537850SAkhilesh Sanikop EXPECT_TRUE(ints2.GrowIfNeeded());
141*09537850SAkhilesh Sanikop ints2.Push(17);
142*09537850SAkhilesh Sanikop EXPECT_TRUE(ints2.GrowIfNeeded());
143*09537850SAkhilesh Sanikop ints2.Push(19);
144*09537850SAkhilesh Sanikop
145*09537850SAkhilesh Sanikop // Move assignment.
146*09537850SAkhilesh Sanikop UnboundedQueue<int> ints3;
147*09537850SAkhilesh Sanikop ASSERT_TRUE(ints3.Init());
148*09537850SAkhilesh Sanikop EXPECT_TRUE(ints3.GrowIfNeeded());
149*09537850SAkhilesh Sanikop ints3.Push(23);
150*09537850SAkhilesh Sanikop ints3 = std::move(ints2);
151*09537850SAkhilesh Sanikop EXPECT_EQ(ints3.Front(), 11);
152*09537850SAkhilesh Sanikop ints3.Pop();
153*09537850SAkhilesh Sanikop EXPECT_EQ(ints3.Front(), 13);
154*09537850SAkhilesh Sanikop ints3.Pop();
155*09537850SAkhilesh Sanikop EXPECT_EQ(ints3.Front(), 17);
156*09537850SAkhilesh Sanikop ints3.Pop();
157*09537850SAkhilesh Sanikop EXPECT_EQ(ints3.Front(), 19);
158*09537850SAkhilesh Sanikop ints3.Pop();
159*09537850SAkhilesh Sanikop EXPECT_TRUE(ints3.Empty());
160*09537850SAkhilesh Sanikop }
161*09537850SAkhilesh Sanikop
162*09537850SAkhilesh Sanikop } // namespace
163*09537850SAkhilesh Sanikop } // namespace libgav1
164