2 * Copyright © 2011 Red Hat Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 * Authors: Benjamin Otte <otte@gnome.org>
22 #include "gtk/gtkallocatedbitmaskprivate.h"
24 #define VALUE_TYPE gsize
26 #define VALUE_SIZE_BITS (sizeof (VALUE_TYPE) * 8)
27 #define VALUE_BIT(idx) (((VALUE_TYPE) 1) << (idx))
35 gtk_allocated_bitmask_resize (GtkBitmask *mask,
36 gsize size) G_GNUC_WARN_UNUSED_RESULT;
38 gtk_allocated_bitmask_resize (GtkBitmask *mask,
43 mask = g_realloc (mask, sizeof (GtkBitmask) + sizeof(VALUE_TYPE) * (MAX (size, 1) - 1));
45 for (i = mask->len; i < size; i++)
54 _gtk_allocated_bitmask_new (void)
56 return g_malloc0 (sizeof (GtkBitmask));
60 _gtk_allocated_bitmask_copy (const GtkBitmask *mask)
64 g_return_val_if_fail (mask != NULL, NULL);
66 copy = _gtk_allocated_bitmask_new ();
68 return _gtk_allocated_bitmask_union (copy, mask);
72 _gtk_allocated_bitmask_free (GtkBitmask *mask)
74 g_return_if_fail (mask != NULL);
80 _gtk_allocated_bitmask_print (const GtkBitmask *mask,
85 g_return_if_fail (mask != NULL);
86 g_return_if_fail (string != NULL);
88 for (i = mask->len * VALUE_SIZE_BITS - 1; i >= 0; i--)
90 if (_gtk_allocated_bitmask_get (mask, i))
96 g_string_append_c (string, '0');
102 g_string_append_c (string, _gtk_allocated_bitmask_get (mask, i) ? '1' : '0');
107 _gtk_allocated_bitmask_to_string (const GtkBitmask *mask)
111 string = g_string_new (NULL);
112 _gtk_allocated_bitmask_print (mask, string);
113 return g_string_free (string, FALSE);
116 /* NB: Call this function whenever the
117 * array might have become too large.
118 * _gtk_allocated_bitmask_is_empty() depends on this.
121 gtk_allocated_bitmask_shrink (GtkBitmask *mask) G_GNUC_WARN_UNUSED_RESULT;
123 gtk_allocated_bitmask_shrink (GtkBitmask *mask)
127 for (i = mask->len; i; i--)
129 if (mask->data[i - 1])
133 return gtk_allocated_bitmask_resize (mask, i);
137 _gtk_allocated_bitmask_intersect (GtkBitmask *mask,
138 const GtkBitmask *other)
142 g_return_val_if_fail (mask != NULL, NULL);
143 g_return_val_if_fail (other != NULL, NULL);
145 mask = gtk_allocated_bitmask_resize (mask, MIN (mask->len, other->len));
146 for (i = 0; i < mask->len; i++)
148 mask->data[i] &= other->data[i];
151 return gtk_allocated_bitmask_shrink (mask);
155 _gtk_allocated_bitmask_union (GtkBitmask *mask,
156 const GtkBitmask *other)
160 g_return_val_if_fail (mask != NULL, NULL);
161 g_return_val_if_fail (other != NULL, NULL);
163 mask = gtk_allocated_bitmask_resize (mask, MAX (mask->len, other->len));
164 for (i = 0; i < other->len; i++)
166 mask->data[i] |= other->data[i];
173 _gtk_allocated_bitmask_subtract (GtkBitmask *mask,
174 const GtkBitmask *other)
178 g_return_val_if_fail (mask != NULL, NULL);
179 g_return_val_if_fail (other != NULL, NULL);
181 for (i = 0; i < other->len; i++)
183 mask->data[i] |= ~other->data[i];
186 return gtk_allocated_bitmask_shrink (mask);
190 gtk_allocated_bitmask_indexes (guint index_,
194 *array_index = index_ / VALUE_SIZE_BITS;
195 *bit_index = index_ % VALUE_SIZE_BITS;
199 _gtk_allocated_bitmask_get (const GtkBitmask *mask,
202 guint array_index, bit_index;
204 g_return_val_if_fail (mask != NULL, FALSE);
206 gtk_allocated_bitmask_indexes (index_, &array_index, &bit_index);
208 if (array_index >= mask->len)
211 return (mask->data[array_index] & VALUE_BIT (bit_index)) ? TRUE : FALSE;
215 _gtk_allocated_bitmask_set (GtkBitmask *mask,
219 guint array_index, bit_index;
221 g_return_val_if_fail (mask != NULL, NULL);
223 gtk_allocated_bitmask_indexes (index_, &array_index, &bit_index);
227 if (array_index >= mask->len)
228 mask = gtk_allocated_bitmask_resize (mask, array_index + 1);
230 mask->data[array_index] |= VALUE_BIT (bit_index);
234 if (array_index < mask->len)
236 mask->data[array_index] &= ~ VALUE_BIT (bit_index);
237 mask = gtk_allocated_bitmask_shrink (mask);
245 _gtk_allocated_bitmask_invert_range (GtkBitmask *mask,
251 g_return_val_if_fail (mask != NULL, NULL);
252 g_return_val_if_fail (start < end, NULL);
254 /* I CAN HAS SPEEDUP? */
256 for (i = start; i < end; i++)
257 mask = _gtk_allocated_bitmask_set (mask, i, !_gtk_allocated_bitmask_get (mask, i));
263 _gtk_allocated_bitmask_is_empty (const GtkBitmask *mask)
265 g_return_val_if_fail (mask != NULL, FALSE);
267 return mask->len == 0;
271 _gtk_allocated_bitmask_equals (const GtkBitmask *mask,
272 const GtkBitmask *other)
276 g_return_val_if_fail (mask != NULL, FALSE);
277 g_return_val_if_fail (other != NULL, FALSE);
279 if (mask->len != other->len)
282 for (i = 0; i < mask->len; i++)
284 if (mask->data[i] != other->data[i])
292 _gtk_allocated_bitmask_intersects (const GtkBitmask *mask,
293 const GtkBitmask *other)
297 g_return_val_if_fail (mask != NULL, FALSE);
298 g_return_val_if_fail (other != NULL, FALSE);
300 for (i = MIN (mask->len, other->len) - 1; i >= 0; i--)
302 if (mask->data[i] & other->data[i])