mirror of
https://github.com/brl/mutter.git
synced 2025-02-09 01:54:10 +00:00
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>
This commit is contained in:
parent
dbc31b70cc
commit
d706991579
@ -40,6 +40,7 @@ INCLUDES = \
|
|||||||
-DCLUTTER_COMPILATION \
|
-DCLUTTER_COMPILATION \
|
||||||
-DG_LOG_DOMAIN=\"CoglPango\" \
|
-DG_LOG_DOMAIN=\"CoglPango\" \
|
||||||
-I$(top_srcdir)/cogl \
|
-I$(top_srcdir)/cogl \
|
||||||
|
-I$(top_builddir)/cogl \
|
||||||
-I$(top_srcdir)/cogl/winsys \
|
-I$(top_srcdir)/cogl/winsys \
|
||||||
-I$(top_srcdir) \
|
-I$(top_srcdir) \
|
||||||
-I$(top_builddir)
|
-I$(top_builddir)
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "cogl-bitmask.h"
|
#include "cogl-bitmask.h"
|
||||||
#include "cogl-util.h"
|
#include "cogl-util.h"
|
||||||
|
#include "cogl-flags.h"
|
||||||
|
|
||||||
/* This code assumes that we can cast an unsigned long to a pointer
|
/* This code assumes that we can cast an unsigned long to a pointer
|
||||||
and back without losing any data */
|
and back without losing any data */
|
||||||
@ -236,41 +237,26 @@ _cogl_bitmask_foreach (const CoglBitmask *bitmask,
|
|||||||
if (_cogl_bitmask_has_array (bitmask))
|
if (_cogl_bitmask_has_array (bitmask))
|
||||||
{
|
{
|
||||||
GArray *array = (GArray *) *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 =
|
if (!func (bit_num, user_data))
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
COGL_FLAGS_FOREACH_END;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned long mask = _cogl_bitmask_to_bits (bitmask);
|
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);
|
if (!func (bit_num, user_data))
|
||||||
|
|
||||||
bit += next_bit;
|
|
||||||
mask >>= next_bit;
|
|
||||||
|
|
||||||
if (!func (bit - 1, user_data))
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
COGL_FLAGS_FOREACH_END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "cogl-util.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
/* These are macros used to implement a fixed-size array of bits. This
|
/* 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)); \
|
~COGL_FLAGS_GET_MASK (flag)); \
|
||||||
} G_STMT_END
|
} 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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_FLAGS_H */
|
#endif /* __COGL_FLAGS_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user