00001 /* +---------------------------------------------------------------------------+ 00002 | The Mobile Robot Programming Toolkit (MRPT) C++ library | 00003 | | 00004 | http://mrpt.sourceforge.net/ | 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 */ 00042 template <typename T> 00043 class circular_buffer 00044 { 00045 private: 00046 std::vector<T> m_data; 00047 const size_t m_size; 00048 size_t m_next_read,m_next_write; 00049 00050 public: 00051 circular_buffer(const size_t size) : 00052 m_data(size), 00053 m_size(size), 00054 m_next_read(0), 00055 m_next_write(0) 00056 { 00057 if (m_size<=2) throw std::invalid_argument("size must be >2"); 00058 } 00059 //virtual ~circular_buffer() { } 00060 00061 /** Insert a copy of the given element in the buffer. 00062 * \exception std::out_of_range If the buffer run out of space. 00063 */ 00064 void push(T d) { 00065 m_data[m_next_write++]=d; 00066 if (m_next_write==m_size) m_next_write=0; 00067 00068 if (m_next_write==m_next_read) 00069 throw std::out_of_range("push: circular_buffer is full"); 00070 } 00071 00072 /** Insert a reference of the given element in the buffer. 00073 * \exception std::out_of_range If the buffer run out of space. 00074 */ 00075 void push_ref(const T &d) { 00076 m_data[m_next_write++]=d; 00077 if (m_next_write==m_size) m_next_write=0; 00078 00079 if (m_next_write==m_next_read) 00080 throw std::out_of_range("push: circular_buffer is full"); 00081 } 00082 00083 /** Insert an array of elements in the buffer. 00084 * \exception std::out_of_range If the buffer run out of space. 00085 */ 00086 void push_many(T *array_elements, size_t count) { 00087 while (count--) 00088 push(*array_elements++); 00089 } 00090 00091 /** Retrieve an element from the buffer. 00092 * \exception std::out_of_range If the buffer is empty. 00093 */ 00094 T pop() { 00095 if (m_next_read==m_next_write) 00096 throw std::out_of_range("pop: circular_buffer is empty"); 00097 00098 const size_t i = m_next_read++; 00099 if (m_next_read==m_size) m_next_read=0; 00100 return m_data[i]; 00101 } 00102 00103 /** Retrieve an element from the buffer. 00104 * \exception std::out_of_range If the buffer is empty. 00105 */ 00106 void pop(T &out_val) { 00107 if (m_next_read==m_next_write) 00108 throw std::out_of_range("pop: circular_buffer is empty"); 00109 00110 out_val=m_data[m_next_read++]; 00111 if (m_next_read==m_size) m_next_read=0; 00112 } 00113 00114 /** Pop a number of elements into a user-provided array. 00115 * \exception std::out_of_range If the buffer has less elements than requested. 00116 */ 00117 void pop_many(T *out_array, size_t count) { 00118 while (count--) 00119 pop(*out_array++); 00120 } 00121 00122 /** Return the number of elements available for read ("pop") in the buffer (this is NOT the maximum size of the internal buffer) 00123 * \sa capacity 00124 */ 00125 size_t size() const { 00126 if (m_next_write>=m_next_read) 00127 return m_next_write-m_next_read; 00128 else return m_next_write + (m_size-m_next_read); 00129 } 00130 00131 /** Return the maximum capacity of the buffer. 00132 * \sa size 00133 */ 00134 size_t capacity() const { 00135 return m_size; 00136 } 00137 00138 /** The maximum number of elements that can be written ("push") without rising an overflow error. 00139 */ 00140 size_t available() const { 00141 return (capacity()-size())-1; 00142 } 00143 00144 /** Delete all the stored data, if any. */ 00145 void clear() { 00146 m_next_write = m_next_read = 0; 00147 } 00148 00149 }; // end class circular_buffer 00150 00151 } // End of namespace 00152 } // End of namespace 00153 #endif
Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:16:28 UTC 2011 |