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