GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
Bitfield.java
Go to the documentation of this file.
1/**
2 * Copyright 2015 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.common.util;
29
30import jogamp.common.util.SyncedBitfield;
31
32/**
33 * Simple bitfield interface for efficient bit storage access in O(1).
34 * @since 2.3.2
35 */
36public interface Bitfield {
37 /** Maximum 32 bit Unsigned Integer Value: {@code 0xffffffff} == {@value}. */
38 public static final int UNSIGNED_INT_MAX_VALUE = 0xffffffff;
39
40 /**
41 * Bit operation utilities (static).
42 */
43 public static class Util {
44 /**
45 * Maximum 32bit integer value being of {@link #isPowerOf2(int)}.
46 * <p>
47 * We rely on the JVM spec {@link Integer#SIZE} == 32.
48 * </p>
49 */
50 public static final int MAX_POWER_OF_2 = 1 << ( Integer.SIZE - 2 );
51
52 /**
53 * Returns the 32 bit mask of n-bits, i.e. n low order 1’s.
54 * <p>
55 * Implementation handles n == 32.
56 * </p>
57 * @throws IndexOutOfBoundsException if {@code b} is out of bounds, i.e. &gt; 32
58 */
59 public static int getBitMask(final int n) {
60 if( 32 > n ) {
61 return ( 1 << n ) - 1;
62 } else if ( 32 == n ) {
64 } else {
65 throw new IndexOutOfBoundsException("n <= 32 expected, is "+n);
66 }
67 }
68
69 /**
70 * Returns the number of set bits within given 32bit integer in O(1)
71 * using a <i>HAKEM 169 Bit Count</i> inspired implementation:
72 * <pre>
73 * http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html
74 * http://home.pipeline.com/~hbaker1/hakmem/hacks.html#item169
75 * http://tekpool.wordpress.com/category/bit-count/
76 * http://www.hackersdelight.org/
77 * </pre>
78 * <p>
79 * We rely on the JVM spec {@link Integer#SIZE} == 32.
80 * </p>
81 */
82 public static final int bitCount(int n) {
83 // Note: Original used 'unsigned int',
84 // hence we use the unsigned right-shift '>>>'
85 /**
86 * Original does not work due to lack of 'unsigned' right-shift and modulo,
87 * we need 2-complementary solution, i.e. 'signed'.
88 int c = n;
89 c -= (n >>> 1) & 033333333333;
90 c -= (n >>> 2) & 011111111111;
91 return ( (c + ( c >>> 3 ) ) & 030707070707 ) & 0x3f; // % 63
92 */
93 // Hackers Delight, Figure 5-2, pop1 of pop.c.txt
94 n = n - ((n >>> 1) & 0x55555555);
95 n = (n & 0x33333333) + ((n >>> 2) & 0x33333333);
96 n = (n + (n >>> 4)) & 0x0f0f0f0f;
97 n = n + (n >>> 8);
98 n = n + (n >>> 16);
99 return n & 0x3f;
100 }
101
102 /**
103 * Returns {@code true} if the given integer is a power of 2
104 * <p>
105 * Source: bithacks: http://www.graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
106 * </p>
107 */
108 public static final boolean isPowerOf2(final int n) {
109 return 0<n && 0 == (n & (n - 1));
110 }
111 /**
112 * Returns the next higher power of 2 of 32-bit of given {@code n}
113 * <p>
114 * Source: bithacks: http://www.graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
115 * </p>
116 * <p>
117 * We rely on the JVM spec {@link Integer#SIZE} == 32.
118 * </p>
119 */
120 public static final int nextPowerOf2(int n) {
121 n--;
122 n |= n >>> 1;
123 n |= n >>> 2;
124 n |= n >>> 4;
125 n |= n >>> 8;
126 n |= n >>> 16;
127 return (n < 0) ? 1 : n + 1; // avoid edge case where n is 0, it would return 0, which isn't a power of 2
128 }
129 /**
130 * If the given {@code n} is not {@link #isPowerOf2(int)} return {@link #nextPowerOf2(int)},
131 * otherwise return {@code n} unchanged.
132 * <pre>
133 * return isPowerOf2(n) ? n : nextPowerOf2(n);
134 * </pre>
135 * <p>
136 * We rely on the JVM spec {@link Integer#SIZE} == 32.
137 * </p>
138 */
139 public static final int roundToPowerOf2(final int n) {
140 return isPowerOf2(n) ? n : nextPowerOf2(n);
141 }
142 }
143 /**
144 * Simple {@link Bitfield} factory for returning the efficient implementation.
145 */
146 public static class Factory {
147 /**
148 * Creates am efficient {@link Bitfield} instance based on the requested {@code storageBitSize}.
149 * <p>
150 * Implementation returns a plain 32 bit integer field implementation for
151 * {@code storageBitSize} &le; 32 bits or an 32 bit integer array implementation otherwise.
152 * </p>
153 */
154 public static Bitfield create(final int storageBitSize) {
155 if( 32 >= storageBitSize ) {
156 return new jogamp.common.util.Int32Bitfield();
157 } else {
158 return new jogamp.common.util.Int32ArrayBitfield(storageBitSize);
159 }
160 }
161 /**
162 * Creates a synchronized {@link Bitfield} by wrapping the given {@link Bitfield} instance.
163 */
164 public static Bitfield synchronize(final Bitfield impl) {
165 return new SyncedBitfield(impl);
166 }
167 }
168 /**
169 * Returns the storage size in bit units, e.g. 32 bit for implementations using one {@code int} field.
170 */
171 int size();
172
173
174 /**
175 * Set all bits of this bitfield to the given value {@code bit}.
176 */
177 void clearField(final boolean bit);
178
179 /**
180 * Returns {@code length} bits from this storage,
181 * starting with the lowest bit from the storage position {@code lowBitnum}.
182 * @param lowBitnum storage bit position of the lowest bit, restricted to [0..{@link #size()}-{@code length}].
183 * @param length number of bits to read, constrained to [0..32].
184 * @throws IndexOutOfBoundsException if {@code rightBitnum} is out of bounds
185 * @see #put32(int, int, int)
186 */
187 int get32(final int lowBitnum, final int length) throws IndexOutOfBoundsException;
188
189 /**
190 * Puts {@code length} bits of given {@code data} into this storage,
191 * starting w/ the lowest bit to the storage position {@code lowBitnum}.
192 * @param lowBitnum storage bit position of the lowest bit, restricted to [0..{@link #size()}-{@code length}].
193 * @param length number of bits to write, constrained to [0..32].
194 * @param data the actual bits to be put into this storage
195 * @throws IndexOutOfBoundsException if {@code rightBitnum} is out of bounds
196 * @see #get32(int, int)
197 */
198 void put32(final int lowBitnum, final int length, final int data) throws IndexOutOfBoundsException;
199
200 /**
201 * Copies {@code length} bits at position {@code srcLowBitnum} to position {@code dstLowBitnum}
202 * and returning the bits.
203 * <p>
204 * Implementation shall operate as if invoking {@link #get32(int, int)}
205 * and then {@link #put32(int, int, int)} sequentially.
206 * </p>
207 * @param srcLowBitnum source bit number, restricted to [0..{@link #size()}-1].
208 * @param dstLowBitnum destination bit number, restricted to [0..{@link #size()}-1].
209 * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
210 * @see #get32(int, int)
211 * @see #put32(int, int, int)
212 */
213 int copy32(final int srcLowBitnum, final int dstLowBitnum, final int length) throws IndexOutOfBoundsException;
214
215 /**
216 * Return <code>true</code> if the bit at position <code>bitnum</code> is set, otherwise <code>false</code>.
217 * @param bitnum bit number, restricted to [0..{@link #size()}-1].
218 * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
219 */
220 boolean get(final int bitnum) throws IndexOutOfBoundsException;
221
222 /**
223 * Set or clear the bit at position <code>bitnum</code> according to <code>bit</code>
224 * and return the previous value.
225 * @param bitnum bit number, restricted to [0..{@link #size()}-1].
226 * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
227 */
228 boolean put(final int bitnum, final boolean bit) throws IndexOutOfBoundsException;
229
230 /**
231 * Set the bit at position <code>bitnum</code> according to <code>bit</code>.
232 * @param bitnum bit number, restricted to [0..{@link #size()}-1].
233 * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
234 */
235 void set(final int bitnum) throws IndexOutOfBoundsException;
236
237 /**
238 * Clear the bit at position <code>bitnum</code> according to <code>bit</code>.
239 * @param bitnum bit number, restricted to [0..{@link #size()}-1].
240 * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
241 */
242 void clear(final int bitnum) throws IndexOutOfBoundsException;
243
244 /**
245 * Copies the bit at position {@code srcBitnum} to position {@code dstBitnum}
246 * and returning <code>true</code> if the bit is set, otherwise <code>false</code>.
247 * @param srcBitnum source bit number, restricted to [0..{@link #size()}-1].
248 * @param dstBitnum destination bit number, restricted to [0..{@link #size()}-1].
249 * @throws IndexOutOfBoundsException if {@code bitnum} is out of bounds
250 */
251 boolean copy(final int srcBitnum, final int dstBitnum) throws IndexOutOfBoundsException;
252
253 /**
254 * Returns the number of one bits within this bitfield.
255 * <p>
256 * Utilizes {#link {@link Bitfield.Util#bitCount(int)}}.
257 * </p>
258 */
259 int bitCount();
260}
Simple Bitfield factory for returning the efficient implementation.
Definition: Bitfield.java:146
static Bitfield synchronize(final Bitfield impl)
Creates a synchronized Bitfield by wrapping the given Bitfield instance.
Definition: Bitfield.java:164
static Bitfield create(final int storageBitSize)
Creates am efficient Bitfield instance based on the requested storageBitSize.
Definition: Bitfield.java:154
Bit operation utilities (static).
Definition: Bitfield.java:43
static final int roundToPowerOf2(final int n)
If the given n is not isPowerOf2(int) return nextPowerOf2(int), otherwise return n unchanged.
Definition: Bitfield.java:139
static final int nextPowerOf2(int n)
Returns the next higher power of 2 of 32-bit of given n @endiliteral.
Definition: Bitfield.java:120
static final boolean isPowerOf2(final int n)
Returns true if the given integer is a power of 2.
Definition: Bitfield.java:108
static final int bitCount(int n)
Returns the number of set bits within given 32bit integer in O(1) using a HAKEM 169 Bit Count inspire...
Definition: Bitfield.java:82
static final int MAX_POWER_OF_2
Maximum 32bit integer value being of isPowerOf2(int).
Definition: Bitfield.java:50
static int getBitMask(final int n)
Returns the 32 bit mask of n-bits, i.e.
Definition: Bitfield.java:59
Simple bitfield interface for efficient bit storage access in O(1).
Definition: Bitfield.java:36
void clear(final int bitnum)
Clear the bit at position bitnum according to bit.
int bitCount()
Returns the number of one bits within this bitfield.
void clearField(final boolean bit)
Set all bits of this bitfield to the given value bit.
int size()
Returns the storage size in bit units, e.g.
int get32(final int lowBitnum, final int length)
Returns length bits from this storage, starting with the lowest bit from the storage position lowBitn...
void put32(final int lowBitnum, final int length, final int data)
Puts length bits of given data into this storage, starting w/ the lowest bit to the storage position ...
static final int UNSIGNED_INT_MAX_VALUE
Maximum 32 bit Unsigned Integer Value: 0xffffffff == {@value}.
Definition: Bitfield.java:38
int copy32(final int srcLowBitnum, final int dstLowBitnum, final int length)
Copies length bits at position srcLowBitnum to position dstLowBitnum and returning the bits.
boolean put(final int bitnum, final boolean bit)
Set or clear the bit at position bitnum according to bit and return the previous value.
boolean copy(final int srcBitnum, final int dstBitnum)
Copies the bit at position srcBitnum to position dstBitnum and returning true if the bit is set,...