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