Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / utils / monobitset.c
index 48ceb714bd44e42bef208082fcc8a633e69c43b9..c3615d14bbedc53d4cabf12999b183a2f2a42ad9 100644 (file)
@@ -1,31 +1,22 @@
+/**
+ * \file
+ */
+
 #include <glib.h>
 #include <string.h>
 
 #include "monobitset.h"
 #include "config.h"
 
-#ifdef __GNUC__
-#define MONO_ZERO_LEN_ARRAY 0
-#else
-#define MONO_ZERO_LEN_ARRAY 1
-#endif
-
 #define BITS_PER_CHUNK MONO_BITSET_BITS_PER_CHUNK
 
-struct MonoBitSet {
-       gsize size;
-       gsize flags;
-       gsize data [MONO_ZERO_LEN_ARRAY];
-};
-
-/*
+/**
  * mono_bitset_alloc_size:
- * @max_size: The numer of bits you want to hold
- * @flags: unused
- *
- * Return the number of bytes required to hold the bitset.
+ * \param max_size The number of bits you want to hold
+ * \param flags unused
+ * \returns the number of bytes required to hold the bitset.
  * Useful to allocate it on the stack or with mempool.
- * Use with mono_bitset_mem_new ().
+ * Use with \c mono_bitset_mem_new.
  */
 guint32
 mono_bitset_alloc_size (guint32 max_size, guint32 flags) {
@@ -34,39 +25,38 @@ mono_bitset_alloc_size (guint32 max_size, guint32 flags) {
        return sizeof (MonoBitSet) + sizeof (gsize) * (real_size - MONO_ZERO_LEN_ARRAY);
 }
 
-/*
+/**
  * mono_bitset_new:
- * @max_size: The numer of bits you want to hold
- * @flags: bitfield of flags
- *
- * Return a bitset of size max_size. It must be freed using
- * mono_bitset_free.
+ * \param max_size The numer of bits you want to hold
+ * \param flags bitfield of flags
+ * \returns a bitset of size \p max_size. It must be freed using
+ * \c mono_bitset_free.
  */
 MonoBitSet *
 mono_bitset_new (guint32 max_size, guint32 flags) {
        guint32 real_size = (max_size + BITS_PER_CHUNK - 1) / BITS_PER_CHUNK;
        MonoBitSet *result;
 
-       result = g_malloc0 (sizeof (MonoBitSet) + sizeof (gsize) * (real_size - MONO_ZERO_LEN_ARRAY));
+       result = (MonoBitSet *) g_malloc0 (sizeof (MonoBitSet) + sizeof (gsize) * (real_size - MONO_ZERO_LEN_ARRAY));
        result->size = real_size * BITS_PER_CHUNK;
        result->flags = flags;
        return result;
 }
 
-/*
+/**
  * mono_bitset_mem_new:
- * @mem: The location the bitset is stored
- * @max_size: The number of bits you want to hold
- * @flags: bitfield of flags
+ * \param mem The location the bitset is stored
+ * \param max_size The number of bits you want to hold
+ * \param flags bitfield of flags
  *
- * Return mem, which is now a initialized bitset of size max_size. It is
- * not freed even if called with mono_bitset_free. mem must be at least
- * as big as mono_bitset_alloc_size returns for the same max_size.
+ * Return \p mem, which is now a initialized bitset of size \p max_size. It is
+ * not freed even if called with \c mono_bitset_free. \p mem must be at least
+ * as big as \c mono_bitset_alloc_size returns for the same \p max_size.
  */
 MonoBitSet *
 mono_bitset_mem_new (gpointer mem, guint32 max_size, guint32 flags) {
        guint32 real_size = (max_size + BITS_PER_CHUNK - 1) / BITS_PER_CHUNK;
-       MonoBitSet *result = mem;
+       MonoBitSet *result = (MonoBitSet *) mem;
 
        result->size = real_size * BITS_PER_CHUNK;
        result->flags = flags | MONO_BITSET_DONT_FREE;
@@ -75,11 +65,11 @@ mono_bitset_mem_new (gpointer mem, guint32 max_size, guint32 flags) {
 
 /*
  * mono_bitset_free:
- * @set: bitset ptr to free
+ * \param set bitset ptr to free
  *
- * Free bitset unless flags have MONO_BITSET_DONT_FREE set. Does not
- * free anything if flag MONO_BITSET_DONT_FREE is set or bitset was
- * made with mono_bitset_mem_new.
+ * Free bitset unless flags have \c MONO_BITSET_DONT_FREE set. Does not
+ * free anything if flag \c MONO_BITSET_DONT_FREE is set or bitset was
+ * made with \c mono_bitset_mem_new.
  */
 void
 mono_bitset_free (MonoBitSet *set) {
@@ -87,12 +77,12 @@ mono_bitset_free (MonoBitSet *set) {
                g_free (set);
 }
 
-/*
+/**
  * mono_bitset_set:
- * @set: bitset ptr
- * @pos: set bit at this pos
+ * \param set bitset ptr
+ * \param pos set bit at this pos
  *
- * Set bit at pos @pos, counting from 0.
+ * Set bit at \p pos, counting from 0.
  */
 void
 mono_bitset_set (MonoBitSet *set, guint32 pos) {
@@ -104,13 +94,12 @@ mono_bitset_set (MonoBitSet *set, guint32 pos) {
        set->data [j] |= (gsize)1 << bit;
 }
 
-/*
+/**
  * mono_bitset_test:
- * @set: bitset ptr
- * @pos: test bit at this pos
- *
- * Test bit at pos @pos, counting from 0.
- * Returns a value != 0 if set, 0 otherwise.
+ * \param set bitset ptr
+ * \param pos test bit at this pos
+ * Test bit at \p pos, counting from 0.
+ * \returns a nonzero value if set, 0 otherwise.
  */
 int
 mono_bitset_test (const MonoBitSet *set, guint32 pos) {
@@ -122,12 +111,11 @@ mono_bitset_test (const MonoBitSet *set, guint32 pos) {
        return (set->data [j] & ((gsize)1 << bit)) > 0;
 }
 
-/*
+/**
  * mono_bitset_test_bulk:
- * @set: bitset ptr
- * @pos: test bit at this pos
- *
- * Return 32/64 bits from the bitset, starting from @pos, which must be 
+ * \param set bitset ptr
+ * \param pos test bit at this pos
+ * \returns 32/64 bits from the bitset, starting from \p pos, which must be 
  * divisible with 32/64.
  */
 gsize
@@ -140,12 +128,12 @@ mono_bitset_test_bulk (const MonoBitSet *set, guint32 pos) {
                return set->data [j];
 }
 
-/*
+/**
  * mono_bitset_clear:
- * @set: bitset ptr
- * @pos: unset bit at this pos
+ * \param set bitset ptr
+ * \param pos unset bit at this pos
  *
- * Unset bit at pos 'pos', counting from 0.
+ * Unset bit at \p pos, counting from 0.
  */
 void
 mono_bitset_clear (MonoBitSet *set, guint32 pos) {
@@ -157,9 +145,9 @@ mono_bitset_clear (MonoBitSet *set, guint32 pos) {
        set->data [j] &= ~((gsize)1 << bit);
 }
 
-/*
+/**
  * mono_bitset_clear_all:
- * @set: bitset ptr
+ * \param set bitset ptr
  *
  * Unset all bits.
  */
@@ -168,9 +156,9 @@ mono_bitset_clear_all (MonoBitSet *set) {
        memset (set->data, 0, set->size / 8);
 }
 
-/*
+/**
  * mono_bitset_set_all:
- * @set: bitset ptr
+ * \param set bitset ptr
  *
  * Set all bits.
  */
@@ -179,9 +167,9 @@ mono_bitset_set_all (MonoBitSet *set) {
        memset (set->data, -1, set->size / 8);
 }
 
-/*
+/**
  * mono_bitset_invert:
- * @set: bitset ptr
+ * \param set bitset ptr
  *
  * Flip all bits.
  */
@@ -192,11 +180,10 @@ mono_bitset_invert (MonoBitSet *set) {
                set->data [i] = ~set->data [i];
 }
 
-/*
+/**
  * mono_bitset_size:
- * @set: bitset ptr
- *
- * Returns the number of bits this bitset can hold.
+ * \param set bitset ptr
+ * \returns the number of bits this bitset can hold.
  */
 guint32
 mono_bitset_size (const MonoBitSet *set) {
@@ -208,11 +195,10 @@ mono_bitset_size (const MonoBitSet *set) {
  */
 #if 1
 
-/*
+/**
  * mono_bitset_count:
- * @set: bitset ptr
- *
- * return number of bits that is set.
+ * \param set bitset ptr
+ * \returns number of bits that are set.
  */
 guint32
 mono_bitset_count (const MonoBitSet *set) {
@@ -222,25 +208,17 @@ mono_bitset_count (const MonoBitSet *set) {
        count = 0;
        for (i = 0; i < set->size / BITS_PER_CHUNK; ++i) {
                d = set->data [i];
-               /* there is probably some asm code that can do this much faster */
-               if (d) {
-#if SIZEOF_VOID_P == 8
-                       /* http://www.jjj.de/bitwizardry/bitwizardrypage.html */
-                       d -=  (d>>1) & 0x5555555555555555;
-                       d  = ((d>>2) & 0x3333333333333333) + (d & 0x3333333333333333);
-                       d  = ((d>>4) + d) & 0x0f0f0f0f0f0f0f0f;
-                       d *= 0x0101010101010101;
-                       count += d >> 56;
+#ifdef __GNUC__
+               if (sizeof (gsize) == sizeof (unsigned int))
+                       count += __builtin_popcount (d);
+               else
+                       count += __builtin_popcountll (d);
 #else
-                       /* http://aggregate.org/MAGIC/ */
-                       d -= ((d >> 1) & 0x55555555);
-                       d = (((d >> 2) & 0x33333333) + (d & 0x33333333));
-                       d = (((d >> 4) + d) & 0x0f0f0f0f);
-                       d += (d >> 8);
-                       d += (d >> 16);
-                       count += (d & 0x0000003f);
-#endif
+               while (d) {
+                       count ++;
+                       d &= (d - 1);
                }
+#endif
        }
        return count;
 }
@@ -297,7 +275,7 @@ my_g_bit_nth_lsf (gsize mask, gint nth_bit)
        if ((mask == 0) || (nth_bit == BITS_PER_CHUNK))
                return -1;
 
-#if defined(__i386__) && defined(__GNUC__)
+#if (defined(__i386__) && defined(__GNUC__))
  {
         int r;
         /* This depends on mask != 0 */
@@ -327,7 +305,7 @@ static inline gint
 my_g_bit_nth_lsf_nomask (gsize mask)
 {
        /* Mask is expected to be != 0 */
-#if defined(__i386__) && defined(__GNUC__)
+#if (defined(__i386__) && defined(__GNUC__))
        int r;
 
        __asm__("bsfl %1,%0\n\t"
@@ -384,7 +362,7 @@ my_g_bit_nth_msf (gsize mask,
 }
 
 static int
-find_first_unset (gulong mask, gint nth_bit)
+find_first_unset (gsize mask, gint nth_bit)
 {
        do {
                nth_bit++;
@@ -399,11 +377,10 @@ find_first_unset (gulong mask, gint nth_bit)
        return -1;
 }
 
-/*
+/**
  * mono_bitset_find_start:
- * @set: bitset ptr
- *
- * Equivalent to mono_bitset_find_first (set, -1) but faster.
+ * \param set bitset ptr
+ * Equivalent to <code>mono_bitset_find_first (set, -1)</code> but faster.
  */
 int
 mono_bitset_find_start   (const MonoBitSet *set)
@@ -417,13 +394,12 @@ mono_bitset_find_start   (const MonoBitSet *set)
        return -1;
 }
 
-/*
+/**
  * mono_bitset_find_first:
- * @set: bitset ptr
- * @pos: pos to search _after_ (not including)
- *
- * Returns position of first set bit after @pos. If pos < 0 begin search from
- * start. Return -1 if no bit set is found.
+ * \param set bitset ptr
+ * \param pos pos to search after (not including)
+ * \returns position of first set bit after \p pos. If \p pos < 0, begin search from
+ * start. Return \c -1 if no bit set is found.
  */
 int
 mono_bitset_find_first (const MonoBitSet *set, gint pos) {
@@ -453,13 +429,12 @@ mono_bitset_find_first (const MonoBitSet *set, gint pos) {
        return -1;
 }
 
-/*
+/**
  * mono_bitset_find_last:
- * @set: bitset ptr
- * @pos: pos to search _before_ (not including)
- *
- * Returns position of last set bit before pos. If pos < 0 search is
- * started from the end. Returns -1 if no set bit is found.
+ * \param set bitset ptr
+ * \param pos pos to search before (not including)
+ * \returns position of last set bit before \p pos. If \p pos < 0 search is
+ * started from the end. Returns \c -1 if no set bit is found.
  */
 int
 mono_bitset_find_last (const MonoBitSet *set, gint pos) {
@@ -485,13 +460,12 @@ mono_bitset_find_last (const MonoBitSet *set, gint pos) {
        return -1;
 }
 
-/*
+/**
  * mono_bitset_find_first_unset:
- * @set: bitset ptr
- * @pos: pos to search _after_ (not including)
- *
- * Returns position of first unset bit after @pos. If pos < 0 begin search from
- * start. Return -1 if no bit set is found.
+ * \param set bitset ptr
+ * \param pos pos to search after (not including)
+ * \returns position of first unset bit after \p pos. If \p pos < 0 begin search from
+ * start. Return \c -1 if no bit set is found.
  */
 int
 mono_bitset_find_first_unset (const MonoBitSet *set, gint pos) {
@@ -522,13 +496,12 @@ mono_bitset_find_first_unset (const MonoBitSet *set, gint pos) {
        return -1;
 }
 
-/*
+/**
  * mono_bitset_clone:
- * @set: bitset ptr to clone
- * @new_size: number of bits the cloned bitset can hold
- *
- * Return a cloned bitset of size new_size. MONO_BITSET_DONT_FREE
- * unset in cloned bitset. If new_size is 0, the cloned object is just
+ * \param set bitset ptr to clone
+ * \param new_size number of bits the cloned bitset can hold
+ * \returns a cloned bitset of size \p new_size. \c MONO_BITSET_DONT_FREE
+ * unset in cloned bitset. If \p new_size is 0, the cloned object is just
  * as big.
  */
 MonoBitSet*
@@ -543,10 +516,10 @@ mono_bitset_clone (const MonoBitSet *set, guint32 new_size) {
        return result;
 }
 
-/*
+/**
  * mono_bitset_copyto:
- * @src: bitset ptr to copy from
- * @dest: bitset ptr to copy to
+ * \param src bitset ptr to copy from
+ * \param dest bitset ptr to copy to
  *
  * Copy one bitset to another.
  */
@@ -557,82 +530,85 @@ mono_bitset_copyto (const MonoBitSet *src, MonoBitSet *dest) {
        memcpy (&dest->data, &src->data, dest->size / 8);
 }
 
-/*
+/**
  * mono_bitset_union:
- * @dest: bitset ptr to hold union
- * @src: bitset ptr to copy
+ * \param dest bitset ptr to hold union
+ * \param src bitset ptr to copy
  *
  * Make union of one bitset and another.
  */
 void
 mono_bitset_union (MonoBitSet *dest, const MonoBitSet *src) {
-       int i;
+       int i, size;
 
        g_assert (src->size <= dest->size);
 
-       for (i = 0; i < dest->size / BITS_PER_CHUNK; ++i)
+       size = dest->size / BITS_PER_CHUNK;
+       for (i = 0; i < size; ++i)
                dest->data [i] |= src->data [i];
 }
 
-/*
+/**
  * mono_bitset_intersection:
- * @dest: bitset ptr to hold intersection
- * @src: bitset ptr to copy
+ * \param dest bitset ptr to hold intersection
+ * \param src bitset ptr to copy
  *
  * Make intersection of one bitset and another.
  */
 void
 mono_bitset_intersection (MonoBitSet *dest, const MonoBitSet *src) {
-       int i;
+       int i, size;
 
        g_assert (src->size <= dest->size);
 
-       for (i = 0; i < dest->size / BITS_PER_CHUNK; ++i)
-               dest->data [i] = dest->data [i] & src->data [i];
+       size = dest->size / BITS_PER_CHUNK;
+       for (i = 0; i < size; ++i)
+               dest->data [i] &= src->data [i];
 }
 
-/*
+/**
  * mono_bitset_intersection_2:
- * @dest: bitset ptr to hold intersection
- * @src1: first bitset
- * @src2: second bitset
+ * \param dest bitset ptr to hold intersection
+ * \param src1 first bitset
+ * \param src2 second bitset
  *
  * Make intersection of two bitsets
  */
 void
 mono_bitset_intersection_2 (MonoBitSet *dest, const MonoBitSet *src1, const MonoBitSet *src2) {
-       int i;
+       int i, size;
 
        g_assert (src1->size <= dest->size);
        g_assert (src2->size <= dest->size);
 
-       for (i = 0; i < dest->size / BITS_PER_CHUNK; ++i)
+       size = dest->size / BITS_PER_CHUNK;
+       for (i = 0; i < size; ++i)
                dest->data [i] = src1->data [i] & src2->data [i];
 }
 
-/*
+/**
  * mono_bitset_sub:
- * @dest: bitset ptr to hold bitset - src
- * @src: bitset ptr to copy
+ * \param dest bitset ptr to hold bitset - src
+ * \param src bitset ptr to copy
  *
- * Unset all bits in dest, which are set in src.
+ * Unset all bits in \p dest that are set in \p src.
  */
 void
 mono_bitset_sub (MonoBitSet *dest, const MonoBitSet *src) {
-       int i;
+       int i, size;
 
        g_assert (src->size <= dest->size);
 
-       for (i = 0; i < src->size / BITS_PER_CHUNK; ++i)
+       size = src->size / BITS_PER_CHUNK;
+       for (i = 0; i < size; ++i)
                dest->data [i] &= ~src->data [i];
 }
 
-/*
+/**
  * mono_bitset_equal:
- * @src: bitset ptr
- * @src1: bitset ptr
- *
- * return TRUE if their size are the same and the same bits are set in
+ * \param src bitset ptr
+ * \param src1 bitset ptr
+ * \returns TRUE if their size are the same and the same bits are set in
  * both bitsets.
  */
 gboolean
@@ -647,13 +623,12 @@ mono_bitset_equal (const MonoBitSet *src, const MonoBitSet *src1) {
        return TRUE;
 }
 
-/*
+/**
  * mono_bitset_foreach:
- * @set: bitset ptr
- * @func: Function to call for every set bit
- * @data: pass this as second arg to func
- *
- * Calls func for every bit set in bitset. Argument 1 is the number of
+ * \param set bitset ptr
+ * \param func Function to call for every set bit
+ * \param data pass this as second arg to func
+ * Calls \p func for every bit set in bitset. Argument 1 is the number of
  * the bit set, argument 2 is data
  */
 void
@@ -825,4 +800,3 @@ main() {
 }
 
 #endif
-