/// @file AP_Buffer.h /// @brief fifo (queue) buffer template class #pragma once #include /// @class AP_Buffer template class AP_Buffer { public: /// Constructor /// AP_Buffer(); /// clear - removes all elements from the queue /// void clear(); /// push_back - adds an item to the end of the buffer. /// If the buffer is full, the oldest element (i.e. the element at the begin) is removed /// @param item void push_back( const T &item ); /// pop_front - removes an element from the beginning of the /// buffer (i.e. the oldest element) and returns it in ret. /// @param ret : the removed element, if exists /// @return : true if successful, false if not bool pop_front(T &ret); /// peek - returns a reference to an element of the buffer /// if position isn't valid (i.e. >= size()) 0 is returned /// @param position : index of the element /// "0" is the oldest, size()-1 is the newest /// @return const T& peek(uint8_t position) const; T& peek_mutable(uint8_t position); /// front - return a reference to the element at the begin of the queue (i.e. the oldest element) /// If the queue is empty, 0 is returned. /// @return : oldest element const T& front() const { return this->peek(0); } /// size - returns the number of elements in the queue /// @return uint8_t size() const { return _num_items; } /// is_full - return true if the queue is full (i.e. size() == SIZE) /// @return bool is_full() const { return _num_items >= SIZE; } /// is_empty - returns true if the queue is empty /// @return bool is_empty() const { return _num_items == 0; } private: uint8_t _num_items; // number of items in the buffer uint8_t _head; // first item in the buffer (will be returned with the next pop_front call) T _buff[SIZE]; // x values of each point on the curve }; // Typedef for convenience - add more as needed typedef AP_Buffer AP_BufferFloat_Size5; typedef AP_Buffer AP_BufferFloat_Size15; template AP_Buffer::AP_Buffer() : _num_items(0), _head(0) { } template void AP_Buffer::clear() { // clear the curve _num_items = 0; _head = 0; } template void AP_Buffer::push_back( const T &item ) { // determine position of new item uint8_t tail = _head + _num_items; if( tail >= SIZE ) { tail -= SIZE; } // add item to buffer _buff[tail] = item; // increment number of items if( _num_items < SIZE ) { _num_items++; }else{ // no room for new items so drop oldest item _head++; if( _head >= SIZE ) { _head = 0; } } } template bool AP_Buffer::pop_front(T &ret) { if(_num_items == 0) { // buffer is empty return false; } // get next value in buffer ret = _buff[_head]; // increment to next point _head++; if( _head >= SIZE ) _head = 0; // reduce number of items _num_items--; // success return true; } template const T& AP_Buffer::peek(uint8_t position) const { uint8_t j = _head + position; // wrap around if necessary if( j >= SIZE ) j -= SIZE; // return desired value return _buff[j]; } template T& AP_Buffer::peek_mutable(uint8_t position) { uint8_t j = _head + position; // wrap around if necessary if( j >= SIZE ) j -= SIZE; // return desired value return _buff[j]; }