xref: /aosp_15_r20/external/libgav1/src/utils/queue.h (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1 /*
2  * Copyright 2019 The libgav1 Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LIBGAV1_SRC_UTILS_QUEUE_H_
18 #define LIBGAV1_SRC_UTILS_QUEUE_H_
19 
20 #include <cassert>
21 #include <cstddef>
22 #include <memory>
23 #include <new>
24 #include <utility>
25 
26 #include "src/utils/compiler_attributes.h"
27 
28 namespace libgav1 {
29 
30 // A FIFO queue of a fixed capacity.
31 //
32 // WARNING: No error checking is performed.
33 template <typename T>
34 class Queue {
35  public:
Init(size_t capacity)36   LIBGAV1_MUST_USE_RESULT bool Init(size_t capacity) {
37     elements_.reset(new (std::nothrow) T[capacity]);
38     if (elements_ == nullptr) return false;
39     capacity_ = capacity;
40     return true;
41   }
42 
43   // Pushes the element |value| to the end of the queue. It is an error to call
44   // Push() when the queue is full.
Push(T && value)45   void Push(T&& value) {
46     assert(size_ < capacity_);
47     elements_[end_++] = std::move(value);
48     if (end_ == capacity_) end_ = 0;
49     ++size_;
50   }
51 
52   // Removes the element at the front of the queue. It is an error to call Pop()
53   // when the queue is empty.
Pop()54   void Pop() {
55     assert(size_ != 0);
56     const T element = std::move(elements_[begin_++]);
57     static_cast<void>(element);
58     if (begin_ == capacity_) begin_ = 0;
59     --size_;
60   }
61 
62   // Returns a reference to the element at the front of the queue. It is an
63   // error to call Front() when the queue is empty.
Front()64   T& Front() {
65     assert(size_ != 0);
66     return elements_[begin_];
67   }
68 
69   // Returns a reference to the element at the back of the queue. It is an error
70   // to call Back() when the queue is empty.
Back()71   T& Back() {
72     assert(size_ != 0);
73     const size_t back = ((end_ == 0) ? capacity_ : end_) - 1;
74     return elements_[back];
75   }
76 
77   // Clears the queue.
Clear()78   void Clear() {
79     while (!Empty()) {
80       Pop();
81     }
82   }
83 
84   // Returns true if the queue is empty.
Empty()85   bool Empty() const { return size_ == 0; }
86 
87   // Returns true if the queue is full.
Full()88   bool Full() const { return size_ >= capacity_; }
89 
90   // Returns the number of elements in the queue.
Size()91   size_t Size() const { return size_; }
92 
93  private:
94   // An array of |capacity| elements. Used as a circular array.
95   std::unique_ptr<T[]> elements_;
96   size_t capacity_ = 0;
97   // The index of the element to be removed by Pop().
98   size_t begin_ = 0;
99   // The index where the new element is inserted by Push().
100   size_t end_ = 0;
101   size_t size_ = 0;
102 };
103 
104 }  // namespace libgav1
105 
106 #endif  // LIBGAV1_SRC_UTILS_QUEUE_H_
107