xref: /aosp_15_r20/external/antlr/runtime/ObjC/Framework/ANTLRBitSet.m (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot// [The "BSD licence"]
2*16467b97STreehugger Robot// Copyright (c) 2006-2007 Kay Roepke 2010 Alan Condit
3*16467b97STreehugger Robot// All rights reserved.
4*16467b97STreehugger Robot//
5*16467b97STreehugger Robot// Redistribution and use in source and binary forms, with or without
6*16467b97STreehugger Robot// modification, are permitted provided that the following conditions
7*16467b97STreehugger Robot// are met:
8*16467b97STreehugger Robot// 1. Redistributions of source code must retain the above copyright
9*16467b97STreehugger Robot//    notice, this list of conditions and the following disclaimer.
10*16467b97STreehugger Robot// 2. Redistributions in binary form must reproduce the above copyright
11*16467b97STreehugger Robot//    notice, this list of conditions and the following disclaimer in the
12*16467b97STreehugger Robot//    documentation and/or other materials provided with the distribution.
13*16467b97STreehugger Robot// 3. The name of the author may not be used to endorse or promote products
14*16467b97STreehugger Robot//    derived from this software without specific prior written permission.
15*16467b97STreehugger Robot//
16*16467b97STreehugger Robot// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*16467b97STreehugger Robot// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*16467b97STreehugger Robot// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*16467b97STreehugger Robot// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*16467b97STreehugger Robot// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*16467b97STreehugger Robot// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*16467b97STreehugger Robot// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*16467b97STreehugger Robot// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*16467b97STreehugger Robot// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*16467b97STreehugger Robot// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*16467b97STreehugger Robot
27*16467b97STreehugger Robot#import "ANTLRBitSet.h"
28*16467b97STreehugger Robot
29*16467b97STreehugger Robot@implementation ANTLRBitSet
30*16467b97STreehugger Robot#pragma mark Class Methods
31*16467b97STreehugger Robot
32*16467b97STreehugger Robot+ (ANTLRBitSet *) newBitSet
33*16467b97STreehugger Robot{
34*16467b97STreehugger Robot    return [[ANTLRBitSet alloc] init];
35*16467b97STreehugger Robot}
36*16467b97STreehugger Robot
37*16467b97STreehugger Robot+ (ANTLRBitSet *) newBitSetWithType:(TokenType)type
38*16467b97STreehugger Robot{
39*16467b97STreehugger Robot    return [[ANTLRBitSet alloc] initWithType:type];
40*16467b97STreehugger Robot}
41*16467b97STreehugger Robot
42*16467b97STreehugger Robot/** Construct a ANTLRBitSet given the size
43*16467b97STreehugger Robot * @param nbits The size of the ANTLRBitSet in bits
44*16467b97STreehugger Robot */
45*16467b97STreehugger Robot+ (ANTLRBitSet *) newBitSetWithNBits:(NSUInteger)nbits
46*16467b97STreehugger Robot{
47*16467b97STreehugger Robot    return [[ANTLRBitSet alloc] initWithNBits:nbits];
48*16467b97STreehugger Robot}
49*16467b97STreehugger Robot
50*16467b97STreehugger Robot+ (ANTLRBitSet *) newBitSetWithArray:(AMutableArray *)types
51*16467b97STreehugger Robot{
52*16467b97STreehugger Robot    return [[ANTLRBitSet alloc] initWithArrayOfBits:types];
53*16467b97STreehugger Robot}
54*16467b97STreehugger Robot
55*16467b97STreehugger Robot+ (ANTLRBitSet *) newBitSetWithBits:(const unsigned long long *)theBits Count:(NSUInteger)longCount
56*16467b97STreehugger Robot{
57*16467b97STreehugger Robot    return [[ANTLRBitSet alloc] initWithBits:theBits Count:longCount];
58*16467b97STreehugger Robot}
59*16467b97STreehugger Robot
60*16467b97STreehugger Robot
61*16467b97STreehugger Robot+ (ANTLRBitSet *) of:(NSUInteger) el
62*16467b97STreehugger Robot{
63*16467b97STreehugger Robot    ANTLRBitSet *s = [ANTLRBitSet newBitSetWithNBits:(el + 1)];
64*16467b97STreehugger Robot    [s add:el];
65*16467b97STreehugger Robot    return s;
66*16467b97STreehugger Robot}
67*16467b97STreehugger Robot
68*16467b97STreehugger Robot+ (ANTLRBitSet *) of:(NSUInteger) a And2:(NSUInteger) b
69*16467b97STreehugger Robot{
70*16467b97STreehugger Robot    NSInteger c = (((a>b)?a:b)+1);
71*16467b97STreehugger Robot    ANTLRBitSet *s = [ANTLRBitSet newBitSetWithNBits:c];
72*16467b97STreehugger Robot    [s add:a];
73*16467b97STreehugger Robot    [s add:b];
74*16467b97STreehugger Robot    return s;
75*16467b97STreehugger Robot}
76*16467b97STreehugger Robot
77*16467b97STreehugger Robot+ (ANTLRBitSet *) of:(NSUInteger)a And2:(NSUInteger)b And3:(NSUInteger)c
78*16467b97STreehugger Robot{
79*16467b97STreehugger Robot    NSUInteger d = ((a>b)?a:b);
80*16467b97STreehugger Robot    d = ((c>d)?c:d)+1;
81*16467b97STreehugger Robot    ANTLRBitSet *s = [ANTLRBitSet newBitSetWithNBits:d];
82*16467b97STreehugger Robot    [s add:a];
83*16467b97STreehugger Robot    [s add:b];
84*16467b97STreehugger Robot    [s add:c];
85*16467b97STreehugger Robot    return s;
86*16467b97STreehugger Robot}
87*16467b97STreehugger Robot
88*16467b97STreehugger Robot+ (ANTLRBitSet *) of:(NSUInteger)a And2:(NSUInteger)b And3:(NSUInteger)c And4:(NSUInteger)d
89*16467b97STreehugger Robot{
90*16467b97STreehugger Robot    NSUInteger e = ((a>b)?a:b);
91*16467b97STreehugger Robot    NSUInteger f = ((c>d)?c:d);
92*16467b97STreehugger Robot    e = ((e>f)?e:f)+1;
93*16467b97STreehugger Robot    ANTLRBitSet *s = [ANTLRBitSet newBitSetWithNBits:e];
94*16467b97STreehugger Robot    [s add:a];
95*16467b97STreehugger Robot    [s add:b];
96*16467b97STreehugger Robot    [s add:c];
97*16467b97STreehugger Robot    [s add:d];
98*16467b97STreehugger Robot    return s;
99*16467b97STreehugger Robot}
100*16467b97STreehugger Robot
101*16467b97STreehugger Robot// initializer
102*16467b97STreehugger Robot#pragma mark Initializer
103*16467b97STreehugger Robot
104*16467b97STreehugger Robot- (ANTLRBitSet *) init
105*16467b97STreehugger Robot{
106*16467b97STreehugger Robot	if ((self = [super init]) != nil) {
107*16467b97STreehugger Robot		bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0);
108*16467b97STreehugger Robot	}
109*16467b97STreehugger Robot	return self;
110*16467b97STreehugger Robot}
111*16467b97STreehugger Robot
112*16467b97STreehugger Robot- (ANTLRBitSet *) initWithType:(TokenType)type
113*16467b97STreehugger Robot{
114*16467b97STreehugger Robot	if ((self = [super init]) != nil) {
115*16467b97STreehugger Robot		bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0);
116*16467b97STreehugger Robot        if ((CFIndex)type >= CFBitVectorGetCount(bitVector))
117*16467b97STreehugger Robot            CFBitVectorSetCount(bitVector, type+1);
118*16467b97STreehugger Robot        CFBitVectorSetBitAtIndex(bitVector, type, 1);
119*16467b97STreehugger Robot	}
120*16467b97STreehugger Robot	return self;
121*16467b97STreehugger Robot}
122*16467b97STreehugger Robot
123*16467b97STreehugger Robot- (ANTLRBitSet *) initWithNBits:(NSUInteger)nbits
124*16467b97STreehugger Robot{
125*16467b97STreehugger Robot	if ((self = [super init]) != nil) {
126*16467b97STreehugger Robot        bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0);
127*16467b97STreehugger Robot        CFBitVectorSetCount( bitVector, nbits );
128*16467b97STreehugger Robot	}
129*16467b97STreehugger Robot	return self;
130*16467b97STreehugger Robot}
131*16467b97STreehugger Robot
132*16467b97STreehugger Robot- (ANTLRBitSet *) initWithBitVector:(CFMutableBitVectorRef)theBitVector
133*16467b97STreehugger Robot{
134*16467b97STreehugger Robot	if ((self = [super init]) != nil) {
135*16467b97STreehugger Robot		bitVector = theBitVector;
136*16467b97STreehugger Robot	}
137*16467b97STreehugger Robot	return self;
138*16467b97STreehugger Robot}
139*16467b97STreehugger Robot
140*16467b97STreehugger Robot// Initialize the bit vector with a constant array of ulonglongs like ANTLR generates.
141*16467b97STreehugger Robot// Converts to big endian, because the underlying CFBitVector works like that.
142*16467b97STreehugger Robot- (ANTLRBitSet *) initWithBits:(const unsigned long long *)theBits Count:(NSUInteger)longCount
143*16467b97STreehugger Robot{
144*16467b97STreehugger Robot	if ((self = [super init]) != nil) {
145*16467b97STreehugger Robot		unsigned int longNo;
146*16467b97STreehugger Robot//        unsigned long long swappedBits = 0LL;
147*16467b97STreehugger Robot		CFIndex bitIdx;
148*16467b97STreehugger Robot        bitVector = CFBitVectorCreateMutable ( kCFAllocatorDefault, 0 );
149*16467b97STreehugger Robot		CFBitVectorSetCount( bitVector, sizeof(unsigned long long)*8*longCount );
150*16467b97STreehugger Robot
151*16467b97STreehugger Robot		for (longNo = 0; longNo < longCount; longNo++) {
152*16467b97STreehugger Robot			for (bitIdx = 0; bitIdx < (CFIndex)sizeof(unsigned long long)*8; bitIdx++) {
153*16467b97STreehugger Robot//				swappedBits = CFSwapInt64HostToBig(theBits[longNo]);
154*16467b97STreehugger Robot//				if (swappedBits & (1LL << bitIdx)) {
155*16467b97STreehugger Robot				if (theBits[longNo] & (1LL << bitIdx)) {
156*16467b97STreehugger Robot					CFBitVectorSetBitAtIndex(bitVector, bitIdx+(longNo*(sizeof(unsigned long long)*8)), 1);
157*16467b97STreehugger Robot				}
158*16467b97STreehugger Robot			}
159*16467b97STreehugger Robot		}
160*16467b97STreehugger Robot	}
161*16467b97STreehugger Robot	return self;
162*16467b97STreehugger Robot}
163*16467b97STreehugger Robot
164*16467b97STreehugger Robot// Initialize bit vector with an array of anything. Just test the boolValue and set the corresponding bit.
165*16467b97STreehugger Robot// Note: This is big-endian!
166*16467b97STreehugger Robot- (ANTLRBitSet *) initWithArrayOfBits:(NSArray *)theArray
167*16467b97STreehugger Robot{
168*16467b97STreehugger Robot	if ((self = [super init]) != nil) {
169*16467b97STreehugger Robot        bitVector = CFBitVectorCreateMutable ( kCFAllocatorDefault, 0 );
170*16467b97STreehugger Robot		id value;
171*16467b97STreehugger Robot		int bit = 0;
172*16467b97STreehugger Robot		for (value in theArray) {
173*16467b97STreehugger Robot			if ([value boolValue] == YES) {
174*16467b97STreehugger Robot                [self add:bit];
175*16467b97STreehugger Robot				//CFBitVectorSetBitAtIndex(bitVector, bit, 1);
176*16467b97STreehugger Robot			}
177*16467b97STreehugger Robot			bit++;
178*16467b97STreehugger Robot		}
179*16467b97STreehugger Robot	}
180*16467b97STreehugger Robot	return self;
181*16467b97STreehugger Robot}
182*16467b97STreehugger Robot
183*16467b97STreehugger Robot- (void)dealloc
184*16467b97STreehugger Robot{
185*16467b97STreehugger Robot#ifdef DEBUG_DEALLOC
186*16467b97STreehugger Robot    NSLog( @"called dealloc in ANTLRBitSet" );
187*16467b97STreehugger Robot#endif
188*16467b97STreehugger Robot	CFRelease(bitVector);
189*16467b97STreehugger Robot	[super dealloc];
190*16467b97STreehugger Robot}
191*16467b97STreehugger Robot
192*16467b97STreehugger Robot	// operations
193*16467b97STreehugger Robot#pragma mark Operations
194*16467b97STreehugger Robot// return a copy of (self|aBitSet)
195*16467b97STreehugger Robot- (ANTLRBitSet *) or:(ANTLRBitSet *) aBitSet
196*16467b97STreehugger Robot{
197*16467b97STreehugger Robot	ANTLRBitSet *bitsetCopy = [self mutableCopyWithZone:nil];
198*16467b97STreehugger Robot	[bitsetCopy orInPlace:aBitSet];
199*16467b97STreehugger Robot	return bitsetCopy;
200*16467b97STreehugger Robot}
201*16467b97STreehugger Robot
202*16467b97STreehugger Robot// perform a bitwise OR operation in place by changing underlying bit vector, growing it if necessary
203*16467b97STreehugger Robot- (void) orInPlace:(ANTLRBitSet *) aBitSet
204*16467b97STreehugger Robot{
205*16467b97STreehugger Robot	CFIndex selfCnt = CFBitVectorGetCount(bitVector);
206*16467b97STreehugger Robot	CFMutableBitVectorRef otherBitVector = [aBitSet _bitVector];
207*16467b97STreehugger Robot	CFIndex otherCnt = CFBitVectorGetCount(otherBitVector);
208*16467b97STreehugger Robot	CFIndex maxBitCnt = selfCnt > otherCnt ? selfCnt : otherCnt;
209*16467b97STreehugger Robot	CFBitVectorSetCount(bitVector,maxBitCnt);		// be sure to grow the CFBitVector manually!
210*16467b97STreehugger Robot
211*16467b97STreehugger Robot	CFIndex currIdx;
212*16467b97STreehugger Robot	for (currIdx = 0; currIdx < maxBitCnt; currIdx++) {
213*16467b97STreehugger Robot		if (CFBitVectorGetBitAtIndex(bitVector, currIdx) | CFBitVectorGetBitAtIndex(otherBitVector, currIdx)) {
214*16467b97STreehugger Robot			CFBitVectorSetBitAtIndex(bitVector, currIdx, 1);
215*16467b97STreehugger Robot		}
216*16467b97STreehugger Robot	}
217*16467b97STreehugger Robot}
218*16467b97STreehugger Robot
219*16467b97STreehugger Robot// set a bit, grow the bit vector if necessary
220*16467b97STreehugger Robot- (void) add:(NSUInteger) bit
221*16467b97STreehugger Robot{
222*16467b97STreehugger Robot	if ((CFIndex)bit >= CFBitVectorGetCount(bitVector))
223*16467b97STreehugger Robot		CFBitVectorSetCount(bitVector, bit+1);
224*16467b97STreehugger Robot	CFBitVectorSetBitAtIndex(bitVector, bit, 1);
225*16467b97STreehugger Robot}
226*16467b97STreehugger Robot
227*16467b97STreehugger Robot// unset a bit
228*16467b97STreehugger Robot- (void) remove:(NSUInteger) bit
229*16467b97STreehugger Robot{
230*16467b97STreehugger Robot	CFBitVectorSetBitAtIndex(bitVector, bit, 0);
231*16467b97STreehugger Robot}
232*16467b97STreehugger Robot
233*16467b97STreehugger Robot- (void) setAllBits:(BOOL) aState
234*16467b97STreehugger Robot{
235*16467b97STreehugger Robot    for( NSInteger bit=0; bit < CFBitVectorGetCount(bitVector); bit++ ) {
236*16467b97STreehugger Robot        CFBitVectorSetBitAtIndex(bitVector, bit, aState);
237*16467b97STreehugger Robot    }
238*16467b97STreehugger Robot}
239*16467b97STreehugger Robot
240*16467b97STreehugger Robot// returns the number of bits in the bit vector.
241*16467b97STreehugger Robot- (NSInteger) numBits
242*16467b97STreehugger Robot{
243*16467b97STreehugger Robot    // return CFBitVectorGetCount(bitVector);
244*16467b97STreehugger Robot    return CFBitVectorGetCountOfBit(bitVector, CFRangeMake(0, CFBitVectorGetCount(bitVector)), 1);
245*16467b97STreehugger Robot}
246*16467b97STreehugger Robot
247*16467b97STreehugger Robot// returns the number of bits in the bit vector.
248*16467b97STreehugger Robot- (NSUInteger) size
249*16467b97STreehugger Robot{
250*16467b97STreehugger Robot    return CFBitVectorGetCount(bitVector);
251*16467b97STreehugger Robot}
252*16467b97STreehugger Robot
253*16467b97STreehugger Robot- (void) setSize:(NSUInteger) nBits
254*16467b97STreehugger Robot{
255*16467b97STreehugger Robot    CFBitVectorSetCount( bitVector, nBits );
256*16467b97STreehugger Robot}
257*16467b97STreehugger Robot
258*16467b97STreehugger Robot#pragma mark Informational
259*16467b97STreehugger Robot// return a bitmask representation of this bitvector for easy operations
260*16467b97STreehugger Robot- (unsigned long long) bitMask:(NSUInteger) bitNumber
261*16467b97STreehugger Robot{
262*16467b97STreehugger Robot	return 1LL << bitNumber;
263*16467b97STreehugger Robot}
264*16467b97STreehugger Robot
265*16467b97STreehugger Robot// test a bit (no pun intended)
266*16467b97STreehugger Robot- (BOOL) member:(NSUInteger) bitNumber
267*16467b97STreehugger Robot{
268*16467b97STreehugger Robot	return CFBitVectorGetBitAtIndex(bitVector,bitNumber) ? YES : NO;
269*16467b97STreehugger Robot}
270*16467b97STreehugger Robot
271*16467b97STreehugger Robot// are all bits off?
272*16467b97STreehugger Robot- (BOOL) isNil
273*16467b97STreehugger Robot{
274*16467b97STreehugger Robot	return ((CFBitVectorGetCountOfBit(bitVector, CFRangeMake(0,CFBitVectorGetCount(bitVector)), 1) == 0) ? YES : NO);
275*16467b97STreehugger Robot}
276*16467b97STreehugger Robot
277*16467b97STreehugger Robot// debugging aid. GDB invokes this automagically
278*16467b97STreehugger Robot// return a string representation of the bit vector, indicating by their bitnumber which bits are set
279*16467b97STreehugger Robot- (NSString *) description
280*16467b97STreehugger Robot{
281*16467b97STreehugger Robot	CFIndex length = CFBitVectorGetCount(bitVector);
282*16467b97STreehugger Robot	CFIndex currBit;
283*16467b97STreehugger Robot	NSMutableString *descString = [NSMutableString  stringWithString:@"{"];
284*16467b97STreehugger Robot	BOOL haveInsertedBit = NO;
285*16467b97STreehugger Robot	for (currBit = 0; currBit < length; currBit++) {
286*16467b97STreehugger Robot		if ( CFBitVectorGetBitAtIndex(bitVector, currBit) ) {
287*16467b97STreehugger Robot			if (haveInsertedBit) {
288*16467b97STreehugger Robot				[descString appendString:@","];
289*16467b97STreehugger Robot			}
290*16467b97STreehugger Robot			[descString appendFormat:@"%d", currBit];
291*16467b97STreehugger Robot			haveInsertedBit = YES;
292*16467b97STreehugger Robot		}
293*16467b97STreehugger Robot	}
294*16467b97STreehugger Robot	[descString appendString:@"}"];
295*16467b97STreehugger Robot	return descString;
296*16467b97STreehugger Robot}
297*16467b97STreehugger Robot
298*16467b97STreehugger Robot// return a string representation of the bit vector, indicating by their bitnumber which bits are set
299*16467b97STreehugger Robot- (NSString *) toString
300*16467b97STreehugger Robot{
301*16467b97STreehugger Robot
302*16467b97STreehugger Robot	return [self description];
303*16467b97STreehugger Robot}
304*16467b97STreehugger Robot
305*16467b97STreehugger Robot	// NSCopying
306*16467b97STreehugger Robot#pragma mark NSCopying support
307*16467b97STreehugger Robot
308*16467b97STreehugger Robot- (id) mutableCopyWithZone:(NSZone *) theZone
309*16467b97STreehugger Robot{
310*16467b97STreehugger Robot	ANTLRBitSet *newBitSet = [[ANTLRBitSet allocWithZone:theZone] initWithBitVector:CFBitVectorCreateMutableCopy(kCFAllocatorDefault,0,bitVector)];
311*16467b97STreehugger Robot	return newBitSet;
312*16467b97STreehugger Robot}
313*16467b97STreehugger Robot
314*16467b97STreehugger Robot- (CFMutableBitVectorRef) _bitVector
315*16467b97STreehugger Robot{
316*16467b97STreehugger Robot	return bitVector;
317*16467b97STreehugger Robot}
318*16467b97STreehugger Robot
319*16467b97STreehugger Robot@synthesize bitVector;
320*16467b97STreehugger Robot@end
321*16467b97STreehugger Robot
322*16467b97STreehugger RobotNSInteger max(NSInteger a, NSInteger b)
323*16467b97STreehugger Robot{
324*16467b97STreehugger Robot    return (a>b)?a:b;
325*16467b97STreehugger Robot}
326*16467b97STreehugger Robot
327