13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef _DERINGBUFFER_HPP
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define _DERINGBUFFER_HPP
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements C++ Base Library
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -----------------------------
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Ring buffer template.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deDefs.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace de
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RingBuffer_selfTest (void);
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/** Ring buffer template. */
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RingBuffer
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RingBuffer		(int size);
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			~RingBuffer		(void);
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	clear			(void);
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	resize			(int newSize);
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		getSize			(void) const	{ return m_size;					}
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		getNumElements	(void) const	{ return m_numElements;				}
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		getNumFree		(void) const	{ return m_size - m_numElements;	}
473fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	pushFront		(const T& elem);
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	pushFront		(const T* elemBuf, int count);
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	peekBack		(T* elemBuf, int count) const;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	T		peekBack		(int offset) const;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	T		popBack			(void);
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	popBack			(T* elemBuf, int count) { peekBack(elemBuf, count); popBack(count); }
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	popBack			(int count);
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		m_numElements;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		m_front;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		m_back;
623fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	T*		m_buffer;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		m_size;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// RingBuffer implementation.
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRingBuffer<T>::RingBuffer (int size)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numElements	(0)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_front		(0)
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_back		(0)
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size		(size)
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(size > 0);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_buffer = new T[m_size];
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRingBuffer<T>::~RingBuffer ()
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete[] m_buffer;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RingBuffer<T>::clear (void)
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numElements	= 0;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_front			= 0;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_back			= 0;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RingBuffer<T>::resize (int newSize)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(newSize >= m_numElements);
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	T* buf = new T[newSize];
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Copy old elements.
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < m_numElements; ndx++)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buf[ndx] = m_buffer[(m_back + ndx) % m_size];
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Reset pointers.
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_front		= m_numElements;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_back		= 0;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_size		= newSize;
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_SWAP(T*, buf, m_buffer);
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete[] buf;
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete[] buf;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void RingBuffer<T>::pushFront (const T& elem)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(getNumFree() > 0);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_buffer[m_front] = elem;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_front = (m_front + 1) % m_size;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numElements += 1;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RingBuffer<T>::pushFront (const T* elemBuf, int count)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inRange(count, 0, getNumFree()));
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < count; i++)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffer[(m_front + i) % m_size] = elemBuf[i];
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_front = (m_front + count) % m_size;
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numElements += count;
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline T RingBuffer<T>::popBack ()
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(getNumElements() > 0);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int ndx = m_back;
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_back = (m_back + 1) % m_size;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numElements -= 1;
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_buffer[ndx];
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline T RingBuffer<T>::peekBack (int offset) const
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(offset, 0, getNumElements()));
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_buffer[(m_back + offset) % m_size];
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RingBuffer<T>::peekBack (T* elemBuf, int count) const
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inRange(count, 0, getNumElements()));
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < count; i++)
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		elemBuf[i] = m_buffer[(m_back + i) % m_size];
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RingBuffer<T>::popBack (int count)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inRange(count, 0, getNumElements()));
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_back = (m_back + count) % m_size;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numElements -= count;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // de
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _DERINGBUFFER_HPP
176