Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
test_lfringbuffer03.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 
39 
40 class Integer {
41  public:
42  IntegralType value;
43 
44  Integer(IntegralType v) : value(v) {}
45 
46  Integer(const Integer &o) noexcept = default;
47  Integer(Integer &&o) noexcept = default;
48  Integer& operator=(const Integer &o) noexcept = default;
49  Integer& operator=(Integer &&o) noexcept = default;
50 
51  operator IntegralType() const {
52  return value;
53  }
54  IntegralType intValue() const { return value; }
55  static Integer valueOf(const IntegralType i) { return Integer(i); }
56 };
57 
58 std::shared_ptr<Integer> NullInteger = nullptr;
59 
60 typedef std::shared_ptr<Integer> SharedType;
62 
63 // Test examples.
65  private:
66 
67  std::shared_ptr<SharedTypeRingbuffer> createEmpty(jau::nsize_t initialCapacity) {
68  std::shared_ptr<SharedTypeRingbuffer> rb = std::shared_ptr<SharedTypeRingbuffer>(new SharedTypeRingbuffer(nullptr, initialCapacity));
69  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
70  return rb;
71  }
72  std::shared_ptr<SharedTypeRingbuffer> createFull(const std::vector<std::shared_ptr<Integer>> & source) {
73  std::shared_ptr<SharedTypeRingbuffer> rb = std::shared_ptr<SharedTypeRingbuffer>(new SharedTypeRingbuffer(nullptr, source));
74  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
75  return rb;
76  }
77 
78  std::vector<SharedType> createIntArray(const jau::nsize_t capacity, const IntegralType startValue) {
79  std::vector<SharedType> array(capacity);
80  for(jau::nsize_t i=0; i<capacity; i++) {
81  array[i] = SharedType(new Integer(startValue+i));
82  }
83  return array;
84  }
85 
86  void readTestImpl(SharedTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
87  (void) clearRef;
88 
89  jau::nsize_t preSize = rb.getSize();
90  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
91  REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
92  REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
93  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
94 
95  for(jau::nsize_t i=0; i<len; i++) {
96  SharedType svI = rb.get();
97  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=nullptr);
98  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(startValue+i) == svI->intValue());
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  void readTestImpl2(SharedTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
106  (void) clearRef;
107 
108  jau::nsize_t preSize = rb.getSize();
109  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
110  REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
111  REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
112  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
113 
114  for(jau::nsize_t i=0; i<len; i++) {
115  SharedType svI;
116  REQUIRE_MSG("ringbuffer get", rb.get(svI));
117  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=nullptr);
118  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(startValue+i) == svI->intValue());
119  }
120 
121  REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.getSize());
122  REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.getFreeSlots()>= len);
123  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
124  }
125 
126  void readRangeTestImpl(SharedTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
127  (void) clearRef;
128 
129  jau::nsize_t preSize = rb.getSize();
130  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
131  REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
132  REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
133  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
134 
135  std::vector<SharedType> array(len);
136  REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) );
137 
138  REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.getSize());
139  REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.getFreeSlots()>= len);
140  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
141 
142  for(jau::nsize_t i=0; i<len; i++) {
143  SharedType svI = array[i];
144  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=nullptr);
145  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(startValue+i) == svI->intValue());
146  }
147  }
148 
149  void writeTestImpl(SharedTypeRingbuffer &rb, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
150  jau::nsize_t preSize = rb.getSize();
151 
152  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
153  REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
154  REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity);
155  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
156 
157  for(jau::nsize_t i=0; i<len; i++) {
158  std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString();
159  REQUIRE_MSG(m, rb.put( SharedType( new Integer(startValue+i) ) ) );
160  }
161 
162  REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.getSize());
163  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
164  }
165 
166  void writeRangeTestImpl(SharedTypeRingbuffer &rb, jau::nsize_t capacity, const std::vector<std::shared_ptr<Integer>> & data) {
167  jau::nsize_t preSize = rb.getSize();
168  jau::nsize_t postSize = preSize+data.size();
169 
170  REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
171  REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size());
172  REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity);
173  REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
174  REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size());
175  REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.getFreeSlots() >= data.size());
176 
177  REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) );
178 
179  REQUIRE_MSG("size "+rb.toString(), postSize == rb.getSize());
180  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
181  }
182 
183  void moveGetPutImpl(SharedTypeRingbuffer &rb, jau::nsize_t pos) {
184  REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
185  for(jau::nsize_t i=0; i<pos; i++) {
186  REQUIRE_MSG("moveFull.get "+rb.toString(), IntegralType(i) == rb.get()->intValue());
187  REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( SharedType( new Integer(i) ) ) );
188  }
189  }
190 
191  void movePutGetImpl(SharedTypeRingbuffer &rb, jau::nsize_t pos) {
192  REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull());
193  for(jau::nsize_t i=0; i<pos; i++) {
194  REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( SharedType( new Integer(600+i) ) ) );
195  REQUIRE_MSG("moveEmpty.get "+rb.toString(), IntegralType(600+i) == rb.get()->intValue());
196  }
197  }
198 
199  public:
200 
202  std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(11);
203 
204  std::string msg("Ringbuffer: uses_memcpy "+std::to_string(SharedTypeRingbuffer::uses_memcpy)+
206  ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename SharedTypeRingbuffer::value_type>::value)+
207  ", size "+std::to_string(sizeof(rb))+" bytes");
208  fprintf(stderr, "%s", msg.c_str());
209  REQUIRE_MSG("Ringbuffer<shared_ptr<T>> not using memcpy", !SharedTypeRingbuffer::uses_memcpy);
210  REQUIRE_MSG("Ringbuffer<shared_ptr<T>> not using memset", !SharedTypeRingbuffer::uses_memset);
211  }
212 
214  jau::nsize_t capacity = 11;
215  std::vector<SharedType> source = createIntArray(capacity, 0);
216  std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
217  INFO_STR("test01_FullRead: Created / "+ rb->toString());
218  REQUIRE_MSG("full size "+rb->toString(), capacity == rb->getSize());
219  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
220 
221  readTestImpl(*rb, true, capacity, capacity, 0);
222  INFO_STR("test01_FullRead: PostRead / " + rb->toString());
223  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
224  }
225 
227  jau::nsize_t capacity = 11;
228  std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
229  INFO( std::string("test02_EmptyWrite: Created / ") + rb->toString().c_str());
230  REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->getSize());
231  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
232 
233  writeTestImpl(*rb, capacity, capacity, 0);
234  INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb->toString().c_str());
235  REQUIRE_MSG("full size "+rb->toString(), capacity == rb->getSize());
236  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
237 
238  readTestImpl(*rb, true, capacity, capacity, 0);
239  INFO( std::string("test02_EmptyWrite: PostRead / ") + rb->toString().c_str());
240  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
241  }
242 
244  {
245  jau::nsize_t capacity = 11;
246  std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
247  INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str());
248  REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->getSize());
249  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
250 
251  /**
252  * Move R == W == 0
253  * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
254  */
255  std::vector<SharedType> new_data = createIntArray(capacity, 0);
256  writeRangeTestImpl(*rb, capacity, new_data);
257 
258  INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str());
259  REQUIRE_MSG("full size "+rb->toString(), capacity == rb->getSize());
260  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
261 
262  readRangeTestImpl(*rb, true, capacity, capacity, 0);
263  INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str());
264  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
265  }
266  {
267  jau::nsize_t capacity = 11;
268  std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
269  INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str());
270  REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->getSize());
271  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
272 
273  /**
274  * Move R == W == 3
275  * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
276  * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ]
277  */
278  SharedType dummy(new Integer(-1));
279  rb->put(dummy);
280  rb->put(dummy);
281  rb->put(dummy);
282  rb->drop(3);
283 
284  std::vector<SharedType> new_data = createIntArray(capacity, 0);
285  writeRangeTestImpl(*rb, capacity, new_data);
286 
287  INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str());
288  REQUIRE_MSG("full size "+rb->toString(), capacity == rb->getSize());
289  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
290 
291  readRangeTestImpl(*rb, true, capacity, capacity, 0);
292  INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str());
293  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
294  }
295  {
296  jau::nsize_t capacity = 11;
297  std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
298  INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str());
299  REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->getSize());
300  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
301 
302  /**
303  * Move R == 2, W == 4, size 2
304  * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
305  * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R
306  */
307  SharedType dummy(new Integer(-1));
308  rb->put(dummy); // w idx 0 -> 1
309  rb->put(dummy);
310  rb->put(dummy);
311  rb->put(dummy); // w idx 3 -> 4
312  rb->drop(2); // r idx 0 -> 2
313 
314  // left = 11 - 2
315  REQUIRE_MSG("size 2 "+rb->toString(), 2 == rb->getSize());
316  REQUIRE_MSG("available 11-2 "+rb->toString(), capacity-2 == rb->getFreeSlots());
317 
318  std::vector<SharedType> new_data = createIntArray(capacity-2, 0);
319  writeRangeTestImpl(*rb, capacity, new_data);
320  // writeTestImpl(*rb, capacity, capacity-2, 0);
321 
322  INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str());
323  REQUIRE_MSG("full size "+rb->toString(), capacity == rb->getSize());
324  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
325 
326  // take off 2 remaining dummies
327  rb->drop(2);
328  REQUIRE_MSG("size capacity-2 "+rb->toString(), capacity-2 == rb->getSize());
329 
330  readRangeTestImpl(*rb, true, capacity, capacity-2, 0);
331  // readTestImpl(*rb, true, capacity, capacity-2, 0);
332  INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str());
333  REQUIRE_MSG("size 0 "+rb->toString(), 0 == rb->getSize());
334  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
335  }
336  {
337  jau::nsize_t capacity = 11;
338  std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
339  INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str());
340  REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->getSize());
341  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
342 
343  /**
344  * Move R == 9, W == 1, size 3
345  * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
346  * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1
347  */
348  SharedType dummy(new Integer(-1));
349  for(int i=0; i<11; i++) { rb->put(dummy); } // fill all
350  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
351 
352  rb->drop(10); // pull
353  REQUIRE_MSG("size 1"+rb->toString(), 1 == rb->getSize());
354 
355  for(int i=0; i<2; i++) { rb->put(dummy); } // fill 2 more
356  REQUIRE_MSG("size 3"+rb->toString(), 3 == rb->getSize());
357 
358  // left = 11 - 3
359  REQUIRE_MSG("available 11-3 "+rb->toString(), capacity-3 == rb->getFreeSlots());
360 
361  std::vector<SharedType> new_data = createIntArray(capacity-3, 0);
362  writeRangeTestImpl(*rb, capacity, new_data);
363  // writeTestImpl(*rb, capacity, capacity-3, 0);
364 
365  INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str());
366  REQUIRE_MSG("full size "+rb->toString(), capacity == rb->getSize());
367  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
368 
369  // take off 3 remaining dummies
370  rb->drop(3); // pull
371  REQUIRE_MSG("size capacity-3 "+rb->toString(), capacity-3 == rb->getSize());
372 
373  readRangeTestImpl(*rb, true, capacity, capacity-3, 0);
374  // readTestImpl(*rb, true, capacity, capacity-3, 0);
375  INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str());
376  REQUIRE_MSG("size 0 "+rb->toString(), 0 == rb->getSize());
377  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
378  }
379  }
380 
382  jau::nsize_t capacity = 11;
383  std::vector<SharedType> source = createIntArray(capacity, 0);
384  std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
385  INFO_STR("test04_FullReadReset: Created / " + rb->toString());
386  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
387 
388  rb->reset(source);
389  INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb->toString());
390  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
391 
392  readTestImpl(*rb, false, capacity, capacity, 0);
393  INFO_STR("test04_FullReadReset: Post Read / " + rb->toString());
394  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
395 
396  rb->reset(source);
397  INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb->toString());
398  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
399 
400  readTestImpl2(*rb, false, capacity, capacity, 0);
401  INFO_STR("test04_FullReadReset: Post Read / " + rb->toString());
402  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
403  }
404 
406  jau::nsize_t capacity = 11;
407  std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
408  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
409 
410  rb->clear();
411  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
412 
413  writeTestImpl(*rb, capacity, capacity, 0);
414  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
415 
416  readTestImpl(*rb, false, capacity, capacity, 0);
417  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
418 
419  rb->clear();
420  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
421 
422  writeTestImpl(*rb, capacity, capacity, 0);
423  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
424 
425  readTestImpl2(*rb, false, capacity, capacity, 0);
426  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
427  }
428 
430  jau::nsize_t capacity = 11;
431  std::vector<SharedType> source = createIntArray(capacity, 0);
432  std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
433  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
434 
435  rb->reset(source);
436  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
437 
438  readTestImpl(*rb, false, capacity, 5, 0);
439  REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty());
440  REQUIRE_MSG("not Full "+rb->toString(), !rb->isFull());
441 
442  rb->reset(source);
443  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
444 
445  readTestImpl(*rb, false, capacity, capacity, 0);
446  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
447  }
448 
450  jau::nsize_t capacity = 11;
451  std::vector<SharedType> source = createIntArray(capacity, 0);
452  std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
453  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
454 
455  rb->reset(source);
456  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
457 
458  moveGetPutImpl(*rb, 5);
459  readTestImpl(*rb, false, capacity, 5, 5);
460  REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty());
461  REQUIRE_MSG("not Full "+rb->toString(), !rb->isFull());
462 
463  rb->reset(source);
464  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
465 
466  readTestImpl(*rb, false, capacity, capacity, 0);
467  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
468  }
469 
470  private:
471 
472  void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) {
473  jau::nsize_t growAmount = 5;
474  jau::nsize_t grownCapacity = initialCapacity+growAmount;
475  std::vector<SharedType> source = createIntArray(initialCapacity, 0);
476  std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
477 
478  for(jau::nsize_t i=0; i<initialCapacity; i++) {
479  SharedType svI = rb->get();
480  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), svI!=nullptr);
481  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType((0+i)%initialCapacity) == svI->intValue());
482  }
483  REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->getSize());
484 
485  rb->reset(source);
486  REQUIRE_MSG("orig size "+rb->toString(), initialCapacity == rb->getSize());
487 
488  moveGetPutImpl(*rb, pos);
489  // PRINTM("X02 "+rb->toString());
490  // rb->dump(stderr, "X02");
491 
492  rb->recapacity(grownCapacity);
493  REQUIRE_MSG("capacity "+rb->toString(), grownCapacity == rb->capacity());
494  REQUIRE_MSG("orig size "+rb->toString(), initialCapacity == rb->getSize());
495  REQUIRE_MSG("not full "+rb->toString(), !rb->isFull());
496  REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty());
497  // PRINTM("X03 "+rb->toString());
498  // rb->dump(stderr, "X03");
499 
500  for(jau::nsize_t i=0; i<growAmount; i++) {
501  REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb->toString(), rb->put( SharedType( new Integer(100+i) ) ) );
502  }
503  REQUIRE_MSG("new size "+rb->toString(), grownCapacity == rb->getSize());
504  REQUIRE_MSG("full "+rb->toString(), rb->isFull());
505 
506  for(jau::nsize_t i=0; i<initialCapacity; i++) {
507  SharedType svI = rb->get();
508  // PRINTM("X05["+std::to_string(i)+"]: "+rb->toString()+", svI-null: "+std::to_string(svI==nullptr));
509  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), svI!=nullptr);
510  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType((pos+i)%initialCapacity) == svI->intValue());
511  }
512 
513  for(jau::nsize_t i=0; i<growAmount; i++) {
514  SharedType svI = rb->get();
515  // PRINTM("X07["+std::to_string(i)+"]: "+rb->toString()+", svI-null: "+std::to_string(svI==nullptr));
516  REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), svI!=nullptr);
517  REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType(100+i) == svI->intValue());
518  }
519 
520  REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->getSize());
521  REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
522 
523  REQUIRE_MSG("not full "+rb->toString(), !rb->isFull());
524  }
525 
526  public:
527 
529  test_GrowFullImpl(11, 0);
530  }
532  test_GrowFullImpl(11, 0+1);
533  }
535  test_GrowFullImpl(11, 0+2);
536  }
538  test_GrowFullImpl(11, 0+3);
539  }
541  test_GrowFullImpl(11, 11-1);
542  }
544  test_GrowFullImpl(11, 11-1-1);
545  }
547  test_GrowFullImpl(11, 11-1-2);
548  }
550  test_GrowFullImpl(11, 11-1-3);
551  }
552 
553 };
554 
jau::ringbuffer::getFreeSlots
Size_type getFreeSlots() const noexcept
Returns the number of free slots available to put.
Definition: ringbuffer.hpp:935
SharedTypeRingbuffer
ringbuffer< SharedType, std::nullptr_t, jau::nsize_t > SharedTypeRingbuffer
Definition: test_lfringbuffer03.cpp:61
jau::ringbuffer::put
bool put(Value_type &&e) noexcept
Enqueues the given element by moving it into this ringbuffer storage.
Definition: ringbuffer.hpp:1140
TestRingbuffer03::test22_GrowFull03_Begin2
void test22_GrowFull03_Begin2()
Definition: test_lfringbuffer03.cpp:534
TestRingbuffer03::test26_GrowFull12_End2
void test26_GrowFull12_End2()
Definition: test_lfringbuffer03.cpp:546
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
SharedType
std::shared_ptr< Integer > SharedType
Definition: test_lfringbuffer03.cpp:60
jau::ringbuffer::isEmpty
bool isEmpty() const noexcept
Returns true if this ring buffer is empty, otherwise false.
Definition: ringbuffer.hpp:938
Integer::operator=
Integer & operator=(const Integer &o) noexcept=default
TestRingbuffer03::test25_GrowFull11_End1
void test25_GrowFull11_End1()
Definition: test_lfringbuffer03.cpp:543
IntegralType
uint8_t IntegralType
Definition: test_lfringbuffer01.cpp:38
Integer::Integer
Integer(Integer &&o) noexcept=default
jau::ringbuffer::clear
void clear() noexcept
Releasing all elements by assigning nullelem.
Definition: ringbuffer.hpp:900
jau
Definition: basic_algos.hpp:34
TestRingbuffer03::test27_GrowFull13_End3
void test27_GrowFull13_End3()
Definition: test_lfringbuffer03.cpp:549
jau::ringbuffer::isFull
bool isFull() const noexcept
Returns true if this ring buffer is full, otherwise false.
Definition: ringbuffer.hpp:941
TestRingbuffer03::test00_PrintInfo
void test00_PrintInfo()
Definition: test_lfringbuffer03.cpp:201
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
TestRingbuffer03::test05_EmptyWriteClear
void test05_EmptyWriteClear()
Definition: test_lfringbuffer03.cpp:405
TestRingbuffer03
Definition: test_lfringbuffer03.cpp:64
INFO_STR
#define INFO_STR(msg)
Definition: catch2_ext.hpp:59
Integer::operator=
Integer & operator=(Integer &&o) noexcept=default
jau::ringbuffer::uses_memcpy
constexpr static const bool uses_memcpy
Definition: ringbuffer.hpp:117
NullInteger
std::shared_ptr< Integer > NullInteger
Definition: test_lfringbuffer03.cpp:58
TestRingbuffer03::test21_GrowFull02_Begin1
void test21_GrowFull02_Begin1()
Definition: test_lfringbuffer03.cpp:531
Integer
Definition: test_lfringbuffer02.cpp:40
TestRingbuffer03::test24_GrowFull05_End
void test24_GrowFull05_End()
Definition: test_lfringbuffer03.cpp:540
TestRingbuffer03::test04_FullReadReset
void test04_FullReadReset()
Definition: test_lfringbuffer03.cpp:381
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
TestRingbuffer03::test02_EmptyWrite
void test02_EmptyWrite()
Definition: test_lfringbuffer03.cpp:226
IntegralType
jau::snsize_t IntegralType
Definition: test_lfringbuffer03.cpp:38
TestRingbuffer03::test06_ReadResetMid01
void test06_ReadResetMid01()
Definition: test_lfringbuffer03.cpp:429
TestRingbuffer03::test01_FullRead
void test01_FullRead()
Definition: test_lfringbuffer03.cpp:213
Integer::Integer
Integer(const Integer &o) noexcept=default
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::snsize_t
int_fast32_t snsize_t
Natural 'ssize_t' alternative using int_fast32_t as its natural sized type.
Definition: int_types.hpp:56
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
Integer::intValue
IntegralType intValue() const
Definition: test_lfringbuffer03.cpp:54
Integer::valueOf
static Integer valueOf(const IntegralType i)
Definition: test_lfringbuffer03.cpp:55
TestRingbuffer03::test03_EmptyWriteRange
void test03_EmptyWriteRange()
Definition: test_lfringbuffer03.cpp:243
jau::ringbuffer::drop
bool drop(const Size_type count) noexcept
Drops.
Definition: ringbuffer.hpp:1112
catch2_ext.hpp
Integer::Integer
Integer(IntegralType v)
Definition: test_lfringbuffer03.cpp:44
REQUIRE_MSG
#define REQUIRE_MSG(MSG,...)
Definition: catch2_ext.hpp:58
TestRingbuffer03::test07_ReadResetMid02
void test07_ReadResetMid02()
Definition: test_lfringbuffer03.cpp:449
METHOD_AS_TEST_CASE
METHOD_AS_TEST_CASE(TestRingbuffer03::test00_PrintInfo, "Test TestRingbuffer 03- 00")
jau::ringbuffer::recapacity
void recapacity(const Size_type newCapacity)
Resizes this ring buffer's capacity.
Definition: ringbuffer.hpp:1222
TestRingbuffer03::test23_GrowFull04_Begin3
void test23_GrowFull04_Begin3()
Definition: test_lfringbuffer03.cpp:537
TestRingbuffer03::test20_GrowFull01_Begin
void test20_GrowFull01_Begin()
Definition: test_lfringbuffer03.cpp:528