diff options
author | Neil Roberts <neil@linux.intel.com> | 2011-11-02 13:41:32 +0000 |
---|---|---|
committer | Neil Roberts <neil@linux.intel.com> | 2011-11-16 16:32:00 +0000 |
commit | d70699157979cf19a5598f27fd071a8fd05f2840 (patch) | |
tree | 438831be105ab22462ec72119a7cea2d03365b98 | |
parent | dbc31b70cc790833d8926ebad3e03c2d236965ae (diff) | |
download | cogl-d70699157979cf19a5598f27fd071a8fd05f2840.tar.gz |
cogl-flags: Add some macros to help iterate the bits
This adds some macros to iterate over all the bits set in an array of
flags. The macros are a bit awkward because it tries to avoid using a
callback pointer so that the code is inlined.
cogl_bitmask is now using these macros as well so that the logic can
be shared.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
-rw-r--r-- | cogl-pango/Makefile.am | 1 | ||||
-rw-r--r-- | cogl/cogl-bitmask.c | 36 | ||||
-rw-r--r-- | cogl/cogl-flags.h | 36 |
3 files changed, 48 insertions, 25 deletions
diff --git a/cogl-pango/Makefile.am b/cogl-pango/Makefile.am index 6917c1cd..5ee1fabb 100644 --- a/cogl-pango/Makefile.am +++ b/cogl-pango/Makefile.am @@ -40,6 +40,7 @@ INCLUDES = \ -DCLUTTER_COMPILATION \ -DG_LOG_DOMAIN=\"CoglPango\" \ -I$(top_srcdir)/cogl \ + -I$(top_builddir)/cogl \ -I$(top_srcdir)/cogl/winsys \ -I$(top_srcdir) \ -I$(top_builddir) diff --git a/cogl/cogl-bitmask.c b/cogl/cogl-bitmask.c index 1fe21983..ec69625d 100644 --- a/cogl/cogl-bitmask.c +++ b/cogl/cogl-bitmask.c @@ -33,6 +33,7 @@ #include "cogl-bitmask.h" #include "cogl-util.h" +#include "cogl-flags.h" /* This code assumes that we can cast an unsigned long to a pointer and back without losing any data */ @@ -236,41 +237,26 @@ _cogl_bitmask_foreach (const CoglBitmask *bitmask, if (_cogl_bitmask_has_array (bitmask)) { GArray *array = (GArray *) *bitmask; - int array_index; + const unsigned long *values = &g_array_index (array, unsigned long, 0); + int bit_num; - for (array_index = 0; array_index < array->len; array_index++) + COGL_FLAGS_FOREACH_START (values, array->len, bit_num) { - unsigned long mask = - g_array_index (array, unsigned long, array_index); - int bit = 0; - - while (mask) - { - int next_bit = _cogl_util_ffsl (mask); - - bit += next_bit; - mask >>= next_bit; - - if (!func (array_index * sizeof (unsigned long) * 8 + bit - 1, - user_data)) - return; - } + if (!func (bit_num, user_data)) + return; } + COGL_FLAGS_FOREACH_END; } else { unsigned long mask = _cogl_bitmask_to_bits (bitmask); - int bit = 0; + int bit_num; - while (mask) + COGL_FLAGS_FOREACH_START (&mask, 1, bit_num) { - int next_bit = _cogl_util_ffsl (mask); - - bit += next_bit; - mask >>= next_bit; - - if (!func (bit - 1, user_data)) + if (!func (bit_num, user_data)) return; } + COGL_FLAGS_FOREACH_END; } } diff --git a/cogl/cogl-flags.h b/cogl/cogl-flags.h index 14fb8f19..bf5eadd4 100644 --- a/cogl/cogl-flags.h +++ b/cogl/cogl-flags.h @@ -29,6 +29,8 @@ #include <glib.h> +#include "cogl-util.h" + G_BEGIN_DECLS /* These are macros used to implement a fixed-size array of bits. This @@ -78,6 +80,40 @@ G_BEGIN_DECLS ~COGL_FLAGS_GET_MASK (flag)); \ } G_STMT_END +/* Macros to help iterate an array of flags. It should be used like + * this: + * + * int n_longs = COGL_FLAGS_N_LONGS_FOR_SIZE (...); + * unsigned long flags[n_longs]; + * int bit_num; + * + * COGL_FLAGS_FOREACH_START (flags, n_longs, bit_num) + * { + * do_something_with_the_bit (bit_num); + * } + * COGL_FLAGS_FOREACH_END; + */ +#define COGL_FLAGS_FOREACH_START(array, n_longs, bit) \ + G_STMT_START { \ + const unsigned long *_p = (array); \ + int _n_longs = (n_longs); \ + int _i; \ + \ + for (_i = 0; _i < _n_longs; _i++) \ + { \ + unsigned long _mask = *(_p++); \ + \ + (bit) = _i * sizeof (unsigned long) * 8 - 1; \ + \ + while (_mask) \ + { \ + int _next_bit = _cogl_util_ffsl (_mask); \ + (bit) += _next_bit; \ + _mask >>= _next_bit; + +#define COGL_FLAGS_FOREACH_END \ + } } } G_STMT_END + G_END_DECLS #endif /* __COGL_FLAGS_H */ |