summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2021-10-31 17:08:15 +0100
committerSven Gothel <[email protected]>2021-10-31 17:08:15 +0100
commita847f3b0d7ba4465bde0d91fe534c9c0562c225b (patch)
tree5f24647b94660afbb54e44422af6e338ddb5e5db
parent573160dcc8e77c738410b9006ca27d5611a2eff1 (diff)
test_lfringbuffer[00..04]: Unify non-threaded functional tests using template, testing multiple types and all parameter
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/test_lfringbuffer01.cpp565
-rw-r--r--test/test_lfringbuffer02.cpp587
-rw-r--r--test/test_lfringbuffer03.cpp564
-rw-r--r--test/test_lfringbuffer04.cpp118
-rw-r--r--test/test_lfringbuffer_a.hpp549
6 files changed, 876 insertions, 1508 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 0468605..0f9f137 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -27,6 +27,7 @@ set( SOURCES_IDIOMATIC_EXAMPLES
test_lfringbuffer01.cpp
test_lfringbuffer02.cpp
test_lfringbuffer03.cpp
+ test_lfringbuffer04.cpp
test_lfringbuffer11.cpp
test_lfringbuffer12.cpp
test_lfringbuffer13.cpp
diff --git a/test/test_lfringbuffer01.cpp b/test/test_lfringbuffer01.cpp
index 68aeaf2..7eb0b88 100644
--- a/test/test_lfringbuffer01.cpp
+++ b/test/test_lfringbuffer01.cpp
@@ -33,510 +33,85 @@
#include <jau/ringbuffer.hpp>
-using namespace jau;
-
-typedef uint8_t IntegralType;
-typedef uint8_t TrivialType;
-constexpr const TrivialType TrivialTypeNullElem(0xff);
-typedef ringbuffer<TrivialType, jau::nsize_t> TrivialTypeRingbuffer;
-
-// Test examples.
-class TestRingbuffer01 {
- private:
-
- TrivialTypeRingbuffer createEmpty(jau::nsize_t initialCapacity) {
- TrivialTypeRingbuffer rb(initialCapacity);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- return rb;
- }
- TrivialTypeRingbuffer createFull(const std::vector<TrivialType> & source) {
- TrivialTypeRingbuffer rb(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
- return rb;
- }
-
- std::vector<TrivialType> createIntArray(const jau::nsize_t capacity, const IntegralType startValue) {
- std::vector<TrivialType> array(capacity);
- for(jau::nsize_t i=0; i<capacity; i++) {
- array[i] = TrivialType(startValue+i);
- }
- return array;
- }
-
- void readTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- (void) clearRef;
-
- jau::nsize_t preSize = rb.size();
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
-
- for(jau::nsize_t i=0; i<len; i++) {
- TrivialType svI;
- REQUIRE_MSG("ringbuffer get", rb.get(svI));
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI);
- }
-
- REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size());
- REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- }
-
- void readRangeTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- (void) clearRef;
-
- jau::nsize_t preSize = rb.size();
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
-
- std::vector<TrivialType> array(len);
- REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) );
-
- REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size());
- REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
-
- for(jau::nsize_t i=0; i<len; i++) {
- TrivialType svI = array[i];
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI);
- }
- }
-
- void writeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- jau::nsize_t preSize = rb.size();
-
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
-
- for(jau::nsize_t i=0; i<len; i++) {
- std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString();
- REQUIRE_MSG(m, rb.put( TrivialType( startValue+i ) ) );
- }
-
- REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.size());
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- }
-
- void writeRangeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, const std::vector<TrivialType> & data) {
- jau::nsize_t preSize = rb.size();
- jau::nsize_t postSize = preSize+data.size();
-
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size());
- REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size());
- REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.freeSlots() >= data.size());
-
- REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) );
-
- REQUIRE_MSG("size "+rb.toString(), postSize == rb.size());
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- }
-
- void moveGetPutImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) {
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- for(jau::nsize_t i=0; i<pos; i++) {
- TrivialType svI;
- REQUIRE_MSG("moveFull.get "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("moveFull.get "+rb.toString(), (IntegralType)i == svI);
- REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( TrivialType( (IntegralType)i ) ) );
- }
- }
-
- void movePutGetImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) {
- REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull());
- for(jau::nsize_t i=0; i<pos; i++) {
- REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( TrivialType( 600+(IntegralType)i ) ) );
-
- TrivialType svI;
- REQUIRE_MSG("moveEmpty.get "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("moveEmpty.get "+rb.toString(), 600+(IntegralType)i == svI);
- }
- }
-
- public:
-
- void test00_PrintInfo() {
- TrivialTypeRingbuffer rb = createEmpty(11);
-
- std::string msg("Ringbuffer: uses_memcpy "+std::to_string(TrivialTypeRingbuffer::uses_memcpy)+
- ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename TrivialTypeRingbuffer::value_type>::value)+
- ", size "+std::to_string(sizeof(rb))+" bytes");
- fprintf(stderr, "%s\n", msg.c_str());
- fprintf(stderr, "%s\n", rb.get_info().c_str());
- REQUIRE_MSG("Ringbuffer<T> using memcpy", TrivialTypeRingbuffer::uses_memcpy);
- }
-
- void test01_FullRead() {
- jau::nsize_t capacity = 11;
- std::vector<TrivialType> source = createIntArray(capacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
- INFO_STR("test01_FullRead: Created / "+ rb.toString());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, true, capacity, capacity, 0);
- INFO_STR("test01_FullRead: PostRead / " + rb.toString());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test02_EmptyWrite() {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test02_EmptyWrite: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- writeTestImpl(rb, capacity, capacity, 0);
- INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, true, capacity, capacity, 0);
- INFO( std::string("test02_EmptyWrite: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("empty1 "+rb.toString(), rb.isEmpty());
- }
-
- void test03_EmptyWriteRange() {
- {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- /**
- * Move R == W == 0
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- */
- std::vector<TrivialType> new_data = createIntArray(capacity, 0);
- writeRangeTestImpl(rb, capacity, new_data);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readRangeTestImpl(rb, true, capacity, capacity, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
- {
- jau::nsize_t capacity = 11;
-
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- /**
- * Move R == W == 3
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ]
- */
- TrivialType dummy(TrivialTypeNullElem);
- rb.put(dummy);
- rb.put(dummy);
- rb.put(dummy);
- rb.drop(3);
-
- std::vector<TrivialType> new_data = createIntArray(capacity, 0);
- writeRangeTestImpl(rb, capacity, new_data);
- // writeTestImpl(rb, capacity, capacity, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readRangeTestImpl(rb, true, capacity, capacity, 0);
- // readTestImpl(rb, true, capacity, capacity, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
- {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- /**
- * Move R == 2, W == 4, size 2
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R
- */
- TrivialType dummy(TrivialTypeNullElem);
- rb.put(dummy); // w idx 0 -> 1
- rb.put(dummy);
- rb.put(dummy);
- rb.put(dummy); // w idx 3 -> 4
- rb.drop(2); // r idx 0 -> 2
+#include "test_lfringbuffer_a.hpp"
- // left = 11 - 2
- REQUIRE_MSG("size 2 "+rb.toString(), 2 == rb.size());
- REQUIRE_MSG("available 11-2 "+rb.toString(), capacity-2 == rb.freeSlots());
-
- std::vector<TrivialType> new_data = createIntArray(capacity-2, 0);
- writeRangeTestImpl(rb, capacity, new_data);
- // writeTestImpl(rb, capacity, capacity-2, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- // take off 2 remaining dummies
- rb.drop(2);
- REQUIRE_MSG("size capacity-2 "+rb.toString(), capacity-2 == rb.size());
-
- readRangeTestImpl(rb, true, capacity, capacity-2, 0);
- // readTestImpl(rb, true, capacity, capacity-2, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
- {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- /**
- * Move R == 9, W == 1, size 3
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1
- */
- TrivialType dummy(TrivialTypeNullElem);
- for(int i=0; i<11; i++) { rb.put(dummy); } // fill all
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- rb.drop(10); // pull
- REQUIRE_MSG("size 1"+rb.toString(), 1 == rb.size());
-
- for(int i=0; i<2; i++) { rb.put(dummy); } // fill 2 more
- REQUIRE_MSG("size 3"+rb.toString(), 3 == rb.size());
-
- // left = 11 - 3
- REQUIRE_MSG("available 11-3 "+rb.toString(), capacity-3 == rb.freeSlots());
-
- std::vector<TrivialType> new_data = createIntArray(capacity-3, 0);
- writeRangeTestImpl(rb, capacity, new_data);
- // writeTestImpl(rb, capacity, capacity-3, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- // take off 3 remaining dummies
- rb.drop(3); // pull
- REQUIRE_MSG("size capacity-3 "+rb.toString(), capacity-3 == rb.size());
-
- readRangeTestImpl(rb, true, capacity, capacity-3, 0);
- // readTestImpl(rb, true, capacity, capacity-3, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
- }
-
- void test04_FullReadReset() {
- jau::nsize_t capacity = 11;
- std::vector<TrivialType> source = createIntArray(capacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
- INFO_STR("test04_FullReadReset: Created / " + rb.toString());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- rb.reset(source);
- INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- INFO_STR("test04_FullReadReset: Post Read / " + rb.toString());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- rb.reset(source);
- INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- INFO_STR("test04_FullReadReset: Post Read / " + rb.toString());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test05_EmptyWriteClear() {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- rb.clear();
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- writeTestImpl(rb, capacity, capacity, 0);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- rb.clear();
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- writeTestImpl(rb, capacity, capacity, 0);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test06_ReadResetMid01() {
- jau::nsize_t capacity = 11;
- std::vector<TrivialType> source = createIntArray(capacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- rb.reset(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, 5, 0);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull());
-
- rb.reset(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test07_ReadResetMid02() {
- jau::nsize_t capacity = 11;
- std::vector<TrivialType> source = createIntArray(capacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- rb.reset(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- moveGetPutImpl(rb, 5);
- readTestImpl(rb, false, capacity, 5, 5);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull());
-
- rb.reset(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- private:
-
- void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) {
- jau::nsize_t growAmount = 5;
- jau::nsize_t grownCapacity = initialCapacity+growAmount;
- std::vector<TrivialType> source = createIntArray(initialCapacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
-
- for(jau::nsize_t i=0; i<initialCapacity; i++) {
- TrivialType svI;;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((0+i)%initialCapacity) == svI);
- }
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
-
- rb.reset(source);
- REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size());
-
- moveGetPutImpl(rb, pos);
- // PRINTM("X02 "+rb.toString());
- // rb.dump(stderr, "X02");
-
- rb.recapacity(grownCapacity);
- REQUIRE_MSG("capacity "+rb.toString(), grownCapacity == rb.capacity());
- REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size());
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- // PRINTM("X03 "+rb.toString());
- // rb.dump(stderr, "X03");
-
- for(jau::nsize_t i=0; i<growAmount; i++) {
- REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb.toString(), rb.put( TrivialType( 100+i ) ) );
- }
- REQUIRE_MSG("new size "+rb.toString(), grownCapacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+using namespace jau;
- for(jau::nsize_t i=0; i<initialCapacity; i++) {
- TrivialType svI;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((pos+i)%initialCapacity) == svI);
- }
+typedef uint8_t Integral_type;
+typedef uint8_t Value_type;
- for(jau::nsize_t i=0; i<growAmount; i++) {
- TrivialType svI;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(100+i) == svI);
- }
+template<>
+Value_type getDefault() { return (Value_type)0xff; }
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+template<>
+Value_type createValue(const Integral_type& v) { return v; }
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- }
+template<>
+Integral_type getValue(const Value_type& e) { return e; }
- public:
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ true /* exp_memmove */, true /* exp_memcpy */, false /* exp_secmem */> TestRingbuffer01a;
- void test20_GrowFull01_Begin() {
- test_GrowFullImpl(11, 0);
- }
- void test21_GrowFull02_Begin1() {
- test_GrowFullImpl(11, 0+1);
- }
- void test22_GrowFull03_Begin2() {
- test_GrowFullImpl(11, 0+2);
- }
- void test23_GrowFull04_Begin3() {
- test_GrowFullImpl(11, 0+3);
- }
- void test24_GrowFull05_End() {
- test_GrowFullImpl(11, 11-1);
- }
- void test25_GrowFull11_End1() {
- test_GrowFullImpl(11, 11-1-1);
- }
- void test26_GrowFull12_End2() {
- test_GrowFullImpl(11, 11-1-2);
- }
- void test27_GrowFull13_End3() {
- test_GrowFullImpl(11, 11-1-3);
- }
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ true /* exp_memmove */, true /* exp_memcpy */, true /* exp_secmem */,
+ true /* use_memmove */, true /* use_memcpy */, true /* use_secmem */> TestRingbuffer01b;
-};
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ false /* exp_memmove */, false /* exp_memcpy */, true /* exp_secmem */,
+ false /* use_memmove */, false /* use_memcpy */, true /* use_secmem */> TestRingbuffer01c;
#if 1
-METHOD_AS_TEST_CASE( TestRingbuffer01::test00_PrintInfo, "Test TestRingbuffer 01- 00");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test01_FullRead, "Test TestRingbuffer 01- 01");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test02_EmptyWrite, "Test TestRingbuffer 01- 02");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test03_EmptyWriteRange, "Test TestRingbuffer 01- 03");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test04_FullReadReset, "Test TestRingbuffer 01- 04");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test05_EmptyWriteClear, "Test TestRingbuffer 01- 05");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test06_ReadResetMid01, "Test TestRingbuffer 01- 06");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test07_ReadResetMid02, "Test TestRingbuffer 01- 07");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test20_GrowFull01_Begin, "Test TestRingbuffer 01- 20");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test21_GrowFull02_Begin1, "Test TestRingbuffer 01- 21");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test22_GrowFull03_Begin2, "Test TestRingbuffer 01- 22");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test23_GrowFull04_Begin3, "Test TestRingbuffer 01- 23");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test24_GrowFull05_End, "Test TestRingbuffer 01- 24");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test25_GrowFull11_End1, "Test TestRingbuffer 01- 25");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test26_GrowFull12_End2, "Test TestRingbuffer 01- 26");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test27_GrowFull13_End3, "Test TestRingbuffer 01- 27");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test00_PrintInfo, "Test TestRingbuffer 01a- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test01_FullRead, "Test TestRingbuffer 01a- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test02_EmptyWrite, "Test TestRingbuffer 01a- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test03_EmptyWriteRange, "Test TestRingbuffer 01a- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test04_FullReadReset, "Test TestRingbuffer 01a- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test05_EmptyWriteClear, "Test TestRingbuffer 01a- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test06_ReadResetMid01, "Test TestRingbuffer 01a- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test07_ReadResetMid02, "Test TestRingbuffer 01a- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test20_GrowFull01_Begin, "Test TestRingbuffer 01a- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test21_GrowFull02_Begin1, "Test TestRingbuffer 01a- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test22_GrowFull03_Begin2, "Test TestRingbuffer 01a- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test23_GrowFull04_Begin3, "Test TestRingbuffer 01a- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test24_GrowFull05_End, "Test TestRingbuffer 01a- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test25_GrowFull11_End1, "Test TestRingbuffer 01a- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test26_GrowFull12_End2, "Test TestRingbuffer 01a- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test27_GrowFull13_End3, "Test TestRingbuffer 01a- 27");
#else
-METHOD_AS_TEST_CASE( TestRingbuffer01::test00_PrintInfo, "Test TestRingbuffer 01- 00");
-METHOD_AS_TEST_CASE( TestRingbuffer01::test03_EmptyWriteRange, "Test TestRingbuffer 01- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test00_PrintInfo, "Test TestRingbuffer 01a- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer01a::test03_EmptyWriteRange, "Test TestRingbuffer 01a- 03");
#endif
+
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test00_PrintInfo, "Test TestRingbuffer 01b- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test01_FullRead, "Test TestRingbuffer 01b- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test02_EmptyWrite, "Test TestRingbuffer 01b- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test03_EmptyWriteRange, "Test TestRingbuffer 01b- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test04_FullReadReset, "Test TestRingbuffer 01b- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test05_EmptyWriteClear, "Test TestRingbuffer 01b- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test06_ReadResetMid01, "Test TestRingbuffer 01b- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test07_ReadResetMid02, "Test TestRingbuffer 01b- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test20_GrowFull01_Begin, "Test TestRingbuffer 01b- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test21_GrowFull02_Begin1, "Test TestRingbuffer 01b- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test22_GrowFull03_Begin2, "Test TestRingbuffer 01b- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test23_GrowFull04_Begin3, "Test TestRingbuffer 01b- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test24_GrowFull05_End, "Test TestRingbuffer 01b- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test25_GrowFull11_End1, "Test TestRingbuffer 01b- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test26_GrowFull12_End2, "Test TestRingbuffer 01b- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer01b::test27_GrowFull13_End3, "Test TestRingbuffer 01b- 27");
+
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test00_PrintInfo, "Test TestRingbuffer 01c- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test01_FullRead, "Test TestRingbuffer 01c- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test02_EmptyWrite, "Test TestRingbuffer 01c- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test03_EmptyWriteRange, "Test TestRingbuffer 01c- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test04_FullReadReset, "Test TestRingbuffer 01c- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test05_EmptyWriteClear, "Test TestRingbuffer 01c- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test06_ReadResetMid01, "Test TestRingbuffer 01c- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test07_ReadResetMid02, "Test TestRingbuffer 01c- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test20_GrowFull01_Begin, "Test TestRingbuffer 01c- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test21_GrowFull02_Begin1, "Test TestRingbuffer 01c- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test22_GrowFull03_Begin2, "Test TestRingbuffer 01c- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test23_GrowFull04_Begin3, "Test TestRingbuffer 01c- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test24_GrowFull05_End, "Test TestRingbuffer 01c- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test25_GrowFull11_End1, "Test TestRingbuffer 01c- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test26_GrowFull12_End2, "Test TestRingbuffer 01c- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer01c::test27_GrowFull13_End3, "Test TestRingbuffer 01c- 27");
diff --git a/test/test_lfringbuffer02.cpp b/test/test_lfringbuffer02.cpp
index 35953e7..f9fccca 100644
--- a/test/test_lfringbuffer02.cpp
+++ b/test/test_lfringbuffer02.cpp
@@ -33,540 +33,105 @@
#include <jau/ringbuffer.hpp>
+#include "test_lfringbuffer_a.hpp"
+
using namespace jau;
-typedef jau::snsize_t IntegralType;
+typedef jau::snsize_t Integral_type;
class Integer {
public:
- IntegralType value;
+ Integral_type value;
- Integer(IntegralType v) : value(v) {}
+ Integer(Integral_type v) : value(v) {}
- Integer() noexcept : value(0) { }
+ Integer() noexcept : value(-1) { }
Integer(const Integer &o) noexcept = default;
Integer(Integer &&o) noexcept = default;
Integer& operator=(const Integer &o) noexcept = default;
Integer& operator=(Integer &&o) noexcept = default;
- operator IntegralType() const {
+ operator Integral_type() const {
return value;
}
- IntegralType intValue() const { return value; }
- static Integer valueOf(const IntegralType i) { return Integer(i); }
+ constexpr Integral_type getValue() const { return value; }
+ static Integer valueOf(const Integral_type i) { return Integer(i); }
};
+typedef Integer Value_type;
-typedef Integer TrivialType;
-static const TrivialType TrivialTypeNullElem(-1);
-typedef ringbuffer<TrivialType, jau::nsize_t> TrivialTypeRingbuffer;
-
-// Test examples.
-class TestRingbuffer02 {
- private:
-
- TrivialTypeRingbuffer createEmpty(jau::nsize_t initialCapacity) {
- TrivialTypeRingbuffer rb(initialCapacity);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- return rb;
- }
- TrivialTypeRingbuffer createFull(const std::vector<TrivialType> & source) {
- TrivialTypeRingbuffer rb(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
- return rb;
- }
-
- std::vector<TrivialType> createIntArray(const jau::nsize_t capacity, const IntegralType startValue) {
- std::vector<TrivialType> array(capacity);
- for(jau::nsize_t i=0; i<capacity; i++) {
- array[i] = TrivialType(startValue+i);
- }
- return array;
- }
-
- void readTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- (void) clearRef;
-
- jau::nsize_t preSize = rb.size();
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
-
- for(jau::nsize_t i=0; i<len; i++) {
- TrivialType svI;
- REQUIRE_MSG("ringbuffer get", rb.get(svI));
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI.intValue());
- }
-
- REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size());
- REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- }
-
- void readRangeTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- (void) clearRef;
-
- jau::nsize_t preSize = rb.size();
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
-
- std::vector<TrivialType> array(len);
- REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) );
-
- REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size());
- REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
-
- for(jau::nsize_t i=0; i<len; i++) {
- TrivialType svI = array[i];
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem);
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI.intValue());
- }
- }
-
- void writeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- jau::nsize_t preSize = rb.size();
-
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
-
- for(jau::nsize_t i=0; i<len; i++) {
- std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString();
- REQUIRE_MSG(m, rb.put( TrivialType( startValue+i ) ) );
- }
-
- REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.size());
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- }
-
- void writeRangeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, const std::vector<TrivialType> & data) {
- jau::nsize_t preSize = rb.size();
- jau::nsize_t postSize = preSize+data.size();
-
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size());
- REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size());
- REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.freeSlots() >= data.size());
-
- REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) );
-
- REQUIRE_MSG("size "+rb.toString(), postSize == rb.size());
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- }
-
- void moveGetPutImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) {
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- for(jau::nsize_t i=0; i<pos; i++) {
- TrivialType svI;
- REQUIRE_MSG("moveFull.get "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("moveFull.get "+rb.toString(), (IntegralType)i == svI.intValue());
- REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( TrivialType( (IntegralType)i ) ) );
- }
- }
-
- void movePutGetImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) {
- REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull());
- for(jau::nsize_t i=0; i<pos; i++) {
- REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( TrivialType( 600+(IntegralType)i ) ) );
- TrivialType svI;
- REQUIRE_MSG("moveEmpty.get "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("moveEmpty.get "+rb.toString(), 600+(IntegralType)i == svI.intValue());
- }
- }
-
- public:
-
- void test00_PrintInfo() {
- TrivialTypeRingbuffer rb = createEmpty(11);
-
- std::string msg("Ringbuffer: uses_memcpy "+std::to_string(TrivialTypeRingbuffer::uses_memcpy)+
- ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename TrivialTypeRingbuffer::value_type>::value)+
- ", size "+std::to_string(sizeof(rb))+" bytes");
- fprintf(stderr, "%s\n", msg.c_str());
- fprintf(stderr, "%s\n", rb.get_info().c_str());
- REQUIRE_MSG("Ringbuffer<T> using memcpy", TrivialTypeRingbuffer::uses_memcpy);
- }
-
- void test01_FullRead() {
- jau::nsize_t capacity = 11;
- std::vector<TrivialType> source = createIntArray(capacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
- INFO_STR("test01_FullRead: Created / "+ rb.toString());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, true, capacity, capacity, 0);
- INFO_STR("test01_FullRead: PostRead / " + rb.toString());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test02_EmptyWrite() {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test02_EmptyWrite: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- writeTestImpl(rb, capacity, capacity, 0);
- INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, true, capacity, capacity, 0);
- INFO( std::string("test02_EmptyWrite: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test03_EmptyWriteRange() {
-#if 1
- {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- /**
- * Move R == W == 0
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- */
- std::vector<TrivialType> new_data = createIntArray(capacity, 0);
- writeRangeTestImpl(rb, capacity, new_data);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readRangeTestImpl(rb, true, capacity, capacity, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-#endif
-#if 1
- {
- jau::nsize_t capacity = 11;
-
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- /**
- * Move R == W == 3
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ]
- */
- TrivialType dummy(TrivialTypeNullElem);
- rb.put(dummy);
- rb.put(dummy);
- rb.put(dummy);
- rb.drop(3);
-
- std::vector<TrivialType> new_data = createIntArray(capacity, 0);
- writeRangeTestImpl(rb, capacity, new_data);
- // writeTestImpl(rb, capacity, capacity, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readRangeTestImpl(rb, true, capacity, capacity, 0);
- // readTestImpl(rb, true, capacity, capacity, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-#endif
-#if 1
- {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- /**
- * Move R == 2, W == 4, size 2
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R
- */
- TrivialType dummy(TrivialTypeNullElem);
- rb.put(dummy); // r idx 0 -> 1
- rb.put(dummy);
- rb.put(dummy);
- rb.put(dummy); // r idx 3 -> 4
- rb.drop(2); // r idx 0 -> 2
+template<>
+Value_type getDefault() { return Integer(); }
- // left = 11 - 2
- REQUIRE_MSG("size 2 "+rb.toString(), 2 == rb.size());
- REQUIRE_MSG("available 11-2 "+rb.toString(), capacity-2 == rb.freeSlots());
+template<>
+Value_type createValue(const Integral_type& v) { return Integer(v); }
- std::vector<TrivialType> new_data = createIntArray(capacity-2, 0);
- writeRangeTestImpl(rb, capacity, new_data);
- // writeTestImpl(rb, capacity, capacity-2, 0);
+template<>
+Integral_type getValue(const Value_type& e) { return e.getValue(); }
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ true /* exp_memmove */, true /* exp_memcpy */, false /* exp_secmem */> TestRingbuffer02a;
- // take off 2 remaining dummies
- rb.drop(2);
- REQUIRE_MSG("size capacity-2 "+rb.toString(), capacity-2 == rb.size());
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ true /* exp_memmove */, true /* exp_memcpy */, true /* exp_secmem */,
+ true /* use_memmove */, true /* use_memcpy */, true /* use_secmem */> TestRingbuffer02b;
- readRangeTestImpl(rb, true, capacity, capacity-2, 0);
- // readTestImpl(rb, true, capacity, capacity-2, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-#endif
-#if 1
- {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- /**
- * Move R == 9, W == 1, size 3
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1
- */
- TrivialType dummy(TrivialTypeNullElem);
- for(int i=0; i<11; i++) { rb.put(dummy); } // fill all
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- // for(int i=0; i<10; i++) { rb.get(); } // pull
- rb.drop(10); // pull
- REQUIRE_MSG("size 1"+rb.toString(), 1 == rb.size());
-
- for(int i=0; i<2; i++) { rb.put(dummy); } // fill 2 more
- REQUIRE_MSG("size 3"+rb.toString(), 3 == rb.size());
-
- // left = 11 - 3
- REQUIRE_MSG("available 11-3 "+rb.toString(), capacity-3 == rb.freeSlots());
-
- std::vector<TrivialType> new_data = createIntArray(capacity-3, 0);
- writeRangeTestImpl(rb, capacity, new_data);
- // writeTestImpl(rb, capacity, capacity-3, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
- REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- // take off 3 remaining dummies
- rb.drop(3); // pull
- // for(int i=0; i<3; i++) { rb.get(); } // pull
- REQUIRE_MSG("size capacity-3 "+rb.toString(), capacity-3 == rb.size());
-
- readRangeTestImpl(rb, true, capacity, capacity-3, 0);
- // readTestImpl(rb, true, capacity, capacity-3, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str());
- REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-#endif
- }
-
- void test04_FullReadReset() {
- jau::nsize_t capacity = 11;
- std::vector<TrivialType> source = createIntArray(capacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
- INFO_STR("test04_FullReadReset: Created / " + rb.toString());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- rb.reset(source);
- INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- INFO_STR("test04_FullReadReset: Post Read / " + rb.toString());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- rb.reset(source);
- INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- INFO_STR("test04_FullReadReset: Post Read / " + rb.toString());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test05_EmptyWriteClear() {
- jau::nsize_t capacity = 11;
- TrivialTypeRingbuffer rb = createEmpty(capacity);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- rb.clear();
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- writeTestImpl(rb, capacity, capacity, 0);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- rb.clear();
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- writeTestImpl(rb, capacity, capacity, 0);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test06_ReadResetMid01() {
- jau::nsize_t capacity = 11;
- std::vector<TrivialType> source = createIntArray(capacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- rb.reset(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, 5, 0);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull());
-
- rb.reset(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- void test07_ReadResetMid02() {
- jau::nsize_t capacity = 11;
- std::vector<TrivialType> source = createIntArray(capacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- rb.reset(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- moveGetPutImpl(rb, 5);
- readTestImpl(rb, false, capacity, 5, 5);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull());
-
- rb.reset(source);
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- readTestImpl(rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
- }
-
- private:
-
- void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) {
- jau::nsize_t growAmount = 5;
- jau::nsize_t grownCapacity = initialCapacity+growAmount;
- std::vector<TrivialType> source = createIntArray(initialCapacity, 0);
- TrivialTypeRingbuffer rb = createFull(source);
-
- for(jau::nsize_t i=0; i<initialCapacity; i++) {
- TrivialType svI;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((0+i)%initialCapacity) == svI.intValue());
- }
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
-
- rb.reset(source);
- REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size());
-
- moveGetPutImpl(rb, pos);
- // PRINTM("X02 "+rb.toString());
- // rb.dump(stderr, "X02");
-
- rb.recapacity(grownCapacity);
- REQUIRE_MSG("capacity "+rb.toString(), grownCapacity == rb.capacity());
- REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size());
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- // PRINTM("X03 "+rb.toString());
- // rb.dump(stderr, "X03");
-
- for(jau::nsize_t i=0; i<growAmount; i++) {
- REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb.toString(), rb.put( TrivialType( 100+i ) ) );
- }
- REQUIRE_MSG("new size "+rb.toString(), grownCapacity == rb.size());
- REQUIRE_MSG("full "+rb.toString(), rb.isFull());
-
- for(jau::nsize_t i=0; i<initialCapacity; i++) {
- TrivialType svI;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((pos+i)%initialCapacity) == svI.intValue());
- }
-
- for(jau::nsize_t i=0; i<growAmount; i++) {
- TrivialType svI;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(100+i) == svI.intValue());
- }
-
- REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
- REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
-
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- }
-
- public:
-
- void test20_GrowFull01_Begin() {
- test_GrowFullImpl(11, 0);
- }
- void test21_GrowFull02_Begin1() {
- test_GrowFullImpl(11, 0+1);
- }
- void test22_GrowFull03_Begin2() {
- test_GrowFullImpl(11, 0+2);
- }
- void test23_GrowFull04_Begin3() {
- test_GrowFullImpl(11, 0+3);
- }
- void test24_GrowFull05_End() {
- test_GrowFullImpl(11, 11-1);
- }
- void test25_GrowFull11_End1() {
- test_GrowFullImpl(11, 11-1-1);
- }
- void test26_GrowFull12_End2() {
- test_GrowFullImpl(11, 11-1-2);
- }
- void test27_GrowFull13_End3() {
- test_GrowFullImpl(11, 11-1-3);
- }
-
-};
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ false /* exp_memmove */, false /* exp_memcpy */, true /* exp_secmem */,
+ false /* use_memmove */, false /* use_memcpy */, true /* use_secmem */> TestRingbuffer02c;
#if 1
-METHOD_AS_TEST_CASE( TestRingbuffer02::test00_PrintInfo, "Test TestRingbuffer 02- 00");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test01_FullRead, "Test TestRingbuffer 02- 01");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test02_EmptyWrite, "Test TestRingbuffer 02- 02");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test03_EmptyWriteRange, "Test TestRingbuffer 02- 03");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test04_FullReadReset, "Test TestRingbuffer 02- 04");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test05_EmptyWriteClear, "Test TestRingbuffer 02- 05");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test06_ReadResetMid01, "Test TestRingbuffer 02- 06");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test07_ReadResetMid02, "Test TestRingbuffer 02- 07");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test20_GrowFull01_Begin, "Test TestRingbuffer 02- 20");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test21_GrowFull02_Begin1, "Test TestRingbuffer 02- 21");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test22_GrowFull03_Begin2, "Test TestRingbuffer 02- 22");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test23_GrowFull04_Begin3, "Test TestRingbuffer 02- 23");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test24_GrowFull05_End, "Test TestRingbuffer 02- 24");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test25_GrowFull11_End1, "Test TestRingbuffer 02- 25");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test26_GrowFull12_End2, "Test TestRingbuffer 02- 26");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test27_GrowFull13_End3, "Test TestRingbuffer 02- 27");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test00_PrintInfo, "Test TestRingbuffer 02a- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test01_FullRead, "Test TestRingbuffer 02a- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test02_EmptyWrite, "Test TestRingbuffer 02a- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test03_EmptyWriteRange, "Test TestRingbuffer 02a- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test04_FullReadReset, "Test TestRingbuffer 02a- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test05_EmptyWriteClear, "Test TestRingbuffer 02a- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test06_ReadResetMid01, "Test TestRingbuffer 02a- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test07_ReadResetMid02, "Test TestRingbuffer 02a- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test20_GrowFull01_Begin, "Test TestRingbuffer 02a- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test21_GrowFull02_Begin1, "Test TestRingbuffer 02a- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test22_GrowFull03_Begin2, "Test TestRingbuffer 02a- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test23_GrowFull04_Begin3, "Test TestRingbuffer 02a- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test24_GrowFull05_End, "Test TestRingbuffer 02a- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test25_GrowFull11_End1, "Test TestRingbuffer 02a- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test26_GrowFull12_End2, "Test TestRingbuffer 02a- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test27_GrowFull13_End3, "Test TestRingbuffer 02a- 27");
#else
-METHOD_AS_TEST_CASE( TestRingbuffer02::test00_PrintInfo, "Test TestRingbuffer 02- 00");
-METHOD_AS_TEST_CASE( TestRingbuffer02::test03_EmptyWriteRange, "Test TestRingbuffer 02- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test00_PrintInfo, "Test TestRingbuffer 02a- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test03_EmptyWriteRange, "Test TestRingbuffer 02a- 03");
#endif
+
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test00_PrintInfo, "Test TestRingbuffer 02b- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test01_FullRead, "Test TestRingbuffer 02b- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test02_EmptyWrite, "Test TestRingbuffer 02b- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test03_EmptyWriteRange, "Test TestRingbuffer 02b- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test04_FullReadReset, "Test TestRingbuffer 02b- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test05_EmptyWriteClear, "Test TestRingbuffer 02b- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test06_ReadResetMid01, "Test TestRingbuffer 02b- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test07_ReadResetMid02, "Test TestRingbuffer 02b- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test20_GrowFull01_Begin, "Test TestRingbuffer 02b- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test21_GrowFull02_Begin1, "Test TestRingbuffer 02b- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test22_GrowFull03_Begin2, "Test TestRingbuffer 02b- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test23_GrowFull04_Begin3, "Test TestRingbuffer 02b- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test24_GrowFull05_End, "Test TestRingbuffer 02b- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test25_GrowFull11_End1, "Test TestRingbuffer 02b- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test26_GrowFull12_End2, "Test TestRingbuffer 02b- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test27_GrowFull13_End3, "Test TestRingbuffer 02b- 27");
+
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test00_PrintInfo, "Test TestRingbuffer 02c- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test01_FullRead, "Test TestRingbuffer 02c- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test02_EmptyWrite, "Test TestRingbuffer 02c- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test03_EmptyWriteRange, "Test TestRingbuffer 02c- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test04_FullReadReset, "Test TestRingbuffer 02c- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test05_EmptyWriteClear, "Test TestRingbuffer 02c- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test06_ReadResetMid01, "Test TestRingbuffer 02c- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test07_ReadResetMid02, "Test TestRingbuffer 02c- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test20_GrowFull01_Begin, "Test TestRingbuffer 02c- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test21_GrowFull02_Begin1, "Test TestRingbuffer 02c- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test22_GrowFull03_Begin2, "Test TestRingbuffer 02c- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test23_GrowFull04_Begin3, "Test TestRingbuffer 02c- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test24_GrowFull05_End, "Test TestRingbuffer 02c- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test25_GrowFull11_End1, "Test TestRingbuffer 02c- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test26_GrowFull12_End2, "Test TestRingbuffer 02c- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test27_GrowFull13_End3, "Test TestRingbuffer 02c- 27");
diff --git a/test/test_lfringbuffer03.cpp b/test/test_lfringbuffer03.cpp
index 5e6f7bc..7ca785e 100644
--- a/test/test_lfringbuffer03.cpp
+++ b/test/test_lfringbuffer03.cpp
@@ -33,520 +33,80 @@
#include <jau/ringbuffer.hpp>
+#include "test_lfringbuffer_a.hpp"
+
using namespace jau;
-typedef jau::snsize_t IntegralType;
+typedef jau::snsize_t Integral_type;
class Integer {
public:
- IntegralType value;
+ Integral_type value;
+
+ Integer(Integral_type v) : value(v) {}
- Integer(IntegralType v) : value(v) {}
+ Integer() noexcept : value(-1) { }
Integer(const Integer &o) noexcept = default;
Integer(Integer &&o) noexcept = default;
Integer& operator=(const Integer &o) noexcept = default;
Integer& operator=(Integer &&o) noexcept = default;
- operator IntegralType() const {
+ operator Integral_type() const {
return value;
}
- IntegralType intValue() const { return value; }
- static Integer valueOf(const IntegralType i) { return Integer(i); }
-};
-
-std::shared_ptr<Integer> NullInteger = nullptr;
-
-typedef std::shared_ptr<Integer> SharedType;
-typedef ringbuffer<SharedType, jau::nsize_t> SharedTypeRingbuffer;
-
-// Test examples.
-class TestRingbuffer03 {
- private:
-
- std::shared_ptr<SharedTypeRingbuffer> createEmpty(jau::nsize_t initialCapacity) {
- std::shared_ptr<SharedTypeRingbuffer> rb = std::shared_ptr<SharedTypeRingbuffer>(new SharedTypeRingbuffer(initialCapacity));
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- return rb;
- }
- std::shared_ptr<SharedTypeRingbuffer> createFull(const std::vector<std::shared_ptr<Integer>> & source) {
- std::shared_ptr<SharedTypeRingbuffer> rb = std::shared_ptr<SharedTypeRingbuffer>(new SharedTypeRingbuffer(source));
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
- return rb;
- }
-
- std::vector<SharedType> createIntArray(const jau::nsize_t capacity, const IntegralType startValue) {
- std::vector<SharedType> array(capacity);
- for(jau::nsize_t i=0; i<capacity; i++) {
- array[i] = SharedType(new Integer(startValue+i));
- }
- return array;
- }
-
- void readTestImpl(SharedTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- (void) clearRef;
-
- jau::nsize_t preSize = rb.size();
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
-
- for(jau::nsize_t i=0; i<len; i++) {
- SharedType svI;
- REQUIRE_MSG("ringbuffer get", rb.get(svI));
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=nullptr);
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(startValue+i) == svI->intValue());
- }
-
- REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size());
- REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- }
-
- void readRangeTestImpl(SharedTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- (void) clearRef;
-
- jau::nsize_t preSize = rb.size();
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
-
- std::vector<SharedType> array(len);
- REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) );
-
- REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size());
- REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
-
- for(jau::nsize_t i=0; i<len; i++) {
- SharedType svI = array[i];
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=nullptr);
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(startValue+i) == svI->intValue());
- }
- }
-
- void writeTestImpl(SharedTypeRingbuffer &rb, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) {
- jau::nsize_t preSize = rb.size();
-
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
- REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
-
- for(jau::nsize_t i=0; i<len; i++) {
- std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString();
- REQUIRE_MSG(m, rb.put( SharedType( new Integer(startValue+i) ) ) );
- }
-
- REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.size());
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- }
-
- void writeRangeTestImpl(SharedTypeRingbuffer &rb, jau::nsize_t capacity, const std::vector<std::shared_ptr<Integer>> & data) {
- jau::nsize_t preSize = rb.size();
- jau::nsize_t postSize = preSize+data.size();
-
- REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
- REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size());
- REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity);
- REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
- REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size());
- REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.freeSlots() >= data.size());
-
- REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) );
-
- REQUIRE_MSG("size "+rb.toString(), postSize == rb.size());
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- }
-
- void moveGetPutImpl(SharedTypeRingbuffer &rb, jau::nsize_t pos) {
- REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
- for(jau::nsize_t i=0; i<pos; i++) {
- SharedType svI;
- REQUIRE_MSG("moveFull.get "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("moveFull.get "+rb.toString(), IntegralType(i) == svI->intValue());
- REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( SharedType( new Integer(i) ) ) );
- }
- }
-
- void movePutGetImpl(SharedTypeRingbuffer &rb, jau::nsize_t pos) {
- REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull());
- for(jau::nsize_t i=0; i<pos; i++) {
- REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( SharedType( new Integer(600+i) ) ) );
- SharedType svI;
- REQUIRE_MSG("moveEmpty.get "+rb.toString(), rb.get(svI));
- REQUIRE_MSG("moveEmpty.get "+rb.toString(), IntegralType(600+i) == svI->intValue());
- }
- }
-
- public:
-
- void test00_PrintInfo() {
- std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(11);
-
- std::string msg("Ringbuffer: uses_memcpy "+std::to_string(SharedTypeRingbuffer::uses_memcpy)+
- ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename SharedTypeRingbuffer::value_type>::value)+
- ", size "+std::to_string(sizeof(*rb))+" bytes");
- fprintf(stderr, "%s\n", msg.c_str());
- fprintf(stderr, "%s\n", rb->get_info().c_str());
- REQUIRE_MSG("Ringbuffer<shared_ptr<T>> not using memcpy", !SharedTypeRingbuffer::uses_memcpy);
- }
-
- void test01_FullRead() {
- jau::nsize_t capacity = 11;
- std::vector<SharedType> source = createIntArray(capacity, 0);
- std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
- INFO_STR("test01_FullRead: Created / "+ rb->toString());
- REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, true, capacity, capacity, 0);
- INFO_STR("test01_FullRead: PostRead / " + rb->toString());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
-
- void test02_EmptyWrite() {
- jau::nsize_t capacity = 11;
- std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
- INFO( std::string("test02_EmptyWrite: Created / ") + rb->toString().c_str());
- REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- writeTestImpl(*rb, capacity, capacity, 0);
- INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb->toString().c_str());
- REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, true, capacity, capacity, 0);
- INFO( std::string("test02_EmptyWrite: PostRead / ") + rb->toString().c_str());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
-
- void test03_EmptyWriteRange() {
- {
- jau::nsize_t capacity = 11;
- std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str());
- REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- /**
- * Move R == W == 0
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- */
- std::vector<SharedType> new_data = createIntArray(capacity, 0);
- writeRangeTestImpl(*rb, capacity, new_data);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str());
- REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readRangeTestImpl(*rb, true, capacity, capacity, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
- {
- jau::nsize_t capacity = 11;
- std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str());
- REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- /**
- * Move R == W == 3
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ]
- */
- SharedType dummy(new Integer(-1));
- rb->put(dummy);
- rb->put(dummy);
- rb->put(dummy);
- rb->drop(3);
-
- std::vector<SharedType> new_data = createIntArray(capacity, 0);
- writeRangeTestImpl(*rb, capacity, new_data);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str());
- REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readRangeTestImpl(*rb, true, capacity, capacity, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
- {
- jau::nsize_t capacity = 11;
- std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str());
- REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- /**
- * Move R == 2, W == 4, size 2
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R
- */
- SharedType dummy(new Integer(-1));
- rb->put(dummy); // w idx 0 -> 1
- rb->put(dummy);
- rb->put(dummy);
- rb->put(dummy); // w idx 3 -> 4
- rb->drop(2); // r idx 0 -> 2
-
- // left = 11 - 2
- REQUIRE_MSG("size 2 "+rb->toString(), 2 == rb->size());
- REQUIRE_MSG("available 11-2 "+rb->toString(), capacity-2 == rb->freeSlots());
-
- std::vector<SharedType> new_data = createIntArray(capacity-2, 0);
- writeRangeTestImpl(*rb, capacity, new_data);
- // writeTestImpl(*rb, capacity, capacity-2, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str());
- REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- // take off 2 remaining dummies
- rb->drop(2);
- REQUIRE_MSG("size capacity-2 "+rb->toString(), capacity-2 == rb->size());
-
- readRangeTestImpl(*rb, true, capacity, capacity-2, 0);
- // readTestImpl(*rb, true, capacity, capacity-2, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str());
- REQUIRE_MSG("size 0 "+rb->toString(), 0 == rb->size());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
- {
- jau::nsize_t capacity = 11;
- std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
- INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str());
- REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- /**
- * Move R == 9, W == 1, size 3
- * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
- * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1
- */
- SharedType dummy(new Integer(-1));
- for(int i=0; i<11; i++) { rb->put(dummy); } // fill all
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- rb->drop(10); // pull
- REQUIRE_MSG("size 1"+rb->toString(), 1 == rb->size());
-
- for(int i=0; i<2; i++) { rb->put(dummy); } // fill 2 more
- REQUIRE_MSG("size 3"+rb->toString(), 3 == rb->size());
-
- // left = 11 - 3
- REQUIRE_MSG("available 11-3 "+rb->toString(), capacity-3 == rb->freeSlots());
-
- std::vector<SharedType> new_data = createIntArray(capacity-3, 0);
- writeRangeTestImpl(*rb, capacity, new_data);
- // writeTestImpl(*rb, capacity, capacity-3, 0);
-
- INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str());
- REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- // take off 3 remaining dummies
- rb->drop(3); // pull
- REQUIRE_MSG("size capacity-3 "+rb->toString(), capacity-3 == rb->size());
-
- readRangeTestImpl(*rb, true, capacity, capacity-3, 0);
- // readTestImpl(*rb, true, capacity, capacity-3, 0);
- INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str());
- REQUIRE_MSG("size 0 "+rb->toString(), 0 == rb->size());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
- }
-
- void test04_FullReadReset() {
- jau::nsize_t capacity = 11;
- std::vector<SharedType> source = createIntArray(capacity, 0);
- std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
- INFO_STR("test04_FullReadReset: Created / " + rb->toString());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- rb->reset(source);
- INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb->toString());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, false, capacity, capacity, 0);
- INFO_STR("test04_FullReadReset: Post Read / " + rb->toString());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- rb->reset(source);
- INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb->toString());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, false, capacity, capacity, 0);
- INFO_STR("test04_FullReadReset: Post Read / " + rb->toString());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
-
- void test05_EmptyWriteClear() {
- jau::nsize_t capacity = 11;
- std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity);
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- rb->clear();
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- writeTestImpl(*rb, capacity, capacity, 0);
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- rb->clear();
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- writeTestImpl(*rb, capacity, capacity, 0);
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
-
- void test06_ReadResetMid01() {
- jau::nsize_t capacity = 11;
- std::vector<SharedType> source = createIntArray(capacity, 0);
- std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- rb->reset(source);
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, false, capacity, 5, 0);
- REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty());
- REQUIRE_MSG("not Full "+rb->toString(), !rb->isFull());
-
- rb->reset(source);
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
-
- void test07_ReadResetMid02() {
- jau::nsize_t capacity = 11;
- std::vector<SharedType> source = createIntArray(capacity, 0);
- std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- rb->reset(source);
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- moveGetPutImpl(*rb, 5);
- readTestImpl(*rb, false, capacity, 5, 5);
- REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty());
- REQUIRE_MSG("not Full "+rb->toString(), !rb->isFull());
-
- rb->reset(source);
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- readTestImpl(*rb, false, capacity, capacity, 0);
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
- }
-
- private:
-
- void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) {
- jau::nsize_t growAmount = 5;
- jau::nsize_t grownCapacity = initialCapacity+growAmount;
- std::vector<SharedType> source = createIntArray(initialCapacity, 0);
- std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source);
-
- for(jau::nsize_t i=0; i<initialCapacity; i++) {
- SharedType svI;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), rb->get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType((0+i)%initialCapacity) == svI->intValue());
- }
- REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size());
-
- rb->reset(source);
- REQUIRE_MSG("orig size "+rb->toString(), initialCapacity == rb->size());
-
- moveGetPutImpl(*rb, pos);
- // PRINTM("X02 "+rb->toString());
- // rb->dump(stderr, "X02");
-
- rb->recapacity(grownCapacity);
- REQUIRE_MSG("capacity "+rb->toString(), grownCapacity == rb->capacity());
- REQUIRE_MSG("orig size "+rb->toString(), initialCapacity == rb->size());
- REQUIRE_MSG("not full "+rb->toString(), !rb->isFull());
- REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty());
- // PRINTM("X03 "+rb->toString());
- // rb->dump(stderr, "X03");
-
- for(jau::nsize_t i=0; i<growAmount; i++) {
- REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb->toString(), rb->put( SharedType( new Integer(100+i) ) ) );
- }
- REQUIRE_MSG("new size "+rb->toString(), grownCapacity == rb->size());
- REQUIRE_MSG("full "+rb->toString(), rb->isFull());
-
- for(jau::nsize_t i=0; i<initialCapacity; i++) {
- SharedType svI;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), rb->get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType((pos+i)%initialCapacity) == svI->intValue());
- }
-
- for(jau::nsize_t i=0; i<growAmount; i++) {
- SharedType svI;
- REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), rb->get(svI));
- REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType(100+i) == svI->intValue());
- }
-
- REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size());
- REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty());
-
- REQUIRE_MSG("not full "+rb->toString(), !rb->isFull());
- }
-
- public:
-
- void test20_GrowFull01_Begin() {
- test_GrowFullImpl(11, 0);
- }
- void test21_GrowFull02_Begin1() {
- test_GrowFullImpl(11, 0+1);
- }
- void test22_GrowFull03_Begin2() {
- test_GrowFullImpl(11, 0+2);
- }
- void test23_GrowFull04_Begin3() {
- test_GrowFullImpl(11, 0+3);
- }
- void test24_GrowFull05_End() {
- test_GrowFullImpl(11, 11-1);
- }
- void test25_GrowFull11_End1() {
- test_GrowFullImpl(11, 11-1-1);
- }
- void test26_GrowFull12_End2() {
- test_GrowFullImpl(11, 11-1-2);
- }
- void test27_GrowFull13_End3() {
- test_GrowFullImpl(11, 11-1-3);
- }
-
+ Integral_type getValue() const { return value; }
+ static Integer valueOf(const Integral_type i) { return Integer(i); }
};
-
-METHOD_AS_TEST_CASE( TestRingbuffer03::test00_PrintInfo, "Test TestRingbuffer 03- 00");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test01_FullRead, "Test TestRingbuffer 03- 01");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test02_EmptyWrite, "Test TestRingbuffer 03- 02");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test03_EmptyWriteRange, "Test TestRingbuffer 03- 03");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test04_FullReadReset, "Test TestRingbuffer 03- 04");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test05_EmptyWriteClear, "Test TestRingbuffer 03- 05");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test06_ReadResetMid01, "Test TestRingbuffer 03- 06");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test07_ReadResetMid02, "Test TestRingbuffer 03- 07");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test20_GrowFull01_Begin, "Test TestRingbuffer 03- 20");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test21_GrowFull02_Begin1, "Test TestRingbuffer 03- 21");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test22_GrowFull03_Begin2, "Test TestRingbuffer 03- 22");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test23_GrowFull04_Begin3, "Test TestRingbuffer 03- 23");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test24_GrowFull05_End, "Test TestRingbuffer 03- 24");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test25_GrowFull11_End1, "Test TestRingbuffer 03- 25");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test26_GrowFull12_End2, "Test TestRingbuffer 03- 26");
-METHOD_AS_TEST_CASE( TestRingbuffer03::test27_GrowFull13_End3, "Test TestRingbuffer 03- 27");
+typedef std::shared_ptr<Integer> Value_type;
+
+template<>
+Value_type getDefault() { return std::make_shared<Integer>(); }
+
+template<>
+Value_type createValue(const Integral_type& v) { return std::make_shared<Integer>(v); }
+
+template<>
+Integral_type getValue(const Value_type& e) { return e->getValue(); }
+
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ false /* exp_memmove */, false /* exp_memcpy */, false /* exp_secmem */> TestRingbuffer03a;
+
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ false /* exp_memmove */, false /* exp_memcpy */, true /* exp_secmem */,
+ false /* use_memmove */, false /* use_memcpy */, true /* use_secmem */> TestRingbuffer03b;
+
+
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test00_PrintInfo, "Test TestRingbuffer 03a- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test01_FullRead, "Test TestRingbuffer 03a- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test02_EmptyWrite, "Test TestRingbuffer 03a- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test03_EmptyWriteRange, "Test TestRingbuffer 03a- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test04_FullReadReset, "Test TestRingbuffer 03a- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test05_EmptyWriteClear, "Test TestRingbuffer 03a- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test06_ReadResetMid01, "Test TestRingbuffer 03a- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test07_ReadResetMid02, "Test TestRingbuffer 03a- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test20_GrowFull01_Begin, "Test TestRingbuffer 03a- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test21_GrowFull02_Begin1, "Test TestRingbuffer 03a- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test22_GrowFull03_Begin2, "Test TestRingbuffer 03a- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test23_GrowFull04_Begin3, "Test TestRingbuffer 03a- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test24_GrowFull05_End, "Test TestRingbuffer 03a- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test25_GrowFull11_End1, "Test TestRingbuffer 03a- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test26_GrowFull12_End2, "Test TestRingbuffer 03a- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer03a::test27_GrowFull13_End3, "Test TestRingbuffer 03a- 27");
+
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test00_PrintInfo, "Test TestRingbuffer 03b- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test01_FullRead, "Test TestRingbuffer 03b- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test02_EmptyWrite, "Test TestRingbuffer 03b- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test03_EmptyWriteRange, "Test TestRingbuffer 03b- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test04_FullReadReset, "Test TestRingbuffer 03b- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test05_EmptyWriteClear, "Test TestRingbuffer 03b- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test06_ReadResetMid01, "Test TestRingbuffer 03b- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test07_ReadResetMid02, "Test TestRingbuffer 03b- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test20_GrowFull01_Begin, "Test TestRingbuffer 03b- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test21_GrowFull02_Begin1, "Test TestRingbuffer 03b- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test22_GrowFull03_Begin2, "Test TestRingbuffer 03b- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test23_GrowFull04_Begin3, "Test TestRingbuffer 03b- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test24_GrowFull05_End, "Test TestRingbuffer 03b- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test25_GrowFull11_End1, "Test TestRingbuffer 03b- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test26_GrowFull12_End2, "Test TestRingbuffer 03b- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer03b::test27_GrowFull13_End3, "Test TestRingbuffer 03b- 27");
diff --git a/test/test_lfringbuffer04.cpp b/test/test_lfringbuffer04.cpp
new file mode 100644
index 0000000..61b1315
--- /dev/null
+++ b/test/test_lfringbuffer04.cpp
@@ -0,0 +1,118 @@
+/*
+ * Author: Sven Gothel <[email protected]>
+ * Copyright (c) 2020 Gothel Software e.K.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <iostream>
+#include <cassert>
+#include <cinttypes>
+#include <cstring>
+#include <memory>
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch_amalgamated.hpp>
+#include <jau/test/catch2_ext.hpp>
+
+#include <jau/ringbuffer.hpp>
+
+#include "test_lfringbuffer_a.hpp"
+
+using namespace jau;
+
+typedef jau::snsize_t Integral_type;
+
+typedef std::array<Integral_type, 6> Value_type;
+
+template<>
+Value_type getDefault() { return Value_type{-1, -1, -1, -1, -1, -1}; }
+
+template<>
+Value_type createValue(const Integral_type& v) { return Value_type{v, v+1, v+2, v+3, v+4, v+5}; }
+
+template<>
+Integral_type getValue(const Value_type& e) { return e[0]; }
+
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ true /* exp_memmove */, true /* exp_memcpy */, false /* exp_secmem */> TestRingbuffer02a;
+
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ true /* exp_memmove */, true /* exp_memcpy */, true /* exp_secmem */,
+ true /* use_memmove */, true /* use_memcpy */, true /* use_secmem */> TestRingbuffer02b;
+
+typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t,
+ false /* exp_memmove */, false /* exp_memcpy */, true /* exp_secmem */,
+ false /* use_memmove */, false /* use_memcpy */, true /* use_secmem */> TestRingbuffer02c;
+
+#if 1
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test00_PrintInfo, "Test TestRingbuffer 02a- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test01_FullRead, "Test TestRingbuffer 02a- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test02_EmptyWrite, "Test TestRingbuffer 02a- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test03_EmptyWriteRange, "Test TestRingbuffer 02a- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test04_FullReadReset, "Test TestRingbuffer 02a- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test05_EmptyWriteClear, "Test TestRingbuffer 02a- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test06_ReadResetMid01, "Test TestRingbuffer 02a- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test07_ReadResetMid02, "Test TestRingbuffer 02a- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test20_GrowFull01_Begin, "Test TestRingbuffer 02a- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test21_GrowFull02_Begin1, "Test TestRingbuffer 02a- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test22_GrowFull03_Begin2, "Test TestRingbuffer 02a- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test23_GrowFull04_Begin3, "Test TestRingbuffer 02a- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test24_GrowFull05_End, "Test TestRingbuffer 02a- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test25_GrowFull11_End1, "Test TestRingbuffer 02a- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test26_GrowFull12_End2, "Test TestRingbuffer 02a- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test27_GrowFull13_End3, "Test TestRingbuffer 02a- 27");
+#else
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test00_PrintInfo, "Test TestRingbuffer 02a- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer02a::test03_EmptyWriteRange, "Test TestRingbuffer 02a- 03");
+#endif
+
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test00_PrintInfo, "Test TestRingbuffer 02b- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test01_FullRead, "Test TestRingbuffer 02b- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test02_EmptyWrite, "Test TestRingbuffer 02b- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test03_EmptyWriteRange, "Test TestRingbuffer 02b- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test04_FullReadReset, "Test TestRingbuffer 02b- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test05_EmptyWriteClear, "Test TestRingbuffer 02b- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test06_ReadResetMid01, "Test TestRingbuffer 02b- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test07_ReadResetMid02, "Test TestRingbuffer 02b- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test20_GrowFull01_Begin, "Test TestRingbuffer 02b- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test21_GrowFull02_Begin1, "Test TestRingbuffer 02b- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test22_GrowFull03_Begin2, "Test TestRingbuffer 02b- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test23_GrowFull04_Begin3, "Test TestRingbuffer 02b- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test24_GrowFull05_End, "Test TestRingbuffer 02b- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test25_GrowFull11_End1, "Test TestRingbuffer 02b- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test26_GrowFull12_End2, "Test TestRingbuffer 02b- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer02b::test27_GrowFull13_End3, "Test TestRingbuffer 02b- 27");
+
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test00_PrintInfo, "Test TestRingbuffer 02c- 00");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test01_FullRead, "Test TestRingbuffer 02c- 01");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test02_EmptyWrite, "Test TestRingbuffer 02c- 02");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test03_EmptyWriteRange, "Test TestRingbuffer 02c- 03");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test04_FullReadReset, "Test TestRingbuffer 02c- 04");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test05_EmptyWriteClear, "Test TestRingbuffer 02c- 05");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test06_ReadResetMid01, "Test TestRingbuffer 02c- 06");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test07_ReadResetMid02, "Test TestRingbuffer 02c- 07");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test20_GrowFull01_Begin, "Test TestRingbuffer 02c- 20");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test21_GrowFull02_Begin1, "Test TestRingbuffer 02c- 21");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test22_GrowFull03_Begin2, "Test TestRingbuffer 02c- 22");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test23_GrowFull04_Begin3, "Test TestRingbuffer 02c- 23");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test24_GrowFull05_End, "Test TestRingbuffer 02c- 24");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test25_GrowFull11_End1, "Test TestRingbuffer 02c- 25");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test26_GrowFull12_End2, "Test TestRingbuffer 02c- 26");
+METHOD_AS_TEST_CASE( TestRingbuffer02c::test27_GrowFull13_End3, "Test TestRingbuffer 02c- 27");
diff --git a/test/test_lfringbuffer_a.hpp b/test/test_lfringbuffer_a.hpp
new file mode 100644
index 0000000..1d128b1
--- /dev/null
+++ b/test/test_lfringbuffer_a.hpp
@@ -0,0 +1,549 @@
+/*
+ * Author: Sven Gothel <[email protected]>
+ * Copyright (c) 2020 Gothel Software e.K.
+ * Copyright (c) 2021 Gothel Software e.K.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <iostream>
+#include <cassert>
+#include <cinttypes>
+#include <cstring>
+#include <memory>
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch_amalgamated.hpp>
+#include <jau/test/catch2_ext.hpp>
+
+#include <jau/ringbuffer.hpp>
+
+using namespace jau;
+
+template<typename Value_type>
+Value_type getDefault();
+
+template<typename Integral_type, typename Value_type>
+Value_type createValue(const Integral_type& v);
+
+template<typename Integral_type, typename Value_type>
+Integral_type getValue(const Value_type& e);
+
+template <typename Integral_type, typename Value_type, typename Size_type,
+ bool exp_memmove, bool exp_memcpy, bool exp_secmem,
+
+ bool use_memmove = std::is_trivially_copyable_v<Value_type> || is_container_memmove_compliant_v<Value_type>,
+ bool use_memcpy = std::is_trivially_copyable_v<Value_type>,
+ bool use_secmem = is_enforcing_secmem_v<Value_type>
+ >
+class TestRingbuffer_A {
+ public:
+ typedef ringbuffer<Value_type, Size_type, use_memmove, use_memcpy, use_secmem> ringbuffer_t;
+
+ private:
+
+ ringbuffer_t createEmpty(jau::nsize_t initialCapacity) {
+ ringbuffer_t rb(initialCapacity);
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ return rb;
+ }
+ ringbuffer_t createFull(const std::vector<Value_type> & source) {
+ ringbuffer_t rb(source);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+ return rb;
+ }
+
+ std::vector<Value_type> createIntArray(const jau::nsize_t capacity, const Integral_type startValue) {
+ std::vector<Value_type> array(capacity);
+ for(jau::nsize_t i=0; i<capacity; i++) {
+ array[i] = createValue<Integral_type, Value_type>( (Integral_type)( startValue+i ));
+ }
+ return array;
+ }
+
+ void readTestImpl(ringbuffer_t &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, Integral_type startValue) {
+ (void) clearRef;
+
+ jau::nsize_t preSize = rb.size();
+ REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
+ REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
+ REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+
+ for(jau::nsize_t i=0; i<len; i++) {
+ Value_type svI = getDefault<Value_type>();
+ REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
+ REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(Integral_type)i == getValue<Integral_type, Value_type>(svI));
+ }
+
+ REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size());
+ REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len);
+ REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
+ }
+
+ void readRangeTestImpl(ringbuffer_t &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, Integral_type startValue) {
+ (void) clearRef;
+
+ jau::nsize_t preSize = rb.size();
+ REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
+ REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
+ REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len);
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+
+ std::vector<Value_type> array(len);
+ REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) );
+
+ REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size());
+ REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len);
+ REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
+
+ for(jau::nsize_t i=0; i<len; i++) {
+ Value_type svI = array[i];
+ REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(Integral_type)i == getValue<Integral_type, Value_type>(svI));
+ }
+ }
+
+ void writeTestImpl(ringbuffer_t &rb, jau::nsize_t capacity, jau::nsize_t len, Integral_type startValue) {
+ jau::nsize_t preSize = rb.size();
+
+ REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
+ REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len);
+ REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity);
+ REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
+
+ for(jau::nsize_t i=0; i<len; i++) {
+ std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString();
+ REQUIRE_MSG(m, rb.put( createValue<Integral_type, Value_type>( (Integral_type)( startValue+i ) ) ) );
+ }
+
+ REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.size());
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+ }
+
+ void writeRangeTestImpl(ringbuffer_t &rb, jau::nsize_t capacity, const std::vector<Value_type> & data) {
+ jau::nsize_t preSize = rb.size();
+ jau::nsize_t postSize = preSize+data.size();
+
+ REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity());
+ REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size());
+ REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity);
+ REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
+ REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size());
+ REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.freeSlots() >= data.size());
+
+ REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) );
+
+ REQUIRE_MSG("size "+rb.toString(), postSize == rb.size());
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+ }
+
+ void moveGetPutImpl(ringbuffer_t &rb, jau::nsize_t pos) {
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+ for(jau::nsize_t i=0; i<pos; i++) {
+ Value_type svI = getDefault<Value_type>();
+ REQUIRE_MSG("moveFull.get "+rb.toString(), rb.get(svI));
+ REQUIRE_MSG("moveFull.get "+rb.toString(), (Integral_type)i == getValue<Integral_type, Value_type>(svI));
+ REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( createValue<Integral_type, Value_type>( (Integral_type)i ) ) );
+ }
+ }
+
+ void movePutGetImpl(ringbuffer_t &rb, jau::nsize_t pos) {
+ REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull());
+ for(jau::nsize_t i=0; i<pos; i++) {
+ REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( createValue<Integral_type, Value_type>( (Integral_type)( 600+i ) ) ) );
+ Value_type svI = getDefault<Value_type>();
+ REQUIRE_MSG("moveEmpty.get "+rb.toString(), rb.get(svI));
+ REQUIRE_MSG("moveEmpty.get "+rb.toString(), 600+(Integral_type)i == getValue<Integral_type, Value_type>(svI));
+ }
+ }
+
+ public:
+
+ void test00_PrintInfo() {
+ ringbuffer_t rb = createEmpty(11);
+
+ std::string msg("Ringbuffer: uses_memcpy "+std::to_string(ringbuffer_t::uses_memcpy)+
+ ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename ringbuffer_t::value_type>::value)+
+ ", size "+std::to_string(sizeof(rb))+" bytes");
+ fprintf(stderr, "%s\n", msg.c_str());
+ fprintf(stderr, "%s\n", rb.get_info().c_str());
+ REQUIRE_MSG("Ringbuffer<T> memmove", ringbuffer_t::uses_memmove == exp_memmove);
+ REQUIRE_MSG("Ringbuffer<T> memcpy", ringbuffer_t::uses_memcpy == exp_memcpy);
+ REQUIRE_MSG("Ringbuffer<T> secmem", ringbuffer_t::uses_secmem == exp_secmem);
+ }
+
+ void test01_FullRead() {
+ jau::nsize_t capacity = 11;
+ std::vector<Value_type> source = createIntArray(capacity, 0);
+ ringbuffer_t rb = createFull(source);
+ INFO_STR("test01_FullRead: Created / "+ rb.toString());
+ REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, true, capacity, capacity, 0);
+ INFO_STR("test01_FullRead: PostRead / " + rb.toString());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+
+ void test02_EmptyWrite() {
+ jau::nsize_t capacity = 11;
+ ringbuffer_t rb = createEmpty(capacity);
+ INFO( std::string("test02_EmptyWrite: Created / ") + rb.toString().c_str());
+ REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ writeTestImpl(rb, capacity, capacity, 0);
+ INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb.toString().c_str());
+ REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, true, capacity, capacity, 0);
+ INFO( std::string("test02_EmptyWrite: PostRead / ") + rb.toString().c_str());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+
+ void test03_EmptyWriteRange() {
+ {
+ jau::nsize_t capacity = 2*11;
+ ringbuffer_t rb = createEmpty(capacity);
+ INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
+ REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ /**
+ * Move R == W == 0
+ * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
+ */
+ std::vector<Value_type> new_data = createIntArray(capacity, 0);
+ writeRangeTestImpl(rb, capacity, new_data);
+
+ INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
+ REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readRangeTestImpl(rb, true, capacity, capacity/2, 0);
+ INFO( std::string("test03_EmptyWriteRange: PostRead-1 / ") + rb.toString().c_str());
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+
+ readRangeTestImpl(rb, true, capacity, capacity/2, capacity/2);
+ INFO( std::string("test03_EmptyWriteRange: PostRead-2 / ") + rb.toString().c_str());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+ {
+ jau::nsize_t capacity = 2*11;
+
+ ringbuffer_t rb = createEmpty(capacity);
+ INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
+ REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ /**
+ * Move R == W == 3
+ * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
+ * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ]
+ */
+ Value_type dummy;
+ rb.put(dummy);
+ rb.put(dummy);
+ rb.put(dummy);
+ rb.drop(3);
+
+ std::vector<Value_type> new_data = createIntArray(capacity, 0);
+ writeRangeTestImpl(rb, capacity, new_data);
+ // writeTestImpl(rb, capacity, capacity, 0);
+
+ INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
+ REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readRangeTestImpl(rb, true, capacity, capacity/2, 0);
+ INFO( std::string("test03_EmptyWriteRange: PostRead-1 / ") + rb.toString().c_str());
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+
+ readRangeTestImpl(rb, true, capacity, capacity/2, capacity/2);
+ INFO( std::string("test03_EmptyWriteRange: PostRead-2 / ") + rb.toString().c_str());
+ REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+ {
+ jau::nsize_t capacity = 2*11;
+ ringbuffer_t rb = createEmpty(capacity);
+ INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
+ REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ /**
+ * Move R == 2, W == 4, size 2
+ * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
+ * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R
+ */
+ Value_type dummy;
+ rb.put(dummy); // r idx 0 -> 1
+ rb.put(dummy);
+ rb.put(dummy);
+ rb.put(dummy); // r idx 3 -> 4
+ rb.drop(2); // r idx 0 -> 2
+
+ // left = 22 - 2
+ REQUIRE_MSG("size 2 "+rb.toString(), 2 == rb.size());
+ REQUIRE_MSG("available 11-2 "+rb.toString(), capacity-2 == rb.freeSlots());
+
+ std::vector<Value_type> new_data = createIntArray(capacity-2, 0);
+ writeRangeTestImpl(rb, capacity, new_data);
+ // writeTestImpl(rb, capacity, capacity-2, 0);
+
+ INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
+ REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ // take off 2 remaining dummies
+ rb.drop(2);
+ REQUIRE_MSG("size capacity-2 "+rb.toString(), capacity-2 == rb.size());
+
+ readRangeTestImpl(rb, true, capacity, capacity/2-2, 0);
+ INFO( std::string("test03_EmptyWriteRange: PostRead-1 / ") + rb.toString().c_str());
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+
+ readRangeTestImpl(rb, true, capacity, capacity/2, capacity/2-2);
+ INFO( std::string("test03_EmptyWriteRange: PostRead-2 / ") + rb.toString().c_str());
+ REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+ {
+ jau::nsize_t capacity = 2*11;
+ ringbuffer_t rb = createEmpty(capacity);
+ INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str());
+ REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ /**
+ * Move R == 9, W == 1, size 3
+ * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start
+ * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1
+ */
+ Value_type dummy;
+ for(jau::nsize_t i=0; i<capacity; i++) { rb.put(dummy); } // fill all
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ // for(int i=0; i<10; i++) { rb.get(); } // pull
+ rb.drop(capacity-1); // pull
+ REQUIRE_MSG("size 1"+rb.toString(), 1 == rb.size());
+
+ for(int i=0; i<2; i++) { rb.put(dummy); } // fill 2 more
+ REQUIRE_MSG("size 3"+rb.toString(), 3 == rb.size());
+
+ // left = 22 - 3
+ REQUIRE_MSG("available 22-3 "+rb.toString(), capacity-3 == rb.freeSlots());
+
+ std::vector<Value_type> new_data = createIntArray(capacity-3, 0);
+ writeRangeTestImpl(rb, capacity, new_data);
+ // writeTestImpl(rb, capacity, capacity-3, 0);
+
+ INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str());
+ REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ // take off 3 remaining dummies
+ rb.drop(3); // pull
+ // for(int i=0; i<3; i++) { rb.get(); } // pull
+ REQUIRE_MSG("size capacity-3 "+rb.toString(), capacity-3 == rb.size());
+
+ readRangeTestImpl(rb, true, capacity, capacity/2-3, 0);
+ INFO( std::string("test03_EmptyWriteRange: PostRead-1 / ") + rb.toString().c_str());
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+
+ readRangeTestImpl(rb, true, capacity, capacity/2, capacity/2-3);
+ INFO( std::string("test03_EmptyWriteRange: PostRead-2 / ") + rb.toString().c_str());
+ REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+ }
+
+ void test04_FullReadReset() {
+ jau::nsize_t capacity = 11;
+ std::vector<Value_type> source = createIntArray(capacity, 0);
+ ringbuffer_t rb = createFull(source);
+ INFO_STR("test04_FullReadReset: Created / " + rb.toString());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ rb.reset(source);
+ INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, false, capacity, capacity, 0);
+ INFO_STR("test04_FullReadReset: Post Read / " + rb.toString());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ rb.reset(source);
+ INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, false, capacity, capacity, 0);
+ INFO_STR("test04_FullReadReset: Post Read / " + rb.toString());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+
+ void test05_EmptyWriteClear() {
+ jau::nsize_t capacity = 11;
+ ringbuffer_t rb = createEmpty(capacity);
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ rb.clear();
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ writeTestImpl(rb, capacity, capacity, 0);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, false, capacity, capacity, 0);
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ rb.clear();
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ writeTestImpl(rb, capacity, capacity, 0);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, false, capacity, capacity, 0);
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+
+ void test06_ReadResetMid01() {
+ jau::nsize_t capacity = 11;
+ std::vector<Value_type> source = createIntArray(capacity, 0);
+ ringbuffer_t rb = createFull(source);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ rb.reset(source);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, false, capacity, 5, 0);
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+ REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull());
+
+ rb.reset(source);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, false, capacity, capacity, 0);
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+
+ void test07_ReadResetMid02() {
+ jau::nsize_t capacity = 11;
+ std::vector<Value_type> source = createIntArray(capacity, 0);
+ ringbuffer_t rb = createFull(source);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ rb.reset(source);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ moveGetPutImpl(rb, 5);
+ readTestImpl(rb, false, capacity, 5, 5);
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+ REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull());
+
+ rb.reset(source);
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ readTestImpl(rb, false, capacity, capacity, 0);
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+ }
+
+ private:
+
+ void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) {
+ jau::nsize_t growAmount = 5;
+ jau::nsize_t grownCapacity = initialCapacity+growAmount;
+ std::vector<Value_type> source = createIntArray(initialCapacity, 0);
+ ringbuffer_t rb = createFull(source);
+
+ for(jau::nsize_t i=0; i<initialCapacity; i++) {
+ Value_type svI = getDefault<Value_type>();
+ REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
+ REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), Integral_type((0+i)%initialCapacity) == getValue<Integral_type, Value_type>(svI));
+ }
+ REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
+
+ rb.reset(source);
+ REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size());
+
+ moveGetPutImpl(rb, pos);
+ // PRINTM("X02 "+rb.toString());
+ // rb.dump(stderr, "X02");
+
+ rb.recapacity(grownCapacity);
+ REQUIRE_MSG("capacity "+rb.toString(), grownCapacity == rb.capacity());
+ REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size());
+ REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
+ REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty());
+ // PRINTM("X03 "+rb.toString());
+ // rb.dump(stderr, "X03");
+
+ for(jau::nsize_t i=0; i<growAmount; i++) {
+ REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb.toString(), rb.put( createValue<Integral_type, Value_type>( (Integral_type)(100+i) ) ) );
+ }
+ REQUIRE_MSG("new size "+rb.toString(), grownCapacity == rb.size());
+ REQUIRE_MSG("full "+rb.toString(), rb.isFull());
+
+ for(jau::nsize_t i=0; i<initialCapacity; i++) {
+ Value_type svI = getDefault<Value_type>();
+ REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
+ REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), Integral_type((pos+i)%initialCapacity) == getValue<Integral_type, Value_type>(svI));
+ }
+
+ for(jau::nsize_t i=0; i<growAmount; i++) {
+ Value_type svI = getDefault<Value_type>();
+ REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI));
+ REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), Integral_type(100+i) == getValue<Integral_type, Value_type>(svI));
+ }
+
+ REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size());
+ REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty());
+
+ REQUIRE_MSG("not full "+rb.toString(), !rb.isFull());
+ }
+
+ public:
+
+ void test20_GrowFull01_Begin() {
+ test_GrowFullImpl(11, 0);
+ }
+ void test21_GrowFull02_Begin1() {
+ test_GrowFullImpl(11, 0+1);
+ }
+ void test22_GrowFull03_Begin2() {
+ test_GrowFullImpl(11, 0+2);
+ }
+ void test23_GrowFull04_Begin3() {
+ test_GrowFullImpl(11, 0+3);
+ }
+ void test24_GrowFull05_End() {
+ test_GrowFullImpl(11, 11-1);
+ }
+ void test25_GrowFull11_End1() {
+ test_GrowFullImpl(11, 11-1-1);
+ }
+ void test26_GrowFull12_End2() {
+ test_GrowFullImpl(11, 11-1-2);
+ }
+ void test27_GrowFull13_End3() {
+ test_GrowFullImpl(11, 11-1-3);
+ }
+
+};
+