UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "cx/test.h" 30 31 #include "cx/iterator.h" 32 33 CX_TEST(test_iterator_create) { 34 unsigned array[20]; 35 size_t size = cx_nmemb(array); 36 for (unsigned i = 0 ; i < size ; i++) array[i] = i; 37 38 CxIterator iter = cxIterator(array, sizeof(unsigned), size, true); 39 CX_TEST_DO { 40 CX_TEST_ASSERT(iter.index == 0); 41 CX_TEST_ASSERT(iter.elem_size == sizeof(unsigned)); 42 CX_TEST_ASSERT(iter.elem_count == size); 43 CX_TEST_ASSERT(iter.src_handle == array); 44 CX_TEST_ASSERT(iter.elem_handle == &array[0]); 45 CX_TEST_ASSERT(cxIteratorValid(iter)); 46 } 47 } 48 49 CX_TEST(test_iterator_create_null) { 50 CxIterator iter = cxIterator(NULL, sizeof(unsigned), 47, true); 51 CX_TEST_DO { 52 CX_TEST_ASSERT(iter.index == 0); 53 CX_TEST_ASSERT(iter.elem_size == sizeof(unsigned)); 54 CX_TEST_ASSERT(iter.elem_count == 0); 55 CX_TEST_ASSERT(iter.src_handle == NULL); 56 CX_TEST_ASSERT(iter.elem_handle == NULL); 57 CX_TEST_ASSERT(!cxIteratorValid(iter)); 58 } 59 } 60 61 CX_TEST(test_iterator_iterate) { 62 unsigned array[20]; 63 size_t size = cx_nmemb(array); 64 for (unsigned i = 0 ; i < size ; i++) array[i] = i; 65 66 CxIterator iter = cxIterator(array, sizeof(unsigned), size, true); 67 CX_TEST_DO { 68 CX_TEST_ASSERT(iter.elem_size == sizeof(unsigned)); 69 CX_TEST_ASSERT(iter.elem_count == size); 70 CX_TEST_ASSERT(iter.src_handle == array); 71 unsigned expected = 0; 72 cx_foreach(unsigned *, e, iter) { 73 CX_TEST_ASSERT(iter.index == expected); 74 CX_TEST_ASSERT(*e == expected); 75 CX_TEST_ASSERT(iter.elem_handle == &array[expected]); 76 expected++; 77 } 78 CX_TEST_ASSERT(expected == size); 79 } 80 } 81 82 CX_TEST(test_iterator_iterate_pointers) { 83 unsigned array[20]; 84 unsigned* ptr_array[20]; 85 size_t size = cx_nmemb(array); 86 for (unsigned i = 0 ; i < size ; i++) { 87 array[i] = 3*i; 88 ptr_array[i] = &array[i]; 89 } 90 91 CxIterator iter = cxIteratorPtr(ptr_array, size, true); 92 CX_TEST_DO { 93 CX_TEST_ASSERT(iter.elem_size == sizeof(void*)); 94 CX_TEST_ASSERT(iter.elem_count == size); 95 CX_TEST_ASSERT(iter.src_handle == ptr_array); 96 unsigned idx = 0; 97 cx_foreach(unsigned *, e, iter) { 98 CX_TEST_ASSERT(iter.index == idx); 99 CX_TEST_ASSERT(*e == array[idx]); 100 CX_TEST_ASSERT(iter.elem_handle == &ptr_array[idx]); 101 idx++; 102 } 103 CX_TEST_ASSERT(idx == size); 104 } 105 } 106 107 CX_TEST(test_iterator_with_slow_remove) { 108 unsigned array[20]; 109 size_t size = cx_nmemb(array); 110 for (unsigned i = 0 ; i < size ; i++) array[i] = i; 111 112 size_t elem_counts[] = { 113 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 114 15, 15, 14, 14, 13, 13, 12, 12, 11, 11 115 }; 116 size_t indices[] = { 117 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 118 6, 6, 7, 7, 8, 8, 9, 9, 10 119 }; 120 unsigned expected_result[] = { 121 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 122 }; 123 124 CxIterator iter = cxIterator(array, sizeof(unsigned), size, true); 125 CX_TEST_DO { 126 unsigned expected = 0; 127 cx_foreach(unsigned *, e, iter) { 128 CX_TEST_ASSERT(*e == expected); 129 CX_TEST_ASSERT(iter.index == indices[expected]); 130 CX_TEST_ASSERT(iter.elem_size == sizeof(unsigned)); 131 CX_TEST_ASSERT(iter.elem_count == elem_counts[expected]); 132 CX_TEST_ASSERT(iter.src_handle == array); 133 CX_TEST_ASSERT(iter.elem_handle == &array[indices[expected]]); 134 expected++; 135 if (expected % 2 == 0) { 136 cxIteratorFlagRemoval(iter); 137 } 138 } 139 CX_TEST_ASSERT(expected == 20); 140 CX_TEST_ASSERT(iter.index == 10); 141 CX_TEST_ASSERT(iter.elem_count == 10); 142 for (unsigned i = 0 ; i < 9 ; i++) { 143 CX_TEST_ASSERT(array[i] == expected_result[i]); 144 } 145 } 146 } 147 148 CX_TEST(test_iterator_with_fast_remove) { 149 unsigned array[20]; 150 size_t size = cx_nmemb(array); 151 for (unsigned i = 0 ; i < size ; i++) array[i] = i; 152 153 size_t elem_counts[] = { 154 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 155 15, 15, 14, 14, 13, 13, 12, 12, 11, 11 156 }; 157 size_t indices[] = { 158 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 159 6, 6, 7, 7, 8, 8, 9, 9, 10 160 }; 161 unsigned expected_result[] = { 162 0, 19, 18, 17, 16, 15, 14, 13, 12, 11 163 }; 164 unsigned expected_visits[] = { 165 0, 1, 19, 2, 18, 3, 17, 4, 16, 5, 166 15, 6, 14, 7, 13, 8, 12, 9, 11, 10 167 }; 168 169 CxIterator iter = cxIterator(array, sizeof(unsigned), size, false); 170 CX_TEST_DO { 171 unsigned expected = 0; 172 cx_foreach(unsigned *, e, iter) { 173 CX_TEST_ASSERT(*e == expected_visits[expected]); 174 CX_TEST_ASSERT(iter.index == indices[expected]); 175 CX_TEST_ASSERT(iter.elem_size == sizeof(unsigned)); 176 CX_TEST_ASSERT(iter.elem_count == elem_counts[expected]); 177 CX_TEST_ASSERT(iter.src_handle == array); 178 CX_TEST_ASSERT(iter.elem_handle == &array[indices[expected]]); 179 expected++; 180 if (expected % 2 == 0) { 181 cxIteratorFlagRemoval(iter); 182 } 183 } 184 CX_TEST_ASSERT(expected == 20); 185 CX_TEST_ASSERT(iter.index == 10); 186 CX_TEST_ASSERT(iter.elem_count == 10); 187 for (unsigned i = 0 ; i < 9 ; i++) { 188 CX_TEST_ASSERT(array[i] == expected_result[i]); 189 } 190 } 191 } 192 193 CxTestSuite *cx_test_suite_iterator(void) { 194 CxTestSuite *suite = cx_test_suite_new("iterator"); 195 196 cx_test_register(suite, test_iterator_create); 197 cx_test_register(suite, test_iterator_iterate); 198 cx_test_register(suite, test_iterator_iterate_pointers); 199 cx_test_register(suite, test_iterator_with_slow_remove); 200 cx_test_register(suite, test_iterator_with_fast_remove); 201 202 return suite; 203 } 204 205