1 | /* |
2 | * Copyright © 2011 Red Hat Inc. |
3 | * |
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. |
8 | * |
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. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | * |
18 | * Authors: Benjamin Otte <otte@gnome.org> |
19 | */ |
20 | |
21 | |
22 | static inline GtkBitmask * |
23 | _gtk_bitmask_new (void) |
24 | { |
25 | return _gtk_bitmask_from_bits (0); |
26 | } |
27 | |
28 | static inline GtkBitmask * |
29 | _gtk_bitmask_copy (const GtkBitmask *mask) |
30 | { |
31 | if (_gtk_bitmask_is_allocated (mask)) |
32 | return _gtk_allocated_bitmask_copy (mask); |
33 | else |
34 | return (GtkBitmask *) mask; |
35 | } |
36 | |
37 | static inline void |
38 | _gtk_bitmask_free (GtkBitmask *mask) |
39 | { |
40 | if (_gtk_bitmask_is_allocated (mask)) |
41 | _gtk_allocated_bitmask_free (mask); |
42 | } |
43 | |
44 | static inline char * |
45 | _gtk_bitmask_to_string (const GtkBitmask *mask) |
46 | { |
47 | GString *string; |
48 | |
49 | string = g_string_new (NULL); |
50 | _gtk_allocated_bitmask_print (mask, string); |
51 | return g_string_free (string, FALSE); |
52 | } |
53 | |
54 | static inline void |
55 | _gtk_bitmask_print (const GtkBitmask *mask, |
56 | GString *string) |
57 | { |
58 | _gtk_allocated_bitmask_print (mask, string); |
59 | } |
60 | |
61 | static inline GtkBitmask * |
62 | _gtk_bitmask_intersect (GtkBitmask *mask, |
63 | const GtkBitmask *other) |
64 | { |
65 | return _gtk_allocated_bitmask_intersect (mask, other); |
66 | } |
67 | |
68 | static inline GtkBitmask * |
69 | _gtk_bitmask_union (GtkBitmask *mask, |
70 | const GtkBitmask *other) |
71 | { |
72 | if (_gtk_bitmask_is_allocated (mask) || |
73 | _gtk_bitmask_is_allocated (other)) |
74 | return _gtk_allocated_bitmask_union (mask, other); |
75 | else |
76 | return _gtk_bitmask_from_bits (_gtk_bitmask_to_bits (mask) |
77 | | _gtk_bitmask_to_bits (other)); |
78 | } |
79 | |
80 | static inline GtkBitmask * |
81 | _gtk_bitmask_subtract (GtkBitmask *mask, |
82 | const GtkBitmask *other) |
83 | { |
84 | return _gtk_allocated_bitmask_subtract (mask, other); |
85 | } |
86 | |
87 | static inline gboolean |
88 | _gtk_bitmask_get (const GtkBitmask *mask, |
89 | guint index_) |
90 | { |
91 | if (_gtk_bitmask_is_allocated (mask)) |
92 | return _gtk_allocated_bitmask_get (mask, index_); |
93 | else |
94 | return index_ < GTK_BITMASK_N_DIRECT_BITS |
95 | ? !!(_gtk_bitmask_to_bits (mask) & (((gsize) 1) << index_)) |
96 | : FALSE; |
97 | } |
98 | |
99 | static inline GtkBitmask * |
100 | _gtk_bitmask_set (GtkBitmask *mask, |
101 | guint index_, |
102 | gboolean value) |
103 | { |
104 | if (_gtk_bitmask_is_allocated (mask) || |
105 | (index_ >= GTK_BITMASK_N_DIRECT_BITS && value)) |
106 | return _gtk_allocated_bitmask_set (mask, index_, value); |
107 | else if (index_ < GTK_BITMASK_N_DIRECT_BITS) |
108 | { |
109 | gsize bits = _gtk_bitmask_to_bits (mask); |
110 | |
111 | if (value) |
112 | bits |= ((gsize) 1) << index_; |
113 | else |
114 | bits &= ~(((gsize) 1) << index_); |
115 | |
116 | return _gtk_bitmask_from_bits (bits); |
117 | } |
118 | else |
119 | return mask; |
120 | } |
121 | |
122 | static inline GtkBitmask * |
123 | _gtk_bitmask_invert_range (GtkBitmask *mask, |
124 | guint start, |
125 | guint end) |
126 | { |
127 | g_assert (start <= end); |
128 | |
129 | if (_gtk_bitmask_is_allocated (mask) || |
130 | (end > GTK_BITMASK_N_DIRECT_BITS)) |
131 | return _gtk_allocated_bitmask_invert_range (mask, start, end); |
132 | else |
133 | { |
134 | gsize invert = (((gsize) 1) << end) - (((gsize) 1) << start); |
135 | |
136 | return _gtk_bitmask_from_bits (_gtk_bitmask_to_bits (mask) ^ invert); |
137 | } |
138 | } |
139 | |
140 | static inline gboolean |
141 | _gtk_bitmask_is_empty (const GtkBitmask *mask) |
142 | { |
143 | return mask == _gtk_bitmask_from_bits (0); |
144 | } |
145 | |
146 | static inline gboolean |
147 | _gtk_bitmask_equals (const GtkBitmask *mask, |
148 | const GtkBitmask *other) |
149 | { |
150 | if (mask == other) |
151 | return TRUE; |
152 | |
153 | if (!_gtk_bitmask_is_allocated (mask) || |
154 | !_gtk_bitmask_is_allocated (other)) |
155 | return FALSE; |
156 | |
157 | return _gtk_allocated_bitmask_equals (mask, other); |
158 | } |
159 | |
160 | static inline gboolean |
161 | _gtk_bitmask_intersects (const GtkBitmask *mask, |
162 | const GtkBitmask *other) |
163 | { |
164 | if (_gtk_bitmask_is_allocated (mask) || |
165 | _gtk_bitmask_is_allocated (other)) |
166 | return _gtk_allocated_bitmask_intersects (mask, other); |
167 | else |
168 | return _gtk_bitmask_to_bits (mask) & _gtk_bitmask_to_bits (other) ? TRUE : FALSE; |
169 | } |
170 | |