00001 #ifndef _CMT_MONOLITHIC 00002 /*! \file 00003 \brief Contains the FIFO queue interface and implementation (inline) 00004 00005 \section FileCopyright Copyright Notice 00006 Copyright (C) Xsens Technologies B.V., 2006. All rights reserved. 00007 00008 This source code is intended for use only by Xsens Technologies BV and 00009 those that have explicit written permission to use it from 00010 Xsens Technologies BV. 00011 00012 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 00013 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 00014 IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 00015 PARTICULAR PURPOSE. 00016 00017 \section FileChangelog Changelog 00018 00019 \par 2006-05-03, v0.0.1 00020 \li Job Mulder: Created Cmtfifoqueue.h 00021 00022 \par 2006-07-21, v0.1.0 00023 \li Job Mulder: Updated file for release 0.1.0 00024 */ 00025 #endif 00026 #ifndef _FIFOQUEUE_H_2006_05_03 00027 #define _FIFOQUEUE_H_2006_05_03 00028 00029 00030 namespace xsens { 00031 00032 ////////////////////////////////////////////////////////////////////////////////////////// 00033 00034 /*! \brief A FIFO queue with limited length (cyclic). 00035 00036 The class is based on the STL queue class, but has a limited size. If more items are 00037 inserted than would fit, the oldest item is overwritten. The class can only handle 00038 pointer types. 00039 */ 00040 template <class T, bool E=true> 00041 class FifoQueue { 00042 protected: 00043 size_t m_maxCount; 00044 size_t m_currentCount; 00045 size_t m_first; 00046 bool m_deleteOnOverwrite; 00047 00048 T* m_list; 00049 public: 00050 typedef T value_type; //!< The type of the value stored in this queue. 00051 typedef size_t size_type; //!< The type of a 'size' value. 00052 00053 //! Create an empty queue with capacity size. 00054 FifoQueue(size_type size=16, bool delOnOverwrite = true) 00055 { 00056 if (size > 0) 00057 m_maxCount = size; 00058 else 00059 m_maxCount = 1; 00060 m_list = new T[m_maxCount]; 00061 m_currentCount = 0; 00062 m_first = 0; 00063 m_deleteOnOverwrite = delOnOverwrite; 00064 } 00065 00066 //! The copy constructor. 00067 template <bool E2> 00068 FifoQueue(const FifoQueue<T,E2>& q) 00069 { 00070 m_maxCount = q.m_maxCount; 00071 m_list = new T[m_maxCount]; 00072 m_currentCount = q.m_currentCount; 00073 m_deleteOnOverwrite = q.m_deleteOnOverwrite; 00074 m_first = 0; 00075 for (size_t i = 0;i<m_currentCount;++i) 00076 m_list[i] = q.m_list[(i+q.m_first) % m_maxCount]; 00077 } 00078 00079 void eraseAndClear(void) 00080 { 00081 for (size_t i = 0;i<m_currentCount;++i) 00082 delete m_list[(i+m_first) % m_maxCount]; 00083 m_currentCount = 0; 00084 m_first = 0; 00085 } 00086 00087 //! The destructor. 00088 ~FifoQueue() 00089 { 00090 if (E) 00091 eraseAndClear(); 00092 m_maxCount = 0; 00093 delete[] m_list; 00094 } 00095 00096 //! The assignment operator. 00097 template <bool E2> 00098 FifoQueue<T,E>& operator=(const FifoQueue<T,E2>& q) 00099 { 00100 if (m_maxCount != q.m_maxCount) 00101 { 00102 delete[] m_list; 00103 m_maxCount = q.m_maxCount; 00104 m_list = new T[m_maxCount]; 00105 } 00106 m_currentCount = q.m_currentCount; 00107 m_first = 0; 00108 for (size_t i = 0;i<m_currentCount;++i) 00109 m_list[i] = q.m_list[(i+q.m_first) % m_maxCount]; 00110 00111 return *this; 00112 } 00113 00114 //! Resize the queue, note that this function clears the queue. 00115 void resize(const size_t size) 00116 { 00117 if (E) 00118 eraseAndClear(); 00119 delete[] m_list; 00120 if (size > 0) 00121 m_maxCount = size; 00122 else 00123 m_maxCount = 1; 00124 m_list = new T[m_maxCount]; 00125 m_currentCount = 0; 00126 m_first = 0; 00127 } 00128 00129 //! Return true if the queue is empty. 00130 bool empty() const 00131 { 00132 return (m_currentCount == 0); 00133 } 00134 00135 //! Return the maximum number of elements in the queue. 00136 size_type size() const 00137 { 00138 return m_maxCount; 00139 } 00140 00141 //! Return the number of elements currnetly in the queue. 00142 size_type length() const 00143 { 00144 return m_currentCount; 00145 } 00146 00147 //! Return the oldest element in the queue. 00148 value_type& front() 00149 { 00150 return m_list[m_first]; 00151 } 00152 00153 //! Return the oldest element in the queue. 00154 const value_type& front() const 00155 { 00156 return m_list[m_first]; 00157 } 00158 00159 //! Return the newest element in the queue. 00160 value_type& back() 00161 { 00162 return m_list[(m_first + m_currentCount - 1) % m_maxCount]; 00163 } 00164 00165 //! Return the newest element in the queue. 00166 const value_type& back() const 00167 { 00168 return m_list[(m_first + m_currentCount - 1) % m_maxCount]; 00169 } 00170 00171 //! Insert x at the back of the queue. 00172 void push(const value_type& x) 00173 { 00174 if (m_currentCount == m_maxCount) 00175 { 00176 if (m_deleteOnOverwrite) 00177 delete (m_list[m_first]); 00178 00179 m_list[m_first] = x; 00180 m_first = (m_first+1) % m_maxCount; 00181 } 00182 else 00183 { 00184 m_list[(m_first + m_currentCount++) % m_maxCount] = x; 00185 } 00186 } 00187 00188 //! Remove the element at the front of the queue. 00189 void pop(void) 00190 { 00191 m_first = (m_first+1) % m_maxCount; 00192 --m_currentCount; 00193 } 00194 00195 //! Remove the element at the back of the queue. 00196 void popBack(void) 00197 { 00198 --m_currentCount; 00199 } 00200 00201 //! Return the index'th oldest item from the queue 00202 const value_type& operator[] (size_t index) const 00203 { 00204 if (index >= m_currentCount) 00205 return m_list[(m_first + m_currentCount - 1) % m_maxCount]; 00206 else 00207 return m_list[(m_first + index) % m_maxCount]; 00208 } 00209 00210 //! Return the index'th oldest item from the queue 00211 value_type& operator[] (size_t index) 00212 { 00213 if (index >= m_currentCount) 00214 return m_list[(m_first + m_currentCount - 1) % m_maxCount]; 00215 else 00216 return m_list[(m_first + index) % m_maxCount]; 00217 } 00218 00219 void clear(void) 00220 { 00221 m_currentCount = 0; 00222 m_first = 0; 00223 } 00224 00225 void remove(size_t index) 00226 { 00227 if (index >= m_currentCount) 00228 return; 00229 if (index == 0) 00230 pop(); 00231 else 00232 { 00233 --m_currentCount; 00234 for (size_t i=index;i<m_currentCount;++i) 00235 m_list[(m_first + i) % m_maxCount] = m_list[(1 + m_first + i) % m_maxCount]; 00236 } 00237 } 00238 }; 00239 00240 00241 ////////////////////////////////////////////////////////////////////////////////////////// 00242 00243 /*! \brief A FIFO queue with limited length (cyclic). 00244 00245 The class is based on the STL queue class, but has a limited size. If more items are 00246 inserted than would fit, the oldest item is overwritten. The class can only handle 00247 non-pointer types. 00248 */ 00249 template <class T> 00250 class FifoQueueBasic { 00251 protected: 00252 size_t m_maxCount; 00253 size_t m_currentCount; 00254 size_t m_first; 00255 00256 T* m_list; 00257 public: 00258 typedef T value_type; //!< The type of the value stored in this queue. 00259 typedef size_t size_type; //!< The type of a 'size' value. 00260 00261 //! Create an empty queue with capacity 'size'. 00262 FifoQueueBasic(size_type size=16) 00263 { 00264 if (size > 0) 00265 m_maxCount = size; 00266 else 00267 m_maxCount = 1; 00268 m_list = new T[m_maxCount]; 00269 m_currentCount = 0; 00270 m_first = 0; 00271 } 00272 00273 //! The copy constructor. 00274 FifoQueueBasic(const FifoQueueBasic<T>& q) 00275 { 00276 m_maxCount = q.m_maxCount; 00277 m_list = new T[m_maxCount]; 00278 m_currentCount = q.m_currentCount; 00279 m_first = 0; 00280 for (size_t i = 0;i<m_currentCount;++i) 00281 m_list[i] = q.m_list[(i+q.m_first) % m_maxCount]; 00282 } 00283 00284 void eraseAndClear(void) 00285 { 00286 for (size_t i = 0;i<m_currentCount;++i) 00287 delete m_list[(i+m_first) % m_maxCount]; 00288 m_currentCount = 0; 00289 m_first = 0; 00290 } 00291 00292 //! The destructor. 00293 ~FifoQueueBasic() 00294 { 00295 m_maxCount = 0; 00296 delete[] m_list; 00297 } 00298 00299 //! The assignment operator. 00300 FifoQueueBasic<T>& operator=(const FifoQueueBasic<T>& q) 00301 { 00302 if (m_maxCount != q.m_maxCount) 00303 { 00304 delete[] m_list; 00305 m_maxCount = q.m_maxCount; 00306 m_list = new T[m_maxCount]; 00307 } 00308 m_currentCount = q.m_currentCount; 00309 m_first = 0; 00310 for (size_t i = 0;i<m_currentCount;++i) 00311 m_list[i] = q.m_list[(i+q.m_first) % m_maxCount]; 00312 00313 return *this; 00314 } 00315 00316 //! Resize the queue, note that this function clears the queue. 00317 void resize(const size_t size) 00318 { 00319 delete[] m_list; 00320 if (size > 0) 00321 m_maxCount = size; 00322 else 00323 m_maxCount = 1; 00324 m_list = new T[m_maxCount]; 00325 m_currentCount = 0; 00326 m_first = 0; 00327 } 00328 00329 //! Return true if the queue is empty. 00330 bool empty() const 00331 { 00332 return (m_currentCount == 0); 00333 } 00334 00335 //! Return the maximum number of elements in the queue. 00336 size_type size() const 00337 { 00338 return m_maxCount; 00339 } 00340 00341 //! Return the number of elements currently in the queue. 00342 size_type length() const 00343 { 00344 return m_currentCount; 00345 } 00346 00347 //! Return the oldest element in the queue. 00348 value_type& front() 00349 { 00350 return m_list[m_first]; 00351 } 00352 00353 //! Return the oldest element in the queue. 00354 const value_type& front() const 00355 { 00356 return m_list[m_first]; 00357 } 00358 00359 //! Return the newest element in the queue. 00360 value_type& back() 00361 { 00362 return m_list[(m_first + m_currentCount - 1) % m_maxCount]; 00363 } 00364 00365 //! Return the newest element in the queue. 00366 const value_type& back() const 00367 { 00368 return m_list[(m_first + m_currentCount - 1) % m_maxCount]; 00369 } 00370 00371 //! Insert x at the back of the queue. 00372 void push(const value_type& x) 00373 { 00374 if (m_currentCount == m_maxCount) 00375 { 00376 m_list[m_first] = x; 00377 m_first = (m_first+1) % m_maxCount; 00378 } 00379 else 00380 { 00381 m_list[(m_first + m_currentCount++) % m_maxCount] = x; 00382 } 00383 } 00384 00385 //! Insert x at the front of the queue (LIFO operation). 00386 void push_front(const value_type& x) 00387 { 00388 m_first = (m_first+m_maxCount-1)%m_maxCount; 00389 if (m_currentCount == 0) 00390 m_first = 0; 00391 m_list[m_first] = x; 00392 if (m_currentCount < m_maxCount) 00393 ++m_currentCount; 00394 } 00395 00396 //! Remove the element at the front of the queue. 00397 void pop(void) 00398 { 00399 if (m_currentCount > 0) 00400 { 00401 m_first = (m_first+1) % m_maxCount; 00402 --m_currentCount; 00403 } 00404 } 00405 00406 //! Remove the element at the back of the queue. 00407 void popBack(void) 00408 { 00409 if (m_currentCount > 0) 00410 --m_currentCount; 00411 } 00412 00413 //! Return the index'th oldest item from the queue 00414 const value_type& operator[] (size_t index) const 00415 { 00416 if (index >= m_currentCount) 00417 return m_list[(m_first + m_currentCount - 1) % m_maxCount]; 00418 else 00419 return m_list[(m_first + index) % m_maxCount]; 00420 } 00421 00422 //! Return the index'th oldest item from the queue 00423 value_type& operator[] (size_t index) 00424 { 00425 if (index >= m_currentCount) 00426 return m_list[(m_first + m_currentCount - 1) % m_maxCount]; 00427 else 00428 return m_list[(m_first + index) % m_maxCount]; 00429 } 00430 00431 void clear(void) 00432 { 00433 m_currentCount = 0; 00434 m_first = 0; 00435 } 00436 00437 void remove(size_t index) 00438 { 00439 if (index >= m_currentCount) 00440 return; 00441 if (index == 0) 00442 pop(); 00443 else 00444 { 00445 --m_currentCount; 00446 for (size_t i=index;i<m_currentCount;++i) 00447 m_list[(m_first + i) % m_maxCount] = m_list[(1 + m_first + i) % m_maxCount]; 00448 } 00449 } 00450 }; 00451 00452 } // end of xsens namespace 00453 00454 #endif // _FIFOQUEUE_H_2006_05_03