1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
// basic unit tester for bitarray.h
#ifdef NDEBUG
#error this is not intended to be compiled with assertions off
#endif
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/bitarray.h>
// helper for basic construction and destruction, with nothing in-between
static void create_reset(size_t size) {
bitarray_t b = bitarray_new(size);
bitarray_reset(&b);
}
// basic creation of a small array
static void test_create_reset_small(void) { create_reset(10); }
// basic creation of a large array
static void test_create_reset_large(void) { create_reset(1023); }
// setting and unsetting of all bits
static void set_unset(size_t size) {
bitarray_t b = bitarray_new(size);
// set and unset each bit
for (size_t i = 0; i < size; ++i) {
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
bitarray_set(&b, i, true);
for (size_t j = 0; j < size; ++j)
assert(bitarray_get(b, j) == (i == j));
bitarray_set(&b, i, false);
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
}
// try the same in reverse
for (size_t i = size - 1;; --i) {
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
bitarray_set(&b, i, true);
for (size_t j = 0; j < size; ++j)
assert(bitarray_get(b, j) == (i == j));
bitarray_set(&b, i, false);
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
if (i == 0)
break;
}
// a different, arbitrary order of a few bits
static const size_t INDEX[] = {3, 1, 4, 42, 6, 7, 123};
for (size_t i = 0; i < sizeof(INDEX) / sizeof(INDEX[0]); ++i) {
if (INDEX[i] >= size)
continue;
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
bitarray_set(&b, INDEX[i], true);
for (size_t j = 0; j < size; ++j)
assert(bitarray_get(b, j) == (INDEX[i] == j));
bitarray_set(&b, INDEX[i], false);
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
}
bitarray_reset(&b);
}
// set/unset for a small array
static void test_set_unset_small(void) { set_unset(10); }
// set/unset for a large array
static void test_set_unset_large(void) { set_unset(1023); }
// using an 8-bit aligned array
static void test_set_unset_aligned(void) {
set_unset(8);
set_unset(16);
set_unset(64);
set_unset(1024);
set_unset(4096);
set_unset(8192);
}
// reusing an array
static void test_reuse(void) {
size_t size = 10;
bitarray_t b = bitarray_new(size);
// set and unset each bit
for (size_t i = 0; i < size; ++i) {
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
bitarray_set(&b, i, true);
for (size_t j = 0; j < size; ++j)
assert(bitarray_get(b, j) == (i == j));
bitarray_set(&b, i, false);
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
}
bitarray_reset(&b);
// reuse it with a different size
size = 1023;
b = bitarray_new(size);
// set and unset each bit
for (size_t i = 0; i < size; ++i) {
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
bitarray_set(&b, i, true);
for (size_t j = 0; j < size; ++j)
assert(bitarray_get(b, j) == (i == j));
bitarray_set(&b, i, false);
for (size_t j = 0; j < size; ++j)
assert(!bitarray_get(b, j));
}
bitarray_reset(&b);
}
// redundant write to a bit
static void double_set(size_t size, bool value) {
bitarray_t b = bitarray_new(size);
static const size_t index = 7;
assert(!bitarray_get(b, index));
bitarray_set(&b, index, value);
assert(bitarray_get(b, index) == value);
bitarray_set(&b, index, value);
assert(bitarray_get(b, index) == value);
bitarray_reset(&b);
}
// various versions of the above
static void test_double_set_small(void) { double_set(10, true); }
static void test_double_set_large(void) { double_set(1023, true); }
static void test_double_clear_small(void) { double_set(10, false); }
static void test_double_clear_large(void) { double_set(1023, false); }
int main(void) {
#define RUN(t) \
do { \
printf("running test_%s... ", #t); \
fflush(stdout); \
test_##t(); \
printf("OK\n"); \
} while (0)
RUN(create_reset_small);
RUN(create_reset_large);
RUN(set_unset_small);
RUN(set_unset_large);
RUN(set_unset_aligned);
RUN(reuse);
RUN(double_set_small);
RUN(double_set_large);
RUN(double_clear_small);
RUN(double_clear_large);
#undef RUN
return EXIT_SUCCESS;
}
|