Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
test_lfringbuffer01.cpp
Go to the documentation of this file.
1 /*
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include <iostream>
25 #include <cassert>
26 #include <cinttypes>
27 #include <cstring>
28 #include <memory>
29 
30 #define CATCH_CONFIG_MAIN
31 #include <catch2/catch_amalgamated.hpp>
32 #include <jau/test/catch2_ext.hpp>
33 
34 #include <jau/ringbuffer.hpp>
35 
36 using namespace jau;
37 
38 typedef uint8_t IntegralType;
39 typedef uint8_t TrivialType;
40 constexpr const TrivialType TrivialTypeNullElem(0xff);
42 
43 // Test examples.
45  private:
46 
47  TrivialTypeRingbuffer createEmpty(jau::nsize_t initialCapacity) {
48  TrivialTypeRingbuffer rb(0xff, initialCapacity);
49  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
50  return rb;
51  }
52  TrivialTypeRingbuffer createFull(const std::vector<TrivialType> & source) {
53  TrivialTypeRingbuffer rb(0xff, source);
54  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
55  return rb;
56  }
57 
58  std::vector<TrivialType> createIntArray(const jau::nsize_t capacity, const IntegralType startValue) {
59  std::vector<TrivialType> array(capacity);
60  for(jau::nsize_t i=0; i<capacity; i++) {
61  array[i] = TrivialType(startValue+i);
62  }
63  return array;
64  }
65 
66  void readTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
67  (void) clearRef;
68 
69  jau::nsize_t preSize = rb.getSize();
70  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
71  REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
72  REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
73  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
74 
75  for(jau::nsize_t i=0; i<len; i++) {
76  TrivialType svI = rb.get();
77  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
78  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI);
79  }
80 
81  REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.getSize());
82  REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.getFreeSlots()>= len);
83  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
84  }
85  void readTestImpl2(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
86  (void) clearRef;
87 
88  jau::nsize_t preSize = rb.getSize();
89  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
90  REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
91  REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
92  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
93 
94  for(jau::nsize_t i=0; i<len; i++) {
95  TrivialType svI;
96  REQUIRE_MSG("ringbuffer get", rb.get(svI));
97  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
98  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI);
99  }
100 
101  REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.getSize());
102  REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.getFreeSlots()>= len);
103  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
104  }
105 
106  void readRangeTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
107  (void) clearRef;
108 
109  jau::nsize_t preSize = rb.getSize();
110  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
111  REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
112  REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
113  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
114 
115  std::vector<TrivialType> array(len);
116  REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) );
117 
118  REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.getSize());
119  REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.getFreeSlots()>= len);
120  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
121 
122  for(jau::nsize_t i=0; i<len; i++) {
123  TrivialType svI = array[i];
124  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
125  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI);
126  }
127  }
128 
129  void writeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
130  jau::nsize_t preSize = rb.getSize();
131 
132  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
133  REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
134  REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity);
135  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
136 
137  for(jau::nsize_t i=0; i<len; i++) {
138  std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString();
139  REQUIRE_MSG(m, rb.put( TrivialType( startValue+i ) ) );
140  }
141 
142  REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.getSize());
143  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
144  }
145 
146  void writeRangeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, const std::vector<TrivialType> & data) {
147  jau::nsize_t preSize = rb.getSize();
148  jau::nsize_t postSize = preSize+data.size();
149 
150  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
151  REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size());
152  REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity);
153  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
154  REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size());
155  REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.getFreeSlots() >= data.size());
156 
157  REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) );
158 
159  REQUIRE_MSG("size "+rb.toString(), postSize == rb.getSize());
160  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
161  }
162 
163  void moveGetPutImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) {
164  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
165  for(jau::nsize_t i=0; i<pos; i++) {
166  REQUIRE_MSG("moveFull.get "+rb.toString(), (IntegralType)i == rb.get());
167  REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( TrivialType( (IntegralType)i ) ) );
168  }
169  }
170 
171  void movePutGetImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) {
172  REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull());
173  for(jau::nsize_t i=0; i<pos; i++) {
174  REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( TrivialType( 600+(IntegralType)i ) ) );
175  REQUIRE_MSG("moveEmpty.get "+rb.toString(), 600+(IntegralType)i == rb.get());
176  }
177  }
178 
179  public:
180 
182  TrivialTypeRingbuffer rb = createEmpty(11);
183 
184  std::string msg("Ringbuffer: uses_memcpy "+std::to_string(TrivialTypeRingbuffer::uses_memcpy)+
186  ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename TrivialTypeRingbuffer::value_type>::value)+
187  ", size "+std::to_string(sizeof(rb))+" bytes");
188  fprintf(stderr, "%s", msg.c_str());
189  REQUIRE_MSG("Ringbuffer<T> using memcpy", TrivialTypeRingbuffer::uses_memcpy);
190  REQUIRE_MSG("Ringbuffer<T> uses memset", TrivialTypeRingbuffer::uses_memset);
191  }
192 
194  jau::nsize_t capacity = 11;
195  std::vector<TrivialType> source = createIntArray(capacity, 0);
196  TrivialTypeRingbuffer rb = createFull(source);
197  INFO_STR("test01_FullRead: Created / "+ rb.toString());
198  REQUIRE_MSG("full size "+rb.toString(), capacity == rb.getSize());
199  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
200 
201  readTestImpl(rb, true, capacity, capacity, 0);
202  INFO_STR("test01_FullRead: PostRead / " + rb.toString());
203  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
204  }
205 
207  jau::nsize_t capacity = 11;
208  TrivialTypeRingbuffer rb = createEmpty(capacity);
209  INFO( std::string("test02_EmptyWrite: Created / ") + rb.toString().c_str());
210  REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.getSize());
211  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
212 
213  writeTestImpl(rb, capacity, capacity, 0);
214  INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb.toString().c_str());
215  REQUIRE_MSG("full size "+rb.toString(), capacity == rb.getSize());
216  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
217 
218  readTestImpl(rb, true, capacity, capacity, 0);
219  INFO( std::string("test02_EmptyWrite: PostRead / ") + rb.toString().c_str());
220  REQUIRE_MSG("empty1 "+rb.toString(), rb.isEmpty());
221  }
222 
224  {
225  jau::nsize_t capacity = 11;
226  TrivialTypeRingbuffer rb = createEmpty(capacity);
227  INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
228  REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.getSize());
229  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
230 
231  /**
232  * Move R == W == 0
233  * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
234  */
235  std::vector<TrivialType> new_data = createIntArray(capacity, 0);
236  writeRangeTestImpl(rb, capacity, new_data);
237 
238  INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
239  REQUIRE_MSG("full size "+rb.toString(), capacity == rb.getSize());
240  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
241 
242  readRangeTestImpl(rb, true, capacity, capacity, 0);
243  INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
244  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
245  }
246  {
247  jau::nsize_t capacity = 11;
248 
249  TrivialTypeRingbuffer rb = createEmpty(capacity);
250  INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
251  REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.getSize());
252  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
253 
254  /**
255  * Move R == W == 3
256  * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
257  * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ]
258  */
260  rb.put(dummy);
261  rb.put(dummy);
262  rb.put(dummy);
263  rb.drop(3);
264 
265  std::vector<TrivialType> new_data = createIntArray(capacity, 0);
266  writeRangeTestImpl(rb, capacity, new_data);
267  // writeTestImpl(rb, capacity, capacity, 0);
268 
269  INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
270  REQUIRE_MSG("full size "+rb.toString(), capacity == rb.getSize());
271  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
272 
273  readRangeTestImpl(rb, true, capacity, capacity, 0);
274  // readTestImpl(rb, true, capacity, capacity, 0);
275 
276  INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
277  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
278  }
279  {
280  jau::nsize_t capacity = 11;
281  TrivialTypeRingbuffer rb = createEmpty(capacity);
282  INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
283  REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.getSize());
284  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
285 
286  /**
287  * Move R == 2, W == 4, size 2
288  * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
289  * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R
290  */
292  rb.put(dummy); // w idx 0 -> 1
293  rb.put(dummy);
294  rb.put(dummy);
295  rb.put(dummy); // w idx 3 -> 4
296  rb.drop(2); // r idx 0 -> 2
297 
298  // left = 11 - 2
299  REQUIRE_MSG("size 2 "+rb.toString(), 2 == rb.getSize());
300  REQUIRE_MSG("available 11-2 "+rb.toString(), capacity-2 == rb.getFreeSlots());
301 
302  std::vector<TrivialType> new_data = createIntArray(capacity-2, 0);
303  writeRangeTestImpl(rb, capacity, new_data);
304  // writeTestImpl(rb, capacity, capacity-2, 0);
305 
306  INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
307  REQUIRE_MSG("full size "+rb.toString(), capacity == rb.getSize());
308  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
309 
310  // take off 2 remaining dummies
311  rb.drop(2);
312  REQUIRE_MSG("size capacity-2 "+rb.toString(), capacity-2 == rb.getSize());
313 
314  readRangeTestImpl(rb, true, capacity, capacity-2, 0);
315  // readTestImpl(rb, true, capacity, capacity-2, 0);
316  INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
317  REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.getSize());
318  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
319  }
320  {
321  jau::nsize_t capacity = 11;
322  TrivialTypeRingbuffer rb = createEmpty(capacity);
323  INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
324  REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.getSize());
325  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
326 
327  /**
328  * Move R == 9, W == 1, size 3
329  * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
330  * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1
331  */
333  for(int i=0; i<11; i++) { rb.put(dummy); } // fill all
334  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
335 
336  rb.drop(10); // pull
337  REQUIRE_MSG("size 1"+rb.toString(), 1 == rb.getSize());
338 
339  for(int i=0; i<2; i++) { rb.put(dummy); } // fill 2 more
340  REQUIRE_MSG("size 3"+rb.toString(), 3 == rb.getSize());
341 
342  // left = 11 - 3
343  REQUIRE_MSG("available 11-3 "+rb.toString(), capacity-3 == rb.getFreeSlots());
344 
345  std::vector<TrivialType> new_data = createIntArray(capacity-3, 0);
346  writeRangeTestImpl(rb, capacity, new_data);
347  // writeTestImpl(rb, capacity, capacity-3, 0);
348 
349  INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
350  REQUIRE_MSG("full size "+rb.toString(), capacity == rb.getSize());
351  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
352 
353  // take off 3 remaining dummies
354  rb.drop(3); // pull
355  REQUIRE_MSG("size capacity-3 "+rb.toString(), capacity-3 == rb.getSize());
356 
357  readRangeTestImpl(rb, true, capacity, capacity-3, 0);
358  // readTestImpl(rb, true, capacity, capacity-3, 0);
359  INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
360  REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.getSize());
361  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
362  }
363  }
364 
366  jau::nsize_t capacity = 11;
367  std::vector<TrivialType> source = createIntArray(capacity, 0);
368  TrivialTypeRingbuffer rb = createFull(source);
369  INFO_STR("test04_FullReadReset: Created / " + rb.toString());
370  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
371 
372  rb.reset(source);
373  INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString());
374  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
375 
376  readTestImpl(rb, false, capacity, capacity, 0);
377  INFO_STR("test04_FullReadReset: Post Read / " + rb.toString());
378  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
379 
380  rb.reset(source);
381  INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString());
382  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
383 
384  readTestImpl2(rb, false, capacity, capacity, 0);
385  INFO_STR("test04_FullReadReset: Post Read / " + rb.toString());
386  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
387  }
388 
390  jau::nsize_t capacity = 11;
391  TrivialTypeRingbuffer rb = createEmpty(capacity);
392  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
393 
394  rb.clear();
395  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
396 
397  writeTestImpl(rb, capacity, capacity, 0);
398  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
399 
400  readTestImpl(rb, false, capacity, capacity, 0);
401  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
402 
403  rb.clear();
404  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
405 
406  writeTestImpl(rb, capacity, capacity, 0);
407  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
408 
409  readTestImpl2(rb, false, capacity, capacity, 0);
410  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
411  }
412 
414  jau::nsize_t capacity = 11;
415  std::vector<TrivialType> source = createIntArray(capacity, 0);
416  TrivialTypeRingbuffer rb = createFull(source);
417  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
418 
419  rb.reset(source);
420  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
421 
422  readTestImpl(rb, false, capacity, 5, 0);
423  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
424  REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull());
425 
426  rb.reset(source);
427  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
428 
429  readTestImpl(rb, false, capacity, capacity, 0);
430  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
431  }
432 
434  jau::nsize_t capacity = 11;
435  std::vector<TrivialType> source = createIntArray(capacity, 0);
436  TrivialTypeRingbuffer rb = createFull(source);
437  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
438 
439  rb.reset(source);
440  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
441 
442  moveGetPutImpl(rb, 5);
443  readTestImpl(rb, false, capacity, 5, 5);
444  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
445  REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull());
446 
447  rb.reset(source);
448  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
449 
450  readTestImpl(rb, false, capacity, capacity, 0);
451  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
452  }
453 
454  private:
455 
456  void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) {
457  jau::nsize_t growAmount = 5;
458  jau::nsize_t grownCapacity = initialCapacity+growAmount;
459  std::vector<TrivialType> source = createIntArray(initialCapacity, 0);
460  TrivialTypeRingbuffer rb = createFull(source);
461 
462  for(jau::nsize_t i=0; i<initialCapacity; i++) {
463  TrivialType svI = rb.get();
464  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
465  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((0+i)%initialCapacity) == svI);
466  }
467  REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.getSize());
468 
469  rb.reset(source);
470  REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.getSize());
471 
472  moveGetPutImpl(rb, pos);
473  // PRINTM("X02 "+rb.toString());
474  // rb.dump(stderr, "X02");
475 
476  rb.recapacity(grownCapacity);
477  REQUIRE_MSG("capacity "+rb.toString(), grownCapacity == rb.capacity());
478  REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.getSize());
479  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
480  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
481  // PRINTM("X03 "+rb.toString());
482  // rb.dump(stderr, "X03");
483 
484  for(jau::nsize_t i=0; i<growAmount; i++) {
485  REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb.toString(), rb.put( TrivialType( 100+i ) ) );
486  }
487  REQUIRE_MSG("new size "+rb.toString(), grownCapacity == rb.getSize());
488  REQUIRE_MSG("full "+rb.toString(), rb.isFull());
489 
490  for(jau::nsize_t i=0; i<initialCapacity; i++) {
491  TrivialType svI = rb.get();
492  // PRINTM("X05["+std::to_string(i)+"]: "+rb.toString()+", svI-null: "+std::to_string(svI==TrivialTypeNullElem));
493  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
494  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((pos+i)%initialCapacity) == svI);
495  }
496 
497  for(jau::nsize_t i=0; i<growAmount; i++) {
498  TrivialType svI = rb.get();
499  // PRINTM("X07["+std::to_string(i)+"]: "+rb.toString()+", svI-null: "+std::to_string(svI==TrivialTypeNullElem));
500  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
501  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(100+i) == svI);
502  }
503 
504  REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.getSize());
505  REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
506 
507  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
508  }
509 
510  public:
511 
513  test_GrowFullImpl(11, 0);
514  }
516  test_GrowFullImpl(11, 0+1);
517  }
519  test_GrowFullImpl(11, 0+2);
520  }
522  test_GrowFullImpl(11, 0+3);
523  }
525  test_GrowFullImpl(11, 11-1);
526  }
528  test_GrowFullImpl(11, 11-1-1);
529  }
531  test_GrowFullImpl(11, 11-1-2);
532  }
534  test_GrowFullImpl(11, 11-1-3);
535  }
536 
537 };
538 
539 #if 1
556 #else
557 METHOD_AS_TEST_CASE( TestRingbuffer01::test00_PrintInfo, "Test TestRingbuffer 01- 00");
558 METHOD_AS_TEST_CASE( TestRingbuffer01::test03_EmptyWriteRange, "Test TestRingbuffer 01- 03");
559 #endif
jau::ringbuffer::getFreeSlots
Size_type getFreeSlots() const noexcept
Returns the number of free slots available to put.
Definition: ringbuffer.hpp:935
TestRingbuffer01::test23_GrowFull04_Begin3
void test23_GrowFull04_Begin3()
Definition: test_lfringbuffer01.cpp:521
TestRingbuffer01::test26_GrowFull12_End2
void test26_GrowFull12_End2()
Definition: test_lfringbuffer01.cpp:530
jau::ringbuffer::put
bool put(Value_type &&e) noexcept
Enqueues the given element by moving it into this ringbuffer storage.
Definition: ringbuffer.hpp:1140
jau::ringbuffer::reset
void reset(const Value_type *copyFrom, const Size_type copyFromCount) noexcept
clear() all elements and add all copyFrom elements thereafter.
Definition: ringbuffer.hpp:911
TestRingbuffer01
Definition: test_lfringbuffer01.cpp:44
jau::ringbuffer::isEmpty
bool isEmpty() const noexcept
Returns true if this ring buffer is empty, otherwise false.
Definition: ringbuffer.hpp:938
TestRingbuffer01::test02_EmptyWrite
void test02_EmptyWrite()
Definition: test_lfringbuffer01.cpp:206
TestRingbuffer01::test06_ReadResetMid01
void test06_ReadResetMid01()
Definition: test_lfringbuffer01.cpp:413
TrivialTypeRingbuffer
ringbuffer< TrivialType, TrivialType, jau::nsize_t > TrivialTypeRingbuffer
Definition: test_lfringbuffer01.cpp:41
IntegralType
uint8_t IntegralType
Definition: test_lfringbuffer01.cpp:38
jau::ringbuffer::clear
void clear() noexcept
Releasing all elements by assigning nullelem.
Definition: ringbuffer.hpp:900
METHOD_AS_TEST_CASE
METHOD_AS_TEST_CASE(TestRingbuffer01::test00_PrintInfo, "Test TestRingbuffer 01- 00")
jau
Definition: basic_algos.hpp:34
jau::ringbuffer::isFull
bool isFull() const noexcept
Returns true if this ring buffer is full, otherwise false.
Definition: ringbuffer.hpp:941
jau::to_string
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
Definition: byte_util.hpp:198
TestRingbuffer01::test01_FullRead
void test01_FullRead()
Definition: test_lfringbuffer01.cpp:193
TestRingbuffer01::test05_EmptyWriteClear
void test05_EmptyWriteClear()
Definition: test_lfringbuffer01.cpp:389
INFO_STR
#define INFO_STR(msg)
Definition: catch2_ext.hpp:59
TestRingbuffer01::test00_PrintInfo
void test00_PrintInfo()
Definition: test_lfringbuffer01.cpp:181
jau::ringbuffer::uses_memcpy
constexpr static const bool uses_memcpy
Definition: ringbuffer.hpp:117
TestRingbuffer01::test27_GrowFull13_End3
void test27_GrowFull13_End3()
Definition: test_lfringbuffer01.cpp:533
TestRingbuffer01::test07_ReadResetMid02
void test07_ReadResetMid02()
Definition: test_lfringbuffer01.cpp:433
jau::ringbuffer
Ring buffer implementation, a.k.a circular buffer, exposing lock-free get*(..) and put*(....
Definition: ringbuffer.hpp:115
jau::ringbuffer::uses_memset
constexpr static const bool uses_memset
Definition: ringbuffer.hpp:118
TestRingbuffer01::test24_GrowFull05_End
void test24_GrowFull05_End()
Definition: test_lfringbuffer01.cpp:524
TestRingbuffer01::test22_GrowFull03_Begin2
void test22_GrowFull03_Begin2()
Definition: test_lfringbuffer01.cpp:518
TestRingbuffer01::test03_EmptyWriteRange
void test03_EmptyWriteRange()
Definition: test_lfringbuffer01.cpp:223
TrivialTypeNullElem
constexpr const TrivialType TrivialTypeNullElem(0xff)
jau::ringbuffer::toString
std::string toString() const noexcept
Returns a short string representation incl.
Definition: ringbuffer.hpp:758
jau::ringbuffer::capacity
Size_type capacity() const noexcept
Returns the net capacity of this ring buffer.
Definition: ringbuffer.hpp:891
jau::nsize_t
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:44
jau::ringbuffer::get
Value_type get() noexcept
Dequeues the oldest enqueued element if available, otherwise null.
Definition: ringbuffer.hpp:1004
ringbuffer.hpp
jau::ringbuffer::getSize
Size_type getSize() const noexcept
Returns the number of elements in this ring buffer.
Definition: ringbuffer.hpp:926
TestRingbuffer01::test21_GrowFull02_Begin1
void test21_GrowFull02_Begin1()
Definition: test_lfringbuffer01.cpp:515
TestRingbuffer01::test04_FullReadReset
void test04_FullReadReset()
Definition: test_lfringbuffer01.cpp:365
jau::ringbuffer::drop
bool drop(const Size_type count) noexcept
Drops.
Definition: ringbuffer.hpp:1112
catch2_ext.hpp
TestRingbuffer01::test25_GrowFull11_End1
void test25_GrowFull11_End1()
Definition: test_lfringbuffer01.cpp:527
REQUIRE_MSG
#define REQUIRE_MSG(MSG,...)
Definition: catch2_ext.hpp:58
TestRingbuffer01::test20_GrowFull01_Begin
void test20_GrowFull01_Begin()
Definition: test_lfringbuffer01.cpp:512
jau::ringbuffer::recapacity
void recapacity(const Size_type newCapacity)
Resizes this ring buffer's capacity.
Definition: ringbuffer.hpp:1222
TrivialType
uint8_t TrivialType
Definition: test_lfringbuffer01.cpp:39