[cogl/wip/neil/pipeline-uniforms: 7/18] cogl-flags: Add some macros to help iterate the bits
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/neil/pipeline-uniforms: 7/18] cogl-flags: Add some macros to help iterate the bits
- Date: Fri, 4 Nov 2011 18:37:04 +0000 (UTC)
commit 43296eb1a1c3cbaecff95b56dde5b7a23556ef4c
Author: Neil Roberts <neil linux intel com>
Date: Wed Nov 2 13:41:32 2011 +0000
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.
cogl/cogl-bitmask.c | 36 +++++++++++-------------------------
cogl/cogl-flags.h | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 25 deletions(-)
---
diff --git a/cogl/cogl-bitmask.c b/cogl/cogl-bitmask.c
index 1fe2198..ec69625 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 14fb8f1..bf5eadd 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 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]