16a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu/* 26a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Copyright (C) 2015 The Android Open Source Project 36a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * 46a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Licensed under the Apache License, Version 2.0 (the "License"); 56a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * you may not use this file except in compliance with the License. 66a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * You may obtain a copy of the License at 76a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * 86a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * http://www.apache.org/licenses/LICENSE-2.0 96a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * 106a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Unless required by applicable law or agreed to in writing, software 116a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * distributed under the License is distributed on an "AS IS" BASIS, 126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * See the License for the specific language governing permissions and 146a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * limitations under the License. 156a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 166a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 176a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#ifndef ANDROID_SENSOR_SERVICE_UTIL_RING_BUFFER_H 186a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#define ANDROID_SENSOR_SERVICE_UTIL_RING_BUFFER_H 196a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include <utils/Log.h> 216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include <cutils/compiler.h> 226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include <iterator> 246a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include <utility> 256a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include <vector> 266a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 276a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xunamespace android { 286a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xunamespace SensorServiceUtil { 296a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 306a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu/** 316a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * A RingBuffer class that maintains an array of objects that can grow up to a certain size. 326a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Elements added to the RingBuffer are inserted in the logical front of the buffer, and 336a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * invalidate all current iterators for that RingBuffer object. 346a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 356a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuclass RingBuffer final { 376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xupublic: 386a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 396a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 406a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Construct a RingBuffer that can grow up to the given length. 416a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 4238fc101331d15dde716f80f2f64b4317ea1e22f1Chih-Hung Hsieh explicit RingBuffer(size_t length); 436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 456a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Forward iterator to this class. Implements an std:forward_iterator. 466a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 476a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu class iterator : public std::iterator<std::forward_iterator_tag, T> { 486a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu public: 496a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu iterator(T* ptr, size_t size, size_t pos, size_t ctr); 506a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 516a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu iterator& operator++(); 526a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 536a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu iterator operator++(int); 546a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 556a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu bool operator==(const iterator& rhs); 566a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 576a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu bool operator!=(const iterator& rhs); 586a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 596a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu T& operator*(); 606a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 616a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu T* operator->(); 626a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 636a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu private: 646a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu T* mPtr; 656a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t mSize; 666a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t mPos; 676a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t mCtr; 686a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu }; 696a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 706a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 716a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Constant forward iterator to this class. Implements an std:forward_iterator. 726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 736a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu class const_iterator : public std::iterator<std::forward_iterator_tag, T> { 746a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu public: 756a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr); 766a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 776a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const_iterator& operator++(); 786a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 796a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const_iterator operator++(int); 806a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 816a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu bool operator==(const const_iterator& rhs); 826a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 836a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu bool operator!=(const const_iterator& rhs); 846a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 856a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const T& operator*(); 866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const T* operator->(); 886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 896a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu private: 906a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const T* mPtr; 916a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t mSize; 926a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t mPos; 936a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t mCtr; 946a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu }; 956a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 966a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 976a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Adds item to the front of this RingBuffer. If the RingBuffer is at its maximum length, 986a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * this will result in the last element being replaced (this is done using the element's 996a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * assignment operator). 1006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * 1016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * All current iterators are invalidated. 1026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu void add(const T& item); 1046a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1056a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1066a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Moves item to the front of this RingBuffer. Following a call to this, item should no 1076a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * longer be used. If the RingBuffer is at its maximum length, this will result in the 1086a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * last element being replaced (this is done using the element's assignment operator). 1096a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * 1106a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * All current iterators are invalidated. 1116a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu void add(T&& item); 1136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1146a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1156a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Construct item in-place in the front of this RingBuffer using the given arguments. If 1166a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * the RingBuffer is at its maximum length, this will result in the last element being 1176a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * replaced (this is done using the element's assignment operator). 1186a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * 1196a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * All current iterators are invalidated. 1206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu template <class... Args> 1226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu void emplace(Args&&... args); 1236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1246a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1256a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Get an iterator to the front of this RingBuffer. 1266a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1276a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu iterator begin(); 1286a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1296a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1306a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Get an iterator to the end of this RingBuffer. 1316a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1326a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu iterator end(); 1336a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1346a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1356a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Get a const_iterator to the front of this RingBuffer. 1366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const_iterator begin() const; 1386a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1396a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1406a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Get a const_iterator to the end of this RingBuffer. 1416a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const_iterator end() const; 1436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1456a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Return a reference to the element at a given index. If the index is out of range for 1466a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * this ringbuffer, [0, size), the behavior for this is undefined. 1476a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1486a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu T& operator[](size_t index); 1496a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1506a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1516a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Return a const reference to the element at a given index. If the index is out of range 1526a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * for this ringbuffer, [0, size), the behavior for this is undefined. 1536a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1546a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const T& operator[](size_t index) const; 1556a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1566a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1576a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Return the current size of this RingBuffer. 1586a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1596a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t size() const; 1606a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1616a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu /** 1626a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Remove all elements from this RingBuffer and set the size to 0. 1636a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */ 1646a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu void clear(); 1656a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1666a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuprivate: 1676a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t mFrontIdx; 1686a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t mMaxBufferSize; 1696a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu std::vector<T> mBuffer; 1706a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}; // class RingBuffer 1716a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1736a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 1746a2d3a06caa337857cf60cfc70a9a78909ad3608Peng XuRingBuffer<T>::RingBuffer(size_t length) : mFrontIdx{0}, mMaxBufferSize{length} {} 1756a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1766a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 1776a2d3a06caa337857cf60cfc70a9a78909ad3608Peng XuRingBuffer<T>::iterator::iterator(T* ptr, size_t size, size_t pos, size_t ctr) : 1786a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {} 1796a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1806a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 1816a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutypename RingBuffer<T>::iterator& RingBuffer<T>::iterator::operator++() { 1826a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu ++mCtr; 1836a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1846a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (CC_UNLIKELY(mCtr == mSize)) { 1856a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mPos = mSize; 1866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return *this; 1876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 1886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1896a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1); 1906a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return *this; 1916a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 1926a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 1936a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 1946a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutypename RingBuffer<T>::iterator RingBuffer<T>::iterator::operator++(int) { 1956a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu iterator tmp{mPtr, mSize, mPos, mCtr}; 1966a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu ++(*this); 1976a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return tmp; 1986a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 1996a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool RingBuffer<T>::iterator::operator==(const iterator& rhs) { 2026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return (mPtr + mPos) == (rhs.mPtr + rhs.mPos); 2036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2046a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2056a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2066a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool RingBuffer<T>::iterator::operator!=(const iterator& rhs) { 2076a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return (mPtr + mPos) != (rhs.mPtr + rhs.mPos); 2086a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2096a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2106a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2116a2d3a06caa337857cf60cfc70a9a78909ad3608Peng XuT& RingBuffer<T>::iterator::operator*() { 2126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return *(mPtr + mPos); 2136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2146a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2156a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2166a2d3a06caa337857cf60cfc70a9a78909ad3608Peng XuT* RingBuffer<T>::iterator::operator->() { 2176a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return mPtr + mPos; 2186a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2196a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng XuRingBuffer<T>::const_iterator::const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr) : 2226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {} 2236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2246a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2256a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutypename RingBuffer<T>::const_iterator& RingBuffer<T>::const_iterator::operator++() { 2266a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu ++mCtr; 2276a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2286a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (CC_UNLIKELY(mCtr == mSize)) { 2296a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mPos = mSize; 2306a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return *this; 2316a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 2326a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2336a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1); 2346a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return *this; 2356a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2386a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutypename RingBuffer<T>::const_iterator RingBuffer<T>::const_iterator::operator++(int) { 2396a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const_iterator tmp{mPtr, mSize, mPos, mCtr}; 2406a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu ++(*this); 2416a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return tmp; 2426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2456a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool RingBuffer<T>::const_iterator::operator==(const const_iterator& rhs) { 2466a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return (mPtr + mPos) == (rhs.mPtr + rhs.mPos); 2476a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2486a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2496a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2506a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool RingBuffer<T>::const_iterator::operator!=(const const_iterator& rhs) { 2516a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return (mPtr + mPos) != (rhs.mPtr + rhs.mPos); 2526a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2536a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2546a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2556a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuconst T& RingBuffer<T>::const_iterator::operator*() { 2566a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return *(mPtr + mPos); 2576a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2586a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2596a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2606a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuconst T* RingBuffer<T>::const_iterator::operator->() { 2616a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return mPtr + mPos; 2626a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2636a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2646a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2656a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuvoid RingBuffer<T>::add(const T& item) { 2666a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (mBuffer.size() < mMaxBufferSize) { 2676a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer.push_back(item); 2686a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 2696a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return; 2706a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 2716a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer[mFrontIdx] = item; 2736a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 2746a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2756a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2766a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2776a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuvoid RingBuffer<T>::add(T&& item) { 2786a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (mBuffer.size() != mMaxBufferSize) { 2796a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer.push_back(std::forward<T>(item)); 2806a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 2816a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return; 2826a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 2836a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2846a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu // Only works for types with move assignment operator 2856a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer[mFrontIdx] = std::forward<T>(item); 2866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 2876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 2886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2896a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 2906a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class... Args> 2916a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuvoid RingBuffer<T>::emplace(Args&&... args) { 2926a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (mBuffer.size() != mMaxBufferSize) { 2936a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer.emplace_back(std::forward<Args>(args)...); 2946a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 2956a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return; 2966a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 2976a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2986a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu // Only works for types with move assignment operator 2996a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer[mFrontIdx] = T(std::forward<Args>(args)...); 3006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); 3016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 3046a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutypename RingBuffer<T>::iterator RingBuffer<T>::begin() { 3056a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1; 3066a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return iterator(mBuffer.data(), mBuffer.size(), (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0); 3076a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3086a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3096a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 3106a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutypename RingBuffer<T>::iterator RingBuffer<T>::end() { 3116a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t s = mBuffer.size(); 3126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return iterator(mBuffer.data(), s, s, s); 3136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3146a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3156a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 3166a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutypename RingBuffer<T>::const_iterator RingBuffer<T>::begin() const { 3176a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1; 3186a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return const_iterator(mBuffer.data(), mBuffer.size(), 3196a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0); 3206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 3236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutypename RingBuffer<T>::const_iterator RingBuffer<T>::end() const { 3246a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t s = mBuffer.size(); 3256a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return const_iterator(mBuffer.data(), s, s, s); 3266a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3276a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3286a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 3296a2d3a06caa337857cf60cfc70a9a78909ad3608Peng XuT& RingBuffer<T>::operator[](size_t index) { 3306a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.", 3316a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu index, mBuffer.size()); 3326a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t pos = (index >= mFrontIdx) ? 3336a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index; 3346a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return mBuffer[pos]; 3356a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 3386a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuconst T& RingBuffer<T>::operator[](size_t index) const { 3396a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.", 3406a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu index, mBuffer.size()); 3416a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu size_t pos = (index >= mFrontIdx) ? 3426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index; 3436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return mBuffer[pos]; 3446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3456a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3466a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 3476a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xusize_t RingBuffer<T>::size() const { 3486a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu return mBuffer.size(); 3496a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3506a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3516a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xutemplate <class T> 3526a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuvoid RingBuffer<T>::clear() { 3536a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mBuffer.clear(); 3546a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mFrontIdx = 0; 3556a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} 3566a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3576a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} // namespace SensorServiceUtil 3586a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}; // namespace android 3596a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3606a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#endif // ANDROID_SENSOR_SERVICE_UTIL_RING_BUFFER_H 3616a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 362