ts_RingBuffer.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
00014 
00015 //----------------------------------------------------------------------
00022 //----------------------------------------------------------------------
00023 #include <icl_core/RingBuffer.h>
00024 
00025 #include <boost/test/unit_test.hpp>
00026 #include <boost/mpl/list.hpp>
00027 
00028 using icl_core::RingBuffer;
00029 
00030 BOOST_AUTO_TEST_SUITE(ts_RingBuffer)
00031 
00032 typedef boost::mpl::list<char, short, int, long, float, double> TestTypes;
00033 
00034 BOOST_AUTO_TEST_CASE_TEMPLATE(RingBufferCapacity, T, TestTypes)
00035 {
00036   RingBuffer<T> ringbuffer(10);
00037 
00038   // Check empty
00039   BOOST_CHECK_EQUAL(ringbuffer.size(), 0u);
00040   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00041   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 10u);
00042   BOOST_CHECK_EQUAL(ringbuffer.empty(), true);
00043   BOOST_CHECK_EQUAL(ringbuffer.full(), false);
00044 
00045   // Check some exceptions
00046   bool read_exception_called = false;
00047   try { ringbuffer.read(); }
00048   catch (std::out_of_range&) { read_exception_called = true; }
00049   BOOST_CHECK_EQUAL(read_exception_called, true);
00050 
00051   // Add one element and check size
00052   ringbuffer.write(0);
00053 
00054   BOOST_CHECK_EQUAL(ringbuffer.size(), 1u);
00055   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00056   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 9u);
00057   BOOST_CHECK_EQUAL(ringbuffer.empty(), false);
00058   BOOST_CHECK_EQUAL(ringbuffer.full(), false);
00059 
00060   // Add six more elements, check again
00061   ringbuffer.write(1);
00062   ringbuffer.write(2);
00063   ringbuffer.write(3);
00064   ringbuffer.write(4);
00065   ringbuffer.write(5);
00066   ringbuffer.write(6);
00067 
00068   BOOST_CHECK_EQUAL(ringbuffer.size(), 7u);
00069   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00070   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 3u);
00071   BOOST_CHECK_EQUAL(ringbuffer.empty(), false);
00072   BOOST_CHECK_EQUAL(ringbuffer.full(), false);
00073 
00074   // Fill up, check full
00075   ringbuffer.write(7);
00076   ringbuffer.write(8);
00077   ringbuffer.write(9);
00078 
00079   BOOST_CHECK_EQUAL(ringbuffer.size(), 10u);
00080   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00081   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 0u);
00082   BOOST_CHECK_EQUAL(ringbuffer.empty(), false);
00083   BOOST_CHECK_EQUAL(ringbuffer.full(), true);
00084 
00085   // Check all contained element values
00086   BOOST_CHECK_EQUAL(ringbuffer.at(0), T(0));
00087   BOOST_CHECK_EQUAL(ringbuffer.at(1), T(1));
00088   BOOST_CHECK_EQUAL(ringbuffer.at(2), T(2));
00089   BOOST_CHECK_EQUAL(ringbuffer.at(3), T(3));
00090   BOOST_CHECK_EQUAL(ringbuffer.at(4), T(4));
00091   BOOST_CHECK_EQUAL(ringbuffer.at(5), T(5));
00092   BOOST_CHECK_EQUAL(ringbuffer.at(6), T(6));
00093   BOOST_CHECK_EQUAL(ringbuffer.at(7), T(7));
00094   BOOST_CHECK_EQUAL(ringbuffer.at(8), T(8));
00095   BOOST_CHECK_EQUAL(ringbuffer.at(9), T(9));
00096 
00097   // Remove the first four elements
00098   BOOST_CHECK_EQUAL(ringbuffer.read(), T(0));
00099   BOOST_CHECK_EQUAL(ringbuffer.read(), T(1));
00100   BOOST_CHECK_EQUAL(ringbuffer.read(), T(2));
00101   BOOST_CHECK_EQUAL(ringbuffer.read(), T(3));
00102 
00103   // Check size
00104   BOOST_CHECK_EQUAL(ringbuffer.size(), 6u);
00105   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00106   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 4u);
00107   BOOST_CHECK_EQUAL(ringbuffer.empty(), false);
00108   BOOST_CHECK_EQUAL(ringbuffer.full(), false);
00109 
00110   // Check remaining element values
00111   BOOST_CHECK_EQUAL(ringbuffer.at(0), T(4));
00112   BOOST_CHECK_EQUAL(ringbuffer.at(1), T(5));
00113   BOOST_CHECK_EQUAL(ringbuffer.at(2), T(6));
00114   BOOST_CHECK_EQUAL(ringbuffer.at(3), T(7));
00115   BOOST_CHECK_EQUAL(ringbuffer.at(4), T(8));
00116   BOOST_CHECK_EQUAL(ringbuffer.at(5), T(9));
00117 
00118   // Fill up again, check full
00119   ringbuffer.write(10);
00120   ringbuffer.write(11);
00121   ringbuffer.write(12);
00122   ringbuffer.write(13);
00123 
00124   BOOST_CHECK_EQUAL(ringbuffer.size(), 10u);
00125   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00126   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 0u);
00127   BOOST_CHECK_EQUAL(ringbuffer.empty(), false);
00128   BOOST_CHECK_EQUAL(ringbuffer.full(), true);
00129 
00130   // Check all element values
00131   BOOST_CHECK_EQUAL(ringbuffer.at(0), T(4));
00132   BOOST_CHECK_EQUAL(ringbuffer.at(1), T(5));
00133   BOOST_CHECK_EQUAL(ringbuffer.at(2), T(6));
00134   BOOST_CHECK_EQUAL(ringbuffer.at(3), T(7));
00135   BOOST_CHECK_EQUAL(ringbuffer.at(4), T(8));
00136   BOOST_CHECK_EQUAL(ringbuffer.at(5), T(9));
00137   BOOST_CHECK_EQUAL(ringbuffer.at(6), T(10));
00138   BOOST_CHECK_EQUAL(ringbuffer.at(7), T(11));
00139   BOOST_CHECK_EQUAL(ringbuffer.at(8), T(12));
00140   BOOST_CHECK_EQUAL(ringbuffer.at(9), T(13));
00141 
00142   // Check some exceptions
00143   bool write_exception_called = false;
00144   try { ringbuffer.write(14); }
00145   catch (std::out_of_range&) { write_exception_called = true; }
00146   BOOST_CHECK_EQUAL(write_exception_called, true);
00147 
00148   // Skip some elements, check size
00149   ringbuffer.skip();
00150   ringbuffer.skip(3);
00151 
00152   BOOST_CHECK_EQUAL(ringbuffer.size(), 6u);
00153   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00154   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 4u);
00155   BOOST_CHECK_EQUAL(ringbuffer.empty(), false);
00156   BOOST_CHECK_EQUAL(ringbuffer.full(), false);
00157 
00158   // Check all element values
00159   BOOST_CHECK_EQUAL(ringbuffer.at(0), T(8));
00160   BOOST_CHECK_EQUAL(ringbuffer.at(1), T(9));
00161   BOOST_CHECK_EQUAL(ringbuffer.at(2), T(10));
00162   BOOST_CHECK_EQUAL(ringbuffer.at(3), T(11));
00163   BOOST_CHECK_EQUAL(ringbuffer.at(4), T(12));
00164   BOOST_CHECK_EQUAL(ringbuffer.at(5), T(13));
00165 
00166   // Empty buffer, check empty
00167   ringbuffer.skip(10);
00168 
00169   BOOST_CHECK_EQUAL(ringbuffer.size(), 0u);
00170   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00171   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 10u);
00172   BOOST_CHECK_EQUAL(ringbuffer.empty(), true);
00173   BOOST_CHECK_EQUAL(ringbuffer.full(), false);
00174 
00175   // Check some exceptions
00176   bool skip_exception_called = false;
00177   try { ringbuffer.skip(); }
00178   catch (std::out_of_range&) { skip_exception_called = true; }
00179   BOOST_CHECK_EQUAL(skip_exception_called, true);
00180 
00181   // Check arrays.  Since the ringbuffer has been emptied completely,
00182   // the read/write pointers should be at entry 0 again.
00183   BOOST_CHECK_EQUAL(ringbuffer.arrayOne().first, ringbuffer.arrayTwo().first);
00184 
00185   BOOST_CHECK_EQUAL(ringbuffer.arrayOne().second, 0u);
00186   BOOST_CHECK_EQUAL(ringbuffer.arrayTwo().second, 0u);
00187   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayOne().second, 10u);
00188   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayTwo().second, 0u);
00189 
00190   // Add some more elemets to move the read/write pointers.
00191   ringbuffer.write(0);
00192   ringbuffer.write(1);
00193   ringbuffer.write(2);
00194   ringbuffer.write(3);
00195   ringbuffer.write(4);
00196   ringbuffer.skip(2);
00197 
00198   // [ - | 2 3 4 - - - - - - ]
00199   BOOST_CHECK_EQUAL(ringbuffer.arrayOne().second, 3u);
00200   BOOST_CHECK_EQUAL(ringbuffer.arrayTwo().second, 0u);
00201   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayOne().second, 6u);
00202   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayTwo().second, 1u);
00203 
00204   // Add some more elemets to move the read/write pointers.
00205   ringbuffer.write(5);
00206   ringbuffer.write(6);
00207   ringbuffer.write(7);
00208   ringbuffer.write(8);
00209   ringbuffer.write(9);
00210   ringbuffer.skip(3);
00211 
00212   // [ - - - - | 5 6 7 8 9 - ]
00213   BOOST_CHECK_EQUAL(ringbuffer.arrayOne().second, 5u);
00214   BOOST_CHECK_EQUAL(ringbuffer.arrayTwo().second, 0u);
00215   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayOne().second, 1u);
00216   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayTwo().second, 4u);
00217 
00218   // Add some more elemets to move the read/write pointers.
00219   ringbuffer.write(10);
00220   ringbuffer.write(11);
00221   ringbuffer.write(12);
00222   ringbuffer.write(13);
00223   ringbuffer.skip(3);
00224 
00225   // [ 11 12 13 - - - - | 8 9 10 ]
00226   BOOST_CHECK_EQUAL(ringbuffer.arrayOne().second, 3u);
00227   BOOST_CHECK_EQUAL(ringbuffer.arrayTwo().second, 3u);
00228   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayOne().second, 4u);
00229   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayTwo().second, 0u);
00230 
00231   // Check that iterators behave correctly.
00232   size_t i = 0;
00233   for (typename RingBuffer<T>::iterator it = ringbuffer.begin(); it != ringbuffer.end(); ++it, ++i)
00234   {
00235     BOOST_CHECK_EQUAL(ringbuffer.at(i), *it);
00236   }
00237   // Same for postfix increment.
00238   i = 0;
00239   for (typename RingBuffer<T>::iterator it = ringbuffer.begin(); it != ringbuffer.end(); it++, ++i)
00240   {
00241     BOOST_CHECK_EQUAL(ringbuffer.at(i), *it);
00242   }
00243   // Check that const_iterators behave correctly.
00244   i = 0;
00245   for (typename RingBuffer<T>::const_iterator it = ringbuffer.begin(); it != ringbuffer.end(); ++it, ++i)
00246   {
00247     BOOST_CHECK_EQUAL(ringbuffer.at(i), *it);
00248   }
00249   // Same for postfix increment.
00250   i = 0;
00251   for (typename RingBuffer<T>::const_iterator it = ringbuffer.begin(); it != ringbuffer.end(); it++, ++i)
00252   {
00253     BOOST_CHECK_EQUAL(ringbuffer.at(i), *it);
00254   }
00255 
00256   // Check that we can move the iterator around.
00257   BOOST_CHECK((ringbuffer.begin() + 3) - 3 == ringbuffer.begin());
00258   BOOST_CHECK((ringbuffer.begin() - 3) + 3 == ringbuffer.begin());
00259   BOOST_CHECK_EQUAL(ringbuffer.end() - ringbuffer.begin(), 6);
00260   BOOST_CHECK_EQUAL(ringbuffer.begin() - ringbuffer.end(), -6);
00261 
00262   // Now make some more room, then add some elements externally.
00263   ringbuffer.skip(3);
00264   // [ 11 12 13 - - - - - - - | ]
00265   T *empty_space = ringbuffer.emptyArrayOne().first;
00266   for (size_t i=0; i<5; ++i)
00267   {
00268     empty_space[i] = T(i+14);
00269   }
00270   // [ 11 12 13 (14) (15) (16) (17) (18) - - | ]
00271   ringbuffer.fakeWrite(5);
00272 
00273   // [ 11 12 13 14 15 16 17 18 - - | ]
00274   BOOST_CHECK_EQUAL(ringbuffer.size(), 8u);
00275   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00276   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 2u);
00277   BOOST_CHECK_EQUAL(ringbuffer.empty(), false);
00278   BOOST_CHECK_EQUAL(ringbuffer.full(), false);
00279   BOOST_CHECK_EQUAL(ringbuffer.at(0), T(11));
00280   BOOST_CHECK_EQUAL(ringbuffer.at(1), T(12));
00281   BOOST_CHECK_EQUAL(ringbuffer.at(2), T(13));
00282   BOOST_CHECK_EQUAL(ringbuffer.at(3), T(14));
00283   BOOST_CHECK_EQUAL(ringbuffer.at(4), T(15));
00284   BOOST_CHECK_EQUAL(ringbuffer.at(5), T(16));
00285   BOOST_CHECK_EQUAL(ringbuffer.at(6), T(17));
00286   BOOST_CHECK_EQUAL(ringbuffer.at(7), T(18));
00287 
00288   BOOST_CHECK_EQUAL(ringbuffer.arrayOne().second, 8u);
00289   BOOST_CHECK_EQUAL(ringbuffer.arrayTwo().second, 0u);
00290   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayOne().second, 2u);
00291   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayTwo().second, 0u);
00292 
00293   // Now fill it up completely.
00294   ringbuffer.write(T(19));
00295   ringbuffer.write(T(20));
00296   BOOST_CHECK_EQUAL(ringbuffer.size(), 10u);
00297   BOOST_CHECK_EQUAL(ringbuffer.capacity(), 10u);
00298   BOOST_CHECK_EQUAL(ringbuffer.reserve(), 0u);
00299   BOOST_CHECK_EQUAL(ringbuffer.empty(), false);
00300   BOOST_CHECK_EQUAL(ringbuffer.full(), true);
00301   BOOST_CHECK_EQUAL(ringbuffer.at(8), T(19));
00302   BOOST_CHECK_EQUAL(ringbuffer.at(9), T(20));
00303   BOOST_CHECK_EQUAL(ringbuffer.arrayOne().second, 10u);
00304   BOOST_CHECK_EQUAL(ringbuffer.arrayTwo().second, 0u);
00305   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayOne().second, 0u);
00306   BOOST_CHECK_EQUAL(ringbuffer.emptyArrayTwo().second, 0u);
00307 
00308   // Check that we can move the iterator around.
00309   BOOST_CHECK((ringbuffer.begin() + 3) - 3 == ringbuffer.begin());
00310   BOOST_CHECK((ringbuffer.begin() - 3) + 3 == ringbuffer.begin());
00311   BOOST_CHECK_EQUAL(ringbuffer.end() - ringbuffer.begin(), 10);
00312   BOOST_CHECK_EQUAL(ringbuffer.begin() - ringbuffer.end(), -10);
00313 }
00314 
00315 BOOST_AUTO_TEST_CASE_TEMPLATE(RingBufferConstness, T, TestTypes)
00316 {
00317   RingBuffer<T> ringbuffer(10);
00318 
00319   // Add some elements until it's completely full.
00320   ringbuffer.write(0);
00321   ringbuffer.write(1);
00322   ringbuffer.write(2);
00323   ringbuffer.write(3);
00324   ringbuffer.write(4);
00325   ringbuffer.write(5);
00326   ringbuffer.write(6);
00327   ringbuffer.write(7);
00328   ringbuffer.write(8);
00329   ringbuffer.write(9);
00330 
00331   const RingBuffer<T>& ringbuffer_const = ringbuffer;
00332 
00333   BOOST_CHECK_EQUAL(ringbuffer_const.size(), 10u);
00334   BOOST_CHECK_EQUAL(ringbuffer_const.capacity(), 10u);
00335   BOOST_CHECK_EQUAL(ringbuffer_const.reserve(), 0u);
00336   BOOST_CHECK_EQUAL(ringbuffer_const.empty(), false);
00337   BOOST_CHECK_EQUAL(ringbuffer_const.full(), true);
00338 
00339   // Check all contained element values
00340   BOOST_CHECK_EQUAL(ringbuffer_const.at(0), T(0));
00341   BOOST_CHECK_EQUAL(ringbuffer_const.at(1), T(1));
00342   BOOST_CHECK_EQUAL(ringbuffer_const.at(2), T(2));
00343   BOOST_CHECK_EQUAL(ringbuffer_const.at(3), T(3));
00344   BOOST_CHECK_EQUAL(ringbuffer_const.at(4), T(4));
00345   BOOST_CHECK_EQUAL(ringbuffer_const.at(5), T(5));
00346   BOOST_CHECK_EQUAL(ringbuffer_const.at(6), T(6));
00347   BOOST_CHECK_EQUAL(ringbuffer_const.at(7), T(7));
00348   BOOST_CHECK_EQUAL(ringbuffer_const.at(8), T(8));
00349   BOOST_CHECK_EQUAL(ringbuffer_const.at(9), T(9));
00350 
00351   // Check that const_iterators behave correctly.
00352   size_t i = 0;
00353   for (typename RingBuffer<T>::const_iterator it = ringbuffer_const.begin(); it != ringbuffer_const.end(); ++it, ++i)
00354   {
00355     BOOST_CHECK_EQUAL(ringbuffer_const.at(i), *it);
00356   }
00357   // Same for postfix increment.
00358   i = 0;
00359   for (typename RingBuffer<T>::const_iterator it = ringbuffer_const.begin(); it != ringbuffer_const.end(); it++, ++i)
00360   {
00361     BOOST_CHECK_EQUAL(ringbuffer_const.at(i), *it);
00362   }
00363 
00364   // Check that we can move the iterator around.
00365   BOOST_CHECK((ringbuffer_const.begin() + 3) - 3 == ringbuffer_const.begin());
00366   BOOST_CHECK((ringbuffer_const.begin() - 3) + 3 == ringbuffer_const.begin());
00367   BOOST_CHECK_EQUAL(ringbuffer_const.end() - ringbuffer_const.begin(), 10);
00368   BOOST_CHECK_EQUAL(ringbuffer_const.begin() - ringbuffer_const.end(), -10);
00369 }
00370 
00371 BOOST_AUTO_TEST_SUITE_END()


fzi_icl_core
Author(s):
autogenerated on Thu Jun 6 2019 20:22:24