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