--- a/test/test_list.cpp Wed Jan 25 19:19:29 2023 +0100 +++ b/test/test_list.cpp Thu Jan 26 20:59:36 2023 +0100 @@ -573,6 +573,14 @@ return list; } + auto pointerLinkedListFromTestData() const -> CxList * { + auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int *))); + cxListStorePointers(list); + // note: cannot use cxListAddArray() because we don't have a list of pointers + cx_for_n(i, testdata_len) cxListAdd(list, &testdata.data[i]); + return list; + } + auto arrayListFromTestData() const -> CxList * { auto list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), testdata_len)); cxListAddArray(list, testdata.data.data(), testdata_len); @@ -625,21 +633,37 @@ EXPECT_EQ(*(int *) cxListAt(list, 3), 42); } - static void verifyInsertArray(CxList *list) { + static void verifyInsertArray( + CxList *list, + bool pointers = false + ) { int a[5] = {5, 47, 11, 13, 42}; int b[5] = {9, 18, 72, 50, 7}; + int *aptr[5]; + int *bptr[5]; + cx_for_n(i, 5) { + aptr[i] = &a[i]; + bptr[i] = &b[i]; + } size_t inserted; - inserted = cxListInsertArray(list, 0, a, 5); + if (pointers) { + inserted = cxListInsertArray(list, 0, aptr, 5); + } else { + inserted = cxListInsertArray(list, 0, a, 5); + } EXPECT_EQ(inserted, 5); EXPECT_EQ(*(int *) cxListAt(list, 0), 5); EXPECT_EQ(*(int *) cxListAt(list, 1), 47); EXPECT_EQ(*(int *) cxListAt(list, 2), 11); EXPECT_EQ(*(int *) cxListAt(list, 3), 13); EXPECT_EQ(*(int *) cxListAt(list, 4), 42); - - inserted = cxListInsertArray(list, 3, b, 5); + if (pointers) { + inserted = cxListInsertArray(list, 3, bptr, 5); + } else { + inserted = cxListInsertArray(list, 3, b, 5); + } EXPECT_EQ(inserted, 5); EXPECT_EQ(*(int *) cxListAt(list, 0), 5); EXPECT_EQ(*(int *) cxListAt(list, 1), 47); @@ -787,9 +811,26 @@ class LinkedList : public HighLevelTest { }; +class PointerLinkedList : public HighLevelTest { +}; + class ArrayList : public HighLevelTest { }; +TEST_F(PointerLinkedList, cxListStorePointers) { + auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, 47)); + EXPECT_FALSE(cxListIsStoringPointers(list)); + cxListStorePointers(list); + EXPECT_EQ(list->itemsize, sizeof(void *)); + EXPECT_NE(list->cl, nullptr); + EXPECT_NE(list->climpl, nullptr); + EXPECT_TRUE(cxListIsStoringPointers(list)); + cxListStoreObjects(list); + EXPECT_NE(list->cl, nullptr); + EXPECT_EQ(list->climpl, nullptr); + EXPECT_FALSE(cxListIsStoringPointers(list)); +} + TEST_F(LinkedList, cxLinkedListCreate) { CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int))); ASSERT_NE(list, nullptr); @@ -807,12 +848,18 @@ } TEST_F(LinkedList, cxListAdd) { - CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int))); + auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int))); verifyAdd(list, false); } +TEST_F(PointerLinkedList, cxListAdd) { + auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int *))); + cxListStorePointers(list); + verifyAdd(list, true); +} + TEST_F(ArrayList, cxListAdd) { - CxList *list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 8)); + auto list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 8)); verifyAdd(list, false); } @@ -820,6 +867,12 @@ verifyInsert(autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int)))); } +TEST_F(PointerLinkedList, cxListInsert) { + auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int *))); + cxListStorePointers(list); + verifyInsert(list); +} + TEST_F(ArrayList, cxListInsert) { verifyInsert(autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 2))); } @@ -828,6 +881,12 @@ verifyInsertArray(autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int)))); } +TEST_F(PointerLinkedList, cxListInsertArray) { + auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int *))); + cxListStorePointers(list); + verifyInsertArray(list, true); +} + TEST_F(ArrayList, cxListInsertArray) { verifyInsertArray(autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 4))); } @@ -836,6 +895,10 @@ verifyRemove(linkedListFromTestData()); } +TEST_F(PointerLinkedList, cxListRemove) { + verifyRemove(pointerLinkedListFromTestData()); +} + TEST_F(ArrayList, cxListRemove) { verifyRemove(arrayListFromTestData()); } @@ -844,6 +907,10 @@ verifyAt(linkedListFromTestData()); } +TEST_F(PointerLinkedList, cxListAt) { + verifyAt(pointerLinkedListFromTestData()); +} + TEST_F(ArrayList, cxListAt) { verifyAt(arrayListFromTestData()); } @@ -852,6 +919,10 @@ verifyFind(linkedListFromTestData()); } +TEST_F(PointerLinkedList, cxListFind) { + verifyFind(pointerLinkedListFromTestData()); +} + TEST_F(ArrayList, cxListFind) { verifyFind(arrayListFromTestData()); } @@ -860,6 +931,10 @@ verifySort(linkedListFromTestData()); } +TEST_F(PointerLinkedList, cxListSort) { + verifySort(pointerLinkedListFromTestData()); +} + TEST_F(ArrayList, cxListSort) { verifySort(arrayListFromTestData()); } @@ -868,6 +943,10 @@ verifyIterator(linkedListFromTestData()); } +TEST_F(PointerLinkedList, Iterator) { + verifyIterator(pointerLinkedListFromTestData()); +} + TEST_F(ArrayList, Iterator) { verifyIterator(arrayListFromTestData()); } @@ -879,6 +958,15 @@ verifyInsertViaIterator(list); } +TEST_F(PointerLinkedList, InsertViaIterator) { + int fivenums[] = {0, 1, 2, 3, 4, 5}; + auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int *))); + cxListStorePointers(list); + // note: cannot use cxListAddArray() because we don't have a list of pointers + cx_for_n(i, 5) cxListAdd(list, &fivenums[i]); + verifyInsertViaIterator(list); +} + TEST_F(ArrayList, InsertViaIterator) { int fivenums[] = {0, 1, 2, 3, 4, 5}; CxList *list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 4)); @@ -890,6 +978,10 @@ verifyReverse(linkedListFromTestData()); } +TEST_F(PointerLinkedList, cxListReverse) { + verifyReverse(pointerLinkedListFromTestData()); +} + TEST_F(ArrayList, cxListReverse) { verifyReverse(arrayListFromTestData()); } @@ -900,20 +992,86 @@ verifyCompare(left, right); } +TEST_F(LinkedList, cxListCompareWithPtrList) { + auto left = linkedListFromTestData(); + auto right = pointerLinkedListFromTestData(); + verifyCompare(left, right); +} + TEST_F(LinkedList, cxListCompareWithArrayList) { auto left = linkedListFromTestData(); auto right = arrayListFromTestData(); verifyCompare(left, right); } +TEST_F(PointerLinkedList, cxListCompare) { + auto left = pointerLinkedListFromTestData(); + auto right = pointerLinkedListFromTestData(); + verifyCompare(left, right); +} + +TEST_F(PointerLinkedList, cxListCompareWithNormalList) { + auto left = pointerLinkedListFromTestData(); + auto right = linkedListFromTestData(); + verifyCompare(left, right); +} + +TEST_F(PointerLinkedList, cxListCompareWithArrayList) { + auto left = pointerLinkedListFromTestData(); + auto right = arrayListFromTestData(); + verifyCompare(left, right); +} + TEST_F(ArrayList, cxListCompare) { auto left = arrayListFromTestData(); auto right = arrayListFromTestData(); verifyCompare(left, right); } -TEST_F(ArrayList, cxListCompareWithLinkedList) { +TEST_F(ArrayList, cxListCompareWithPtrList) { + auto left = arrayListFromTestData(); + auto right = pointerLinkedListFromTestData(); + verifyCompare(left, right); +} + +TEST_F(ArrayList, cxListCompareWithNormalList) { auto left = arrayListFromTestData(); auto right = linkedListFromTestData(); verifyCompare(left, right); } + +TEST_F(PointerLinkedList, NoDestructor) { + void *item = cxMalloc(&testingAllocator, sizeof(int)); + auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int *)); + cxListStorePointers(list); + cxListAdd(list, item); + ASSERT_FALSE(testingAllocator.verify()); + cxListDestroy(list); + EXPECT_FALSE(testingAllocator.verify()); + cxFree(&testingAllocator, item); + EXPECT_TRUE(testingAllocator.verify()); +} + +TEST_F(PointerLinkedList, SimpleDestructor) { + int item = 0; + auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int *)); + cxListStorePointers(list); + list->content_destructor_type = CX_DESTRUCTOR_SIMPLE; + list->simple_destructor = [](void *elem) { *(int *) elem = 42; }; + cxListAdd(list, &item); + cxListDestroy(list); + EXPECT_EQ(item, 42); +} + +TEST_F(PointerLinkedList, AdvancedDestructor) { + void *item = cxMalloc(&testingAllocator, sizeof(int)); + auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int *)); + cxListStorePointers(list); + list->content_destructor_type = CX_DESTRUCTOR_ADVANCED; + list->advanced_destructor.data = &testingAllocator; + list->advanced_destructor.func = (cx_destructor_func2) cxFree; + cxListAdd(list, item); + ASSERT_FALSE(testingAllocator.verify()); + cxListDestroy(list); + EXPECT_TRUE(testingAllocator.verify()); +}