AP_Buffer.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /// @file AP_Buffer.h
  2. /// @brief fifo (queue) buffer template class
  3. #pragma once
  4. #include <stdint.h>
  5. /// @class AP_Buffer
  6. template <class T, uint8_t SIZE>
  7. class AP_Buffer {
  8. public:
  9. /// Constructor
  10. ///
  11. AP_Buffer();
  12. /// clear - removes all elements from the queue
  13. ///
  14. void clear();
  15. /// push_back - adds an item to the end of the buffer.
  16. /// If the buffer is full, the oldest element (i.e. the element at the begin) is removed
  17. /// @param item
  18. void push_back( const T &item );
  19. /// pop_front - removes an element from the beginning of the
  20. /// buffer (i.e. the oldest element) and returns it in ret.
  21. /// @param ret : the removed element, if exists
  22. /// @return : true if successful, false if not
  23. bool pop_front(T &ret);
  24. /// peek - returns a reference to an element of the buffer
  25. /// if position isn't valid (i.e. >= size()) 0 is returned
  26. /// @param position : index of the element
  27. /// "0" is the oldest, size()-1 is the newest
  28. /// @return
  29. const T& peek(uint8_t position) const;
  30. T& peek_mutable(uint8_t position);
  31. /// front - return a reference to the element at the begin of the queue (i.e. the oldest element)
  32. /// If the queue is empty, 0 is returned.
  33. /// @return : oldest element
  34. const T& front() const { return this->peek(0); }
  35. /// size - returns the number of elements in the queue
  36. /// @return
  37. uint8_t size() const { return _num_items; }
  38. /// is_full - return true if the queue is full (i.e. size() == SIZE)
  39. /// @return
  40. bool is_full() const { return _num_items >= SIZE; }
  41. /// is_empty - returns true if the queue is empty
  42. /// @return
  43. bool is_empty() const { return _num_items == 0; }
  44. private:
  45. uint8_t _num_items; // number of items in the buffer
  46. uint8_t _head; // first item in the buffer (will be returned with the next pop_front call)
  47. T _buff[SIZE]; // x values of each point on the curve
  48. };
  49. // Typedef for convenience - add more as needed
  50. typedef AP_Buffer<float,5> AP_BufferFloat_Size5;
  51. typedef AP_Buffer<float,15> AP_BufferFloat_Size15;
  52. template <class T, uint8_t SIZE>
  53. AP_Buffer<T,SIZE>::AP_Buffer() :
  54. _num_items(0), _head(0)
  55. {
  56. }
  57. template <class T, uint8_t SIZE>
  58. void AP_Buffer<T,SIZE>::clear() {
  59. // clear the curve
  60. _num_items = 0;
  61. _head = 0;
  62. }
  63. template <class T, uint8_t SIZE>
  64. void AP_Buffer<T,SIZE>::push_back( const T &item )
  65. {
  66. // determine position of new item
  67. uint8_t tail = _head + _num_items;
  68. if( tail >= SIZE ) {
  69. tail -= SIZE;
  70. }
  71. // add item to buffer
  72. _buff[tail] = item;
  73. // increment number of items
  74. if( _num_items < SIZE ) {
  75. _num_items++;
  76. }else{
  77. // no room for new items so drop oldest item
  78. _head++;
  79. if( _head >= SIZE ) {
  80. _head = 0;
  81. }
  82. }
  83. }
  84. template <class T, uint8_t SIZE>
  85. bool AP_Buffer<T,SIZE>::pop_front(T &ret)
  86. {
  87. if(_num_items == 0) {
  88. // buffer is empty
  89. return false;
  90. }
  91. // get next value in buffer
  92. ret = _buff[_head];
  93. // increment to next point
  94. _head++;
  95. if( _head >= SIZE )
  96. _head = 0;
  97. // reduce number of items
  98. _num_items--;
  99. // success
  100. return true;
  101. }
  102. template <class T, uint8_t SIZE>
  103. const T& AP_Buffer<T,SIZE>::peek(uint8_t position) const
  104. {
  105. uint8_t j = _head + position;
  106. // wrap around if necessary
  107. if( j >= SIZE )
  108. j -= SIZE;
  109. // return desired value
  110. return _buff[j];
  111. }
  112. template <class T, uint8_t SIZE>
  113. T& AP_Buffer<T,SIZE>::peek_mutable(uint8_t position)
  114. {
  115. uint8_t j = _head + position;
  116. // wrap around if necessary
  117. if( j >= SIZE )
  118. j -= SIZE;
  119. // return desired value
  120. return _buff[j];
  121. }