diff --git a/cogl/cogl/cogl-bitmask.c b/cogl/cogl/cogl-bitmask.c index 754c66fa8..0c40ccf07 100644 --- a/cogl/cogl/cogl-bitmask.c +++ b/cogl/cogl/cogl-bitmask.c @@ -36,8 +36,6 @@ #include #include -#include - #include "cogl-bitmask.h" #include "cogl-util.h" #include "cogl-flags.h" @@ -319,171 +317,3 @@ _cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask, return pop + _cogl_util_popcountl (top_mask & ((1UL << bit_index) - 1)); } } - -typedef struct -{ - int n_bits; - int *bits; -} CheckData; - -static gboolean -check_bit (int bit_num, void *user_data) -{ - CheckData *data = user_data; - int i; - - for (i = 0; i < data->n_bits; i++) - if (data->bits[i] == bit_num) - { - data->bits[i] = -1; - return TRUE; - } - - g_assert_not_reached (); - - return TRUE; -} - -static void -verify_bits (const CoglBitmask *bitmask, - ...) -{ - CheckData data; - va_list ap, ap_copy; - int i; - - va_start (ap, bitmask); - G_VA_COPY (ap_copy, ap); - - for (data.n_bits = 0; va_arg (ap, int) != -1; data.n_bits++); - - data.bits = alloca (data.n_bits * (sizeof (int))); - - G_VA_COPY (ap, ap_copy); - - for (i = 0; i < data.n_bits; i++) - data.bits[i] = va_arg (ap, int); - - _cogl_bitmask_foreach (bitmask, check_bit, &data); - - for (i = 0; i < data.n_bits; i++) - g_assert_cmpint (data.bits[i], ==, -1); - - g_assert_cmpint (_cogl_bitmask_popcount (bitmask), ==, data.n_bits); - - for (i = 0; i < 1024; i++) - { - int upto_popcount = 0; - int j; - - G_VA_COPY (ap, ap_copy); - - for (j = 0; j < data.n_bits; j++) - if (va_arg (ap, int) < i) - upto_popcount++; - - g_assert_cmpint (_cogl_bitmask_popcount_upto (bitmask, i), - ==, - upto_popcount); - - G_VA_COPY (ap, ap_copy); - - for (j = 0; j < data.n_bits; j++) - if (va_arg (ap, int) == i) - break; - - g_assert_cmpint (_cogl_bitmask_get (bitmask, i), ==, (j < data.n_bits)); - } -} - -UNIT_TEST (check_bitmask_api, - 0 /* no requirements */, - 0 /* no failure cases */) -{ - CoglBitmask bitmask; - CoglBitmask other_bitmask; - /* A dummy bit to make it use arrays sometimes */ - int dummy_bit; - int i; - - for (dummy_bit = -1; dummy_bit < 256; dummy_bit += 40) - { - _cogl_bitmask_init (&bitmask); - _cogl_bitmask_init (&other_bitmask); - - if (dummy_bit != -1) - _cogl_bitmask_set (&bitmask, dummy_bit, TRUE); - - verify_bits (&bitmask, dummy_bit, -1); - - _cogl_bitmask_set (&bitmask, 1, TRUE); - _cogl_bitmask_set (&bitmask, 4, TRUE); - _cogl_bitmask_set (&bitmask, 5, TRUE); - - verify_bits (&bitmask, 1, 4, 5, dummy_bit, -1); - - _cogl_bitmask_set (&bitmask, 4, FALSE); - - verify_bits (&bitmask, 1, 5, dummy_bit, -1); - - _cogl_bitmask_clear_all (&bitmask); - - verify_bits (&bitmask, -1); - - if (dummy_bit != -1) - _cogl_bitmask_set (&bitmask, dummy_bit, TRUE); - - verify_bits (&bitmask, dummy_bit, -1); - - _cogl_bitmask_set (&bitmask, 1, TRUE); - _cogl_bitmask_set (&bitmask, 4, TRUE); - _cogl_bitmask_set (&bitmask, 5, TRUE); - _cogl_bitmask_set (&other_bitmask, 5, TRUE); - _cogl_bitmask_set (&other_bitmask, 6, TRUE); - - _cogl_bitmask_set_bits (&bitmask, &other_bitmask); - - verify_bits (&bitmask, 1, 4, 5, 6, dummy_bit, -1); - verify_bits (&other_bitmask, 5, 6, -1); - - _cogl_bitmask_set (&bitmask, 6, FALSE); - - verify_bits (&bitmask, 1, 4, 5, dummy_bit, -1); - - _cogl_bitmask_xor_bits (&bitmask, &other_bitmask); - - verify_bits (&bitmask, 1, 4, 6, dummy_bit, -1); - verify_bits (&other_bitmask, 5, 6, -1); - - _cogl_bitmask_set_range (&bitmask, 5, TRUE); - - verify_bits (&bitmask, 0, 1, 2, 3, 4, 6, dummy_bit, -1); - - _cogl_bitmask_set_range (&bitmask, 4, FALSE); - - verify_bits (&bitmask, 4, 6, dummy_bit, -1); - - _cogl_bitmask_destroy (&other_bitmask); - _cogl_bitmask_destroy (&bitmask); - } - - /* Extra tests for really long bitmasks */ - _cogl_bitmask_init (&bitmask); - _cogl_bitmask_set_range (&bitmask, 400, TRUE); - _cogl_bitmask_init (&other_bitmask); - _cogl_bitmask_set (&other_bitmask, 5, TRUE); - _cogl_bitmask_xor_bits (&bitmask, &other_bitmask); - - for (i = 0; i < 1024; i++) - g_assert_cmpint (_cogl_bitmask_get (&bitmask, i), - ==, - (i == 5 ? FALSE : - i < 400 ? TRUE : - FALSE)); - - _cogl_bitmask_set_range (&other_bitmask, 500, TRUE); - _cogl_bitmask_set_bits (&bitmask, &other_bitmask); - - for (i = 0; i < 1024; i++) - g_assert_cmpint (_cogl_bitmask_get (&bitmask, i), ==, (i < 500)); -} diff --git a/cogl/cogl/cogl-bitmask.h b/cogl/cogl/cogl-bitmask.h index 7d73db0db..31a57152c 100644 --- a/cogl/cogl/cogl-bitmask.h +++ b/cogl/cogl/cogl-bitmask.h @@ -90,31 +90,31 @@ typedef struct _CoglBitmaskImaginaryType *CoglBitmask; #define _cogl_bitmask_init(bitmask) \ G_STMT_START { *(bitmask) = _cogl_bitmask_from_bits (0); } G_STMT_END -gboolean +COGL_EXPORT_TEST gboolean _cogl_bitmask_get_from_array (const CoglBitmask *bitmask, unsigned int bit_num); -void +COGL_EXPORT_TEST void _cogl_bitmask_set_in_array (CoglBitmask *bitmask, unsigned int bit_num, gboolean value); -void +COGL_EXPORT_TEST void _cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, unsigned int n_bits, gboolean value); -void +COGL_EXPORT_TEST void _cogl_bitmask_clear_all_in_array (CoglBitmask *bitmask); void _cogl_bitmask_set_flags_array (const CoglBitmask *bitmask, unsigned long *flags); -int +COGL_EXPORT_TEST int _cogl_bitmask_popcount_in_array (const CoglBitmask *bitmask); -int +COGL_EXPORT_TEST int _cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask, int upto); @@ -126,7 +126,7 @@ _cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask, * This makes sure that all of the bits that are set in @src are also * set in @dst. Any unset bits in @src are left alone in @dst. */ -void +COGL_EXPORT_TEST void _cogl_bitmask_set_bits (CoglBitmask *dst, const CoglBitmask *src); @@ -138,7 +138,7 @@ _cogl_bitmask_set_bits (CoglBitmask *dst, * For every bit that is set in src, the corresponding bit in dst is * inverted. */ -void +COGL_EXPORT_TEST void _cogl_bitmask_xor_bits (CoglBitmask *dst, const CoglBitmask *src); @@ -153,7 +153,7 @@ typedef gboolean (* CoglBitmaskForeachFunc) (int bit_num, void *user_data); * * This calls @func for each bit that is set in @bitmask. */ -void +COGL_EXPORT_TEST void _cogl_bitmask_foreach (const CoglBitmask *bitmask, CoglBitmaskForeachFunc func, void *user_data); diff --git a/src/tests/cogl/unit/meson.build b/src/tests/cogl/unit/meson.build index c4c4f3359..021a5d16e 100644 --- a/src/tests/cogl/unit/meson.build +++ b/src/tests/cogl/unit/meson.build @@ -1,4 +1,5 @@ cogl_unit_tests = [ + 'test-bitmask', ] test_env = environment() diff --git a/src/tests/cogl/unit/test-bitmask.c b/src/tests/cogl/unit/test-bitmask.c new file mode 100644 index 000000000..368d2deb4 --- /dev/null +++ b/src/tests/cogl/unit/test-bitmask.c @@ -0,0 +1,181 @@ +#include "cogl-config.h" + +#include "cogl/cogl-bitmask.h" +#include "tests/cogl-test-utils.h" + +typedef struct +{ + int n_bits; + int *bits; +} CheckData; + +static gboolean +check_bit (int bit_num, void *user_data) +{ + CheckData *data = user_data; + int i; + + for (i = 0; i < data->n_bits; i++) + { + if (data->bits[i] == bit_num) + { + data->bits[i] = -1; + return TRUE; + } + } + + g_assert_not_reached (); + + return TRUE; +} + +static void +verify_bits (const CoglBitmask *bitmask, + ...) +{ + CheckData data; + va_list ap, ap_copy; + int i; + + va_start (ap, bitmask); + G_VA_COPY (ap_copy, ap); + + for (data.n_bits = 0; va_arg (ap, int) != -1; data.n_bits++); + + data.bits = alloca (data.n_bits * (sizeof (int))); + + G_VA_COPY (ap, ap_copy); + + for (i = 0; i < data.n_bits; i++) + data.bits[i] = va_arg (ap, int); + + _cogl_bitmask_foreach (bitmask, check_bit, &data); + + for (i = 0; i < data.n_bits; i++) + g_assert_cmpint (data.bits[i], ==, -1); + + g_assert_cmpint (_cogl_bitmask_popcount (bitmask), ==, data.n_bits); + + for (i = 0; i < 1024; i++) + { + int upto_popcount = 0; + int j; + + G_VA_COPY (ap, ap_copy); + + for (j = 0; j < data.n_bits; j++) + if (va_arg (ap, int) < i) + upto_popcount++; + + g_assert_cmpint (_cogl_bitmask_popcount_upto (bitmask, i), + ==, + upto_popcount); + + G_VA_COPY (ap, ap_copy); + + for (j = 0; j < data.n_bits; j++) + { + if (va_arg (ap, int) == i) + break; + } + + g_assert_cmpint (_cogl_bitmask_get (bitmask, i), ==, (j < data.n_bits)); + } +} + +static void +check_bitmask_api (void) +{ + CoglBitmask bitmask; + CoglBitmask other_bitmask; + /* A dummy bit to make it use arrays sometimes */ + int dummy_bit; + int i; + + for (dummy_bit = -1; dummy_bit < 256; dummy_bit += 40) + { + _cogl_bitmask_init (&bitmask); + _cogl_bitmask_init (&other_bitmask); + + if (dummy_bit != -1) + _cogl_bitmask_set (&bitmask, dummy_bit, TRUE); + + verify_bits (&bitmask, dummy_bit, -1); + + _cogl_bitmask_set (&bitmask, 1, TRUE); + _cogl_bitmask_set (&bitmask, 4, TRUE); + _cogl_bitmask_set (&bitmask, 5, TRUE); + + verify_bits (&bitmask, 1, 4, 5, dummy_bit, -1); + + _cogl_bitmask_set (&bitmask, 4, FALSE); + + verify_bits (&bitmask, 1, 5, dummy_bit, -1); + + _cogl_bitmask_clear_all (&bitmask); + + verify_bits (&bitmask, -1); + + if (dummy_bit != -1) + _cogl_bitmask_set (&bitmask, dummy_bit, TRUE); + + verify_bits (&bitmask, dummy_bit, -1); + + _cogl_bitmask_set (&bitmask, 1, TRUE); + _cogl_bitmask_set (&bitmask, 4, TRUE); + _cogl_bitmask_set (&bitmask, 5, TRUE); + _cogl_bitmask_set (&other_bitmask, 5, TRUE); + _cogl_bitmask_set (&other_bitmask, 6, TRUE); + + _cogl_bitmask_set_bits (&bitmask, &other_bitmask); + + verify_bits (&bitmask, 1, 4, 5, 6, dummy_bit, -1); + verify_bits (&other_bitmask, 5, 6, -1); + + _cogl_bitmask_set (&bitmask, 6, FALSE); + + verify_bits (&bitmask, 1, 4, 5, dummy_bit, -1); + + _cogl_bitmask_xor_bits (&bitmask, &other_bitmask); + + verify_bits (&bitmask, 1, 4, 6, dummy_bit, -1); + verify_bits (&other_bitmask, 5, 6, -1); + + _cogl_bitmask_set_range (&bitmask, 5, TRUE); + + verify_bits (&bitmask, 0, 1, 2, 3, 4, 6, dummy_bit, -1); + + _cogl_bitmask_set_range (&bitmask, 4, FALSE); + + verify_bits (&bitmask, 4, 6, dummy_bit, -1); + + _cogl_bitmask_destroy (&other_bitmask); + _cogl_bitmask_destroy (&bitmask); + } + + /* Extra tests for really long bitmasks */ + _cogl_bitmask_init (&bitmask); + _cogl_bitmask_set_range (&bitmask, 400, TRUE); + _cogl_bitmask_init (&other_bitmask); + _cogl_bitmask_set (&other_bitmask, 5, TRUE); + _cogl_bitmask_xor_bits (&bitmask, &other_bitmask); + + for (i = 0; i < 1024; i++) + { + g_assert_cmpint (_cogl_bitmask_get (&bitmask, i), + ==, + (i == 5 ? FALSE : + i < 400 ? TRUE : + FALSE)); + } + + _cogl_bitmask_set_range (&other_bitmask, 500, TRUE); + _cogl_bitmask_set_bits (&bitmask, &other_bitmask); + + for (i = 0; i < 1024; i++) + g_assert_cmpint (_cogl_bitmask_get (&bitmask, i), ==, (i < 500)); +} + +COGL_TEST_SUITE_MINIMAL ( + g_test_add_func ("/bitmask/api", check_bitmask_api); +)