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