00001 /* +---------------------------------------------------------------------------+ 00002 | The Mobile Robot Programming Toolkit (MRPT) C++ library | 00003 | | 00004 | http://www.mrpt.org/ | 00005 | | 00006 | Copyright (C) 2005-2011 University of Malaga | 00007 | | 00008 | This software was written by the Machine Perception and Intelligent | 00009 | Robotics Lab, University of Malaga (Spain). | 00010 | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> | 00011 | | 00012 | This file is part of the MRPT project. | 00013 | | 00014 | MRPT is free software: you can redistribute it and/or modify | 00015 | it under the terms of the GNU General Public License as published by | 00016 | the Free Software Foundation, either version 3 of the License, or | 00017 | (at your option) any later version. | 00018 | | 00019 | MRPT is distributed in the hope that it will be useful, | 00020 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00021 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 00022 | GNU General Public License for more details. | 00023 | | 00024 | You should have received a copy of the GNU General Public License | 00025 | along with MRPT. If not, see <http://www.gnu.org/licenses/>. | 00026 | | 00027 +---------------------------------------------------------------------------+ */ 00028 #ifndef circular_buffer_H 00029 #define circular_buffer_H 00030 00031 // Note: This file is included from "stl_extensions.h" 00032 00033 #include <mrpt/utils/utils_defs.h> 00034 #include <vector> 00035 00036 namespace mrpt 00037 { 00038 namespace utils 00039 { 00040 /** A circular buffer of fixed size (defined at construction-time), implemented with a std::vector as the underlying storage. 00041 * \ingroup stlext_grp 00042 */ 00043 template <typename T> 00044 class circular_buffer 00045 { 00046 private: 00047 std::vector<T> m_data; 00048 const size_t m_size; 00049 size_t m_next_read,m_next_write; 00050 00051 public: 00052 circular_buffer(const size_t size) : 00053 m_data(size), 00054 m_size(size), 00055 m_next_read(0), 00056 m_next_write(0) 00057 { 00058 if (m_size<=2) throw std::invalid_argument("size must be >2"); 00059 } 00060 //virtual ~circular_buffer() { } 00061 00062 /** Insert a copy of the given element in the buffer. 00063 * \exception std::out_of_range If the buffer run out of space. 00064 */ 00065 void push(T d) { 00066 m_data[m_next_write++]=d; 00067 if (m_next_write==m_size) m_next_write=0; 00068 00069 if (m_next_write==m_next_read) 00070 throw std::out_of_range("push: circular_buffer is full"); 00071 } 00072 00073 /** Insert a reference of the given element in the buffer. 00074 * \exception std::out_of_range If the buffer run out of space. 00075 */ 00076 void push_ref(const T &d) { 00077 m_data[m_next_write++]=d; 00078 if (m_next_write==m_size) m_next_write=0; 00079 00080 if (m_next_write==m_next_read) 00081 throw std::out_of_range("push: circular_buffer is full"); 00082 } 00083 00084 /** Insert an array of elements in the buffer. 00085 * \exception std::out_of_range If the buffer run out of space. 00086 */ 00087 void push_many(T *array_elements, size_t count) { 00088 while (count--) 00089 push(*array_elements++); 00090 } 00091 00092 /** Retrieve an element from the buffer. 00093 * \exception std::out_of_range If the buffer is empty. 00094 */ 00095 T pop() { 00096 if (m_next_read==m_next_write) 00097 throw std::out_of_range("pop: circular_buffer is empty"); 00098 00099 const size_t i = m_next_read++; 00100 if (m_next_read==m_size) m_next_read=0; 00101 return m_data[i]; 00102 } 00103 00104 /** Retrieve an element from the buffer. 00105 * \exception std::out_of_range If the buffer is empty. 00106 */ 00107 void pop(T &out_val) { 00108 if (m_next_read==m_next_write) 00109 throw std::out_of_range("pop: circular_buffer is empty"); 00110 00111 out_val=m_data[m_next_read++]; 00112 if (m_next_read==m_size) m_next_read=0; 00113 } 00114 00115 /** Pop a number of elements into a user-provided array. 00116 * \exception std::out_of_range If the buffer has less elements than requested. 00117 */ 00118 void pop_many(T *out_array, size_t count) { 00119 while (count--) 00120 pop(*out_array++); 00121 } 00122 00123 /** Return the number of elements available for read ("pop") in the buffer (this is NOT the maximum size of the internal buffer) 00124 * \sa capacity 00125 */ 00126 size_t size() const { 00127 if (m_next_write>=m_next_read) 00128 return m_next_write-m_next_read; 00129 else return m_next_write + (m_size-m_next_read); 00130 } 00131 00132 /** Return the maximum capacity of the buffer. 00133 * \sa size 00134 */ 00135 size_t capacity() const { 00136 return m_size; 00137 } 00138 00139 /** The maximum number of elements that can be written ("push") without rising an overflow error. 00140 */ 00141 size_t available() const { 00142 return (capacity()-size())-1; 00143 } 00144 00145 /** Delete all the stored data, if any. */ 00146 void clear() { 00147 m_next_write = m_next_read = 0; 00148 } 00149 00150 }; // end class circular_buffer 00151 00152 } // End of namespace 00153 } // End of namespace 00154 #endif
| Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011 |