1e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman/* 2e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Copyright (C) 2015 The Android Open Source Project 3e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 4e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Licensed under the Apache License, Version 2.0 (the "License"); 5e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * you may not use this file except in compliance with the License. 6e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * You may obtain a copy of the License at 7e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 8e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * http://www.apache.org/licenses/LICENSE-2.0 9e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 10e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Unless required by applicable law or agreed to in writing, software 11e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * distributed under the License is distributed on an "AS IS" BASIS, 12e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * See the License for the specific language governing permissions and 14e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * limitations under the License. 15e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 16e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 17e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 18e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#ifndef ANDROID_SERVICE_UTILS_RING_BUFFER_H 19e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#define ANDROID_SERVICE_UTILS_RING_BUFFER_H 20e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 21e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <utils/Log.h> 22e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <cutils/compiler.h> 23e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 24e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <iterator> 25e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <utility> 26e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <vector> 27e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 28e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramannamespace android { 29e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 30e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman/** 31e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * A RingBuffer class that maintains an array of objects that can grow up to a certain size. 32e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Elements added to the RingBuffer are inserted in the logical front of the buffer, and 33e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * invalidate all current iterators for that RingBuffer object. 34e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 35e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 36e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass RingBuffer final { 37e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic: 38e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 39e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 40e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Construct a RingBuffer that can grow up to the given length. 41e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 42e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman explicit RingBuffer(size_t length); 43e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 44e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 45e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Forward iterator to this class. Implements an std:forward_iterator. 46e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 47e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman class iterator : public std::iterator<std::forward_iterator_tag, T> { 48e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman public: 49e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman iterator(T* ptr, size_t size, size_t pos, size_t ctr); 50e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 51e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman iterator& operator++(); 52e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 53e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman iterator operator++(int); 54e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 55e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman bool operator==(const iterator& rhs); 56e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 57e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman bool operator!=(const iterator& rhs); 58e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 59e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman T& operator*(); 60e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 61e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman T* operator->(); 62e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 63e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman private: 64e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman T* mPtr; 65e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mSize; 66e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mPos; 67e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mCtr; 68e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman }; 69e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 70e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 71e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Constant forward iterator to this class. Implements an std:forward_iterator. 72e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 73e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman class const_iterator : public std::iterator<std::forward_iterator_tag, T> { 74e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman public: 75e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr); 76e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 77e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const_iterator& operator++(); 78e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 79e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const_iterator operator++(int); 80e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 81e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman bool operator==(const const_iterator& rhs); 82e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 83e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman bool operator!=(const const_iterator& rhs); 84e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 85e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const T& operator*(); 86e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 87e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const T* operator->(); 88e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 89e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman private: 90e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const T* mPtr; 91e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mSize; 92e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mPos; 93e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mCtr; 94e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman }; 95e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 96e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 97e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Adds item to the front of this RingBuffer. If the RingBuffer is at its maximum length, 98e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * this will result in the last element being replaced (this is done using the element's 99e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * assignment operator). 100e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 101e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * All current iterators are invalidated. 102e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 103e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman void add(const T& item); 104e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 105e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 106e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Moves item to the front of this RingBuffer. Following a call to this, item should no 107e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * longer be used. If the RingBuffer is at its maximum length, this will result in the 108e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * last element being replaced (this is done using the element's assignment operator). 109e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 110e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * All current iterators are invalidated. 111e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 112e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman void add(T&& item); 113e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 114e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 115e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Construct item in-place in the front of this RingBuffer using the given arguments. If 116e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * the RingBuffer is at its maximum length, this will result in the last element being 117e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * replaced (this is done using the element's assignment operator). 118e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * 119e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * All current iterators are invalidated. 120e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 121e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman template <class... Args> 122e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman void emplace(Args&&... args); 123e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 124e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 125e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Get an iterator to the front of this RingBuffer. 126e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 127e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman iterator begin(); 128e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 129e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 130e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Get an iterator to the end of this RingBuffer. 131e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 132e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman iterator end(); 133e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 134e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 135e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Get a const_iterator to the front of this RingBuffer. 136e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 137e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const_iterator begin() const; 138e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 139e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 140e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Get a const_iterator to the end of this RingBuffer. 141e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 142e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const_iterator end() const; 143e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 144e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 145e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Return a reference to the element at a given index. If the index is out of range for 146e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * this ringbuffer, [0, size), the behavior for this is undefined. 147e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 148e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman T& operator[](size_t index); 149e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 150e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 151e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Return a const reference to the element at a given index. If the index is out of range 152e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * for this ringbuffer, [0, size), the behavior for this is undefined. 153e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 154e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const T& operator[](size_t index) const; 155e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 156e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 157e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Return the current size of this RingBuffer. 158e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 159e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t size() const; 160e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 161e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman /** 162e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Remove all elements from this RingBuffer and set the size to 0. 163e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */ 164e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman void clear(); 165e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 166e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprivate: 167e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mFrontIdx; 168e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t mMaxBufferSize; 169e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman std::vector<T> mBuffer; 170e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}; // class RingBuffer 171e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 172e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 173e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 174e2b43843fd12783188edd2c54188ea8d26864788Vijay VenkatramanRingBuffer<T>::RingBuffer(size_t length) : mFrontIdx{0}, mMaxBufferSize{length} {} 175e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 176e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 177e2b43843fd12783188edd2c54188ea8d26864788Vijay VenkatramanRingBuffer<T>::iterator::iterator(T* ptr, size_t size, size_t pos, size_t ctr) : 178e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {} 179e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 180e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 181e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypename RingBuffer<T>::iterator& RingBuffer<T>::iterator::operator++() { 182e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman ++mCtr; 183e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 184e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman if (CC_UNLIKELY(mCtr == mSize)) { 185e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mPos = mSize; 186e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return *this; 187e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman } 188e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 189e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1); 190e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return *this; 191e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 192e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 193e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 194e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypename RingBuffer<T>::iterator RingBuffer<T>::iterator::operator++(int) { 195e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman iterator tmp{mPtr, mSize, mPos, mCtr}; 196e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman ++(*this); 197e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return tmp; 198e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 199e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 200e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 201e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanbool RingBuffer<T>::iterator::operator==(const iterator& rhs) { 202e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return (mPtr + mPos) == (rhs.mPtr + rhs.mPos); 203e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 204e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 205e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 206e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanbool RingBuffer<T>::iterator::operator!=(const iterator& rhs) { 207e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return (mPtr + mPos) != (rhs.mPtr + rhs.mPos); 208e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 209e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 210e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 211e2b43843fd12783188edd2c54188ea8d26864788Vijay VenkatramanT& RingBuffer<T>::iterator::operator*() { 212e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return *(mPtr + mPos); 213e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 214e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 215e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 216e2b43843fd12783188edd2c54188ea8d26864788Vijay VenkatramanT* RingBuffer<T>::iterator::operator->() { 217e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return mPtr + mPos; 218e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 219e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 220e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 221e2b43843fd12783188edd2c54188ea8d26864788Vijay VenkatramanRingBuffer<T>::const_iterator::const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr) : 222e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {} 223e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 224e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 225e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypename RingBuffer<T>::const_iterator& RingBuffer<T>::const_iterator::operator++() { 226e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman ++mCtr; 227e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 228e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman if (CC_UNLIKELY(mCtr == mSize)) { 229e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mPos = mSize; 230e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return *this; 231e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman } 232e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 233e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1); 234e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return *this; 235e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 236e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 237e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 238e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypename RingBuffer<T>::const_iterator RingBuffer<T>::const_iterator::operator++(int) { 239e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman const_iterator tmp{mPtr, mSize, mPos, mCtr}; 240e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman ++(*this); 241e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return tmp; 242e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 243e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 244e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 245e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanbool RingBuffer<T>::const_iterator::operator==(const const_iterator& rhs) { 246e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return (mPtr + mPos) == (rhs.mPtr + rhs.mPos); 247e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 248e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 249e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 250e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanbool RingBuffer<T>::const_iterator::operator!=(const const_iterator& rhs) { 251e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return (mPtr + mPos) != (rhs.mPtr + rhs.mPos); 252e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 253e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 254e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 255e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanconst T& RingBuffer<T>::const_iterator::operator*() { 256e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return *(mPtr + mPos); 257e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 258e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 259e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 260e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanconst T* RingBuffer<T>::const_iterator::operator->() { 261e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return mPtr + mPos; 262e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 263e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 264e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 265e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanvoid RingBuffer<T>::add(const T& item) { 266e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman if (mBuffer.size() < mMaxBufferSize) { 267e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer.push_back(item); 268e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 269e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return; 270e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman } 271e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 272e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer[mFrontIdx] = item; 273e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 274e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 275e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 276e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 277e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanvoid RingBuffer<T>::add(T&& item) { 278e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman if (mBuffer.size() != mMaxBufferSize) { 279e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer.push_back(std::forward<T>(item)); 280e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 281e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return; 282e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman } 283e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 284e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // Only works for types with move assignment operator 285e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer[mFrontIdx] = std::forward<T>(item); 286e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 287e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 288e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 289e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 290e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class... Args> 291e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanvoid RingBuffer<T>::emplace(Args&&... args) { 292e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman if (mBuffer.size() != mMaxBufferSize) { 293e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer.emplace_back(std::forward<Args>(args)...); 294e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 295e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return; 296e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman } 297e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 298e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman // Only works for types with move assignment operator 299e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer[mFrontIdx] = T(std::forward<Args>(args)...); 300e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 301e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 302e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 303e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 304e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypename RingBuffer<T>::iterator RingBuffer<T>::begin() { 305e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1; 306e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return iterator(mBuffer.data(), mBuffer.size(), (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0); 307e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 308e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 309e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 310e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypename RingBuffer<T>::iterator RingBuffer<T>::end() { 311e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t s = mBuffer.size(); 312e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return iterator(mBuffer.data(), s, s, s); 313e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 314e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 315e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 316e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypename RingBuffer<T>::const_iterator RingBuffer<T>::begin() const { 317e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1; 318e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return const_iterator(mBuffer.data(), mBuffer.size(), 319e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0); 320e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 321e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 322e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 323e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantypename RingBuffer<T>::const_iterator RingBuffer<T>::end() const { 324e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t s = mBuffer.size(); 325e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return const_iterator(mBuffer.data(), s, s, s); 326e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 327e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 328e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 329e2b43843fd12783188edd2c54188ea8d26864788Vijay VenkatramanT& RingBuffer<T>::operator[](size_t index) { 330e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.", 331e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman index, mBuffer.size()); 332e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t pos = (index >= mFrontIdx) ? 333e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index; 334e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return mBuffer[pos]; 335e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 336e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 337e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 338e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanconst T& RingBuffer<T>::operator[](size_t index) const { 339e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.", 340e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman index, mBuffer.size()); 341e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman size_t pos = (index >= mFrontIdx) ? 342e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index; 343e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return mBuffer[pos]; 344e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 345e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 346e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 347e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramansize_t RingBuffer<T>::size() const { 348e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman return mBuffer.size(); 349e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 350e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 351e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramantemplate <class T> 352e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanvoid RingBuffer<T>::clear() { 353e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mBuffer.clear(); 354e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman mFrontIdx = 0; 355e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman} 356e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 357e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}; // namespace android 358e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 359e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#endif // ANDROID_SERVICE_UTILS_RING_BUFFER_H 360e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 361e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman 362