1*35238bceSAndroid Build Coastguard Worker #ifndef _DERINGBUFFER_HPP
2*35238bceSAndroid Build Coastguard Worker #define _DERINGBUFFER_HPP
3*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker * drawElements C++ Base Library
5*35238bceSAndroid Build Coastguard Worker * -----------------------------
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
8*35238bceSAndroid Build Coastguard Worker *
9*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
10*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
11*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
14*35238bceSAndroid Build Coastguard Worker *
15*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
16*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
17*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
19*35238bceSAndroid Build Coastguard Worker * limitations under the License.
20*35238bceSAndroid Build Coastguard Worker *
21*35238bceSAndroid Build Coastguard Worker *//*!
22*35238bceSAndroid Build Coastguard Worker * \file
23*35238bceSAndroid Build Coastguard Worker * \brief Ring buffer template.
24*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "deDefs.hpp"
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker namespace de
29*35238bceSAndroid Build Coastguard Worker {
30*35238bceSAndroid Build Coastguard Worker
31*35238bceSAndroid Build Coastguard Worker void RingBuffer_selfTest(void);
32*35238bceSAndroid Build Coastguard Worker
33*35238bceSAndroid Build Coastguard Worker /** Ring buffer template. */
34*35238bceSAndroid Build Coastguard Worker template <typename T>
35*35238bceSAndroid Build Coastguard Worker class RingBuffer
36*35238bceSAndroid Build Coastguard Worker {
37*35238bceSAndroid Build Coastguard Worker public:
38*35238bceSAndroid Build Coastguard Worker RingBuffer(int size);
39*35238bceSAndroid Build Coastguard Worker ~RingBuffer(void);
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard Worker void clear(void);
42*35238bceSAndroid Build Coastguard Worker void resize(int newSize);
43*35238bceSAndroid Build Coastguard Worker
getSize(void) const44*35238bceSAndroid Build Coastguard Worker int getSize(void) const
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker return m_size;
47*35238bceSAndroid Build Coastguard Worker }
getNumElements(void) const48*35238bceSAndroid Build Coastguard Worker int getNumElements(void) const
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker return m_numElements;
51*35238bceSAndroid Build Coastguard Worker }
getNumFree(void) const52*35238bceSAndroid Build Coastguard Worker int getNumFree(void) const
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker return m_size - m_numElements;
55*35238bceSAndroid Build Coastguard Worker }
56*35238bceSAndroid Build Coastguard Worker
57*35238bceSAndroid Build Coastguard Worker void pushFront(const T &elem);
58*35238bceSAndroid Build Coastguard Worker void pushFront(const T *elemBuf, int count);
59*35238bceSAndroid Build Coastguard Worker
60*35238bceSAndroid Build Coastguard Worker void peekBack(T *elemBuf, int count) const;
61*35238bceSAndroid Build Coastguard Worker T peekBack(int offset) const;
62*35238bceSAndroid Build Coastguard Worker
63*35238bceSAndroid Build Coastguard Worker T popBack(void);
popBack(T * elemBuf,int count)64*35238bceSAndroid Build Coastguard Worker void popBack(T *elemBuf, int count)
65*35238bceSAndroid Build Coastguard Worker {
66*35238bceSAndroid Build Coastguard Worker peekBack(elemBuf, count);
67*35238bceSAndroid Build Coastguard Worker popBack(count);
68*35238bceSAndroid Build Coastguard Worker }
69*35238bceSAndroid Build Coastguard Worker void popBack(int count);
70*35238bceSAndroid Build Coastguard Worker
71*35238bceSAndroid Build Coastguard Worker protected:
72*35238bceSAndroid Build Coastguard Worker int m_numElements;
73*35238bceSAndroid Build Coastguard Worker int m_front;
74*35238bceSAndroid Build Coastguard Worker int m_back;
75*35238bceSAndroid Build Coastguard Worker
76*35238bceSAndroid Build Coastguard Worker T *m_buffer;
77*35238bceSAndroid Build Coastguard Worker int m_size;
78*35238bceSAndroid Build Coastguard Worker };
79*35238bceSAndroid Build Coastguard Worker
80*35238bceSAndroid Build Coastguard Worker // RingBuffer implementation.
81*35238bceSAndroid Build Coastguard Worker
82*35238bceSAndroid Build Coastguard Worker template <typename T>
RingBuffer(int size)83*35238bceSAndroid Build Coastguard Worker RingBuffer<T>::RingBuffer(int size) : m_numElements(0)
84*35238bceSAndroid Build Coastguard Worker , m_front(0)
85*35238bceSAndroid Build Coastguard Worker , m_back(0)
86*35238bceSAndroid Build Coastguard Worker , m_size(size)
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker DE_ASSERT(size > 0);
89*35238bceSAndroid Build Coastguard Worker m_buffer = new T[m_size];
90*35238bceSAndroid Build Coastguard Worker }
91*35238bceSAndroid Build Coastguard Worker
92*35238bceSAndroid Build Coastguard Worker template <typename T>
~RingBuffer()93*35238bceSAndroid Build Coastguard Worker RingBuffer<T>::~RingBuffer()
94*35238bceSAndroid Build Coastguard Worker {
95*35238bceSAndroid Build Coastguard Worker delete[] m_buffer;
96*35238bceSAndroid Build Coastguard Worker }
97*35238bceSAndroid Build Coastguard Worker
98*35238bceSAndroid Build Coastguard Worker template <typename T>
clear(void)99*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::clear(void)
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker m_numElements = 0;
102*35238bceSAndroid Build Coastguard Worker m_front = 0;
103*35238bceSAndroid Build Coastguard Worker m_back = 0;
104*35238bceSAndroid Build Coastguard Worker }
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker template <typename T>
resize(int newSize)107*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::resize(int newSize)
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker DE_ASSERT(newSize >= m_numElements);
110*35238bceSAndroid Build Coastguard Worker T *buf = new T[newSize];
111*35238bceSAndroid Build Coastguard Worker
112*35238bceSAndroid Build Coastguard Worker try
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker // Copy old elements.
115*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_numElements; ndx++)
116*35238bceSAndroid Build Coastguard Worker buf[ndx] = m_buffer[(m_back + ndx) % m_size];
117*35238bceSAndroid Build Coastguard Worker
118*35238bceSAndroid Build Coastguard Worker // Reset pointers.
119*35238bceSAndroid Build Coastguard Worker m_front = m_numElements;
120*35238bceSAndroid Build Coastguard Worker m_back = 0;
121*35238bceSAndroid Build Coastguard Worker m_size = newSize;
122*35238bceSAndroid Build Coastguard Worker
123*35238bceSAndroid Build Coastguard Worker DE_SWAP(T *, buf, m_buffer);
124*35238bceSAndroid Build Coastguard Worker delete[] buf;
125*35238bceSAndroid Build Coastguard Worker }
126*35238bceSAndroid Build Coastguard Worker catch (...)
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker delete[] buf;
129*35238bceSAndroid Build Coastguard Worker throw;
130*35238bceSAndroid Build Coastguard Worker }
131*35238bceSAndroid Build Coastguard Worker }
132*35238bceSAndroid Build Coastguard Worker
133*35238bceSAndroid Build Coastguard Worker template <typename T>
pushFront(const T & elem)134*35238bceSAndroid Build Coastguard Worker inline void RingBuffer<T>::pushFront(const T &elem)
135*35238bceSAndroid Build Coastguard Worker {
136*35238bceSAndroid Build Coastguard Worker DE_ASSERT(getNumFree() > 0);
137*35238bceSAndroid Build Coastguard Worker m_buffer[m_front] = elem;
138*35238bceSAndroid Build Coastguard Worker m_front = (m_front + 1) % m_size;
139*35238bceSAndroid Build Coastguard Worker m_numElements += 1;
140*35238bceSAndroid Build Coastguard Worker }
141*35238bceSAndroid Build Coastguard Worker
142*35238bceSAndroid Build Coastguard Worker template <typename T>
pushFront(const T * elemBuf,int count)143*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::pushFront(const T *elemBuf, int count)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(count, 0, getNumFree()));
146*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < count; i++)
147*35238bceSAndroid Build Coastguard Worker m_buffer[(m_front + i) % m_size] = elemBuf[i];
148*35238bceSAndroid Build Coastguard Worker m_front = (m_front + count) % m_size;
149*35238bceSAndroid Build Coastguard Worker m_numElements += count;
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker
152*35238bceSAndroid Build Coastguard Worker template <typename T>
popBack()153*35238bceSAndroid Build Coastguard Worker inline T RingBuffer<T>::popBack()
154*35238bceSAndroid Build Coastguard Worker {
155*35238bceSAndroid Build Coastguard Worker DE_ASSERT(getNumElements() > 0);
156*35238bceSAndroid Build Coastguard Worker int ndx = m_back;
157*35238bceSAndroid Build Coastguard Worker m_back = (m_back + 1) % m_size;
158*35238bceSAndroid Build Coastguard Worker m_numElements -= 1;
159*35238bceSAndroid Build Coastguard Worker return m_buffer[ndx];
160*35238bceSAndroid Build Coastguard Worker }
161*35238bceSAndroid Build Coastguard Worker
162*35238bceSAndroid Build Coastguard Worker template <typename T>
peekBack(int offset) const163*35238bceSAndroid Build Coastguard Worker inline T RingBuffer<T>::peekBack(int offset) const
164*35238bceSAndroid Build Coastguard Worker {
165*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds(offset, 0, getNumElements()));
166*35238bceSAndroid Build Coastguard Worker return m_buffer[(m_back + offset) % m_size];
167*35238bceSAndroid Build Coastguard Worker }
168*35238bceSAndroid Build Coastguard Worker
169*35238bceSAndroid Build Coastguard Worker template <typename T>
peekBack(T * elemBuf,int count) const170*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::peekBack(T *elemBuf, int count) const
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(count, 0, getNumElements()));
173*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < count; i++)
174*35238bceSAndroid Build Coastguard Worker elemBuf[i] = m_buffer[(m_back + i) % m_size];
175*35238bceSAndroid Build Coastguard Worker }
176*35238bceSAndroid Build Coastguard Worker
177*35238bceSAndroid Build Coastguard Worker template <typename T>
popBack(int count)178*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::popBack(int count)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(count, 0, getNumElements()));
181*35238bceSAndroid Build Coastguard Worker m_back = (m_back + count) % m_size;
182*35238bceSAndroid Build Coastguard Worker m_numElements -= count;
183*35238bceSAndroid Build Coastguard Worker }
184*35238bceSAndroid Build Coastguard Worker
185*35238bceSAndroid Build Coastguard Worker } // namespace de
186*35238bceSAndroid Build Coastguard Worker
187*35238bceSAndroid Build Coastguard Worker #endif // _DERINGBUFFER_HPP
188