aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/antlr3_cpp_runtime/include/antlr3bitset.inl
blob: 64318ea0ead5c6b1745beddd28151832de0813f4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
namespace antlr3 {

template <class ImplTraits>
ANTLR_INLINE BitsetList<ImplTraits>::BitsetList()
{
	m_bits = NULL;
	m_length  = 0;
}

template <class ImplTraits>
ANTLR_INLINE BitsetList<ImplTraits>::BitsetList( ANTLR_BITWORD* bits, ANTLR_UINT32 length )
{
	m_bits = bits;
	m_length  = length;
}

template <class ImplTraits>
ANTLR_INLINE ANTLR_BITWORD* BitsetList<ImplTraits>::get_bits() const
{
	return m_bits;
}

template <class ImplTraits>
ANTLR_INLINE ANTLR_UINT32 BitsetList<ImplTraits>::get_length() const
{
	return m_length;
}

template <class ImplTraits>
ANTLR_INLINE void BitsetList<ImplTraits>::set_bits( ANTLR_BITWORD* bits )
{
	m_bits = bits;
}

template <class ImplTraits>
ANTLR_INLINE void BitsetList<ImplTraits>::set_length( ANTLR_UINT32 length )
{
	m_length = length;
}

template <class ImplTraits>
typename BitsetList<ImplTraits>::BitsetType* BitsetList<ImplTraits>::bitsetLoad()
{
	// Allocate memory for the bitset structure itself
	// the input parameter is the bit number (0 based)
	// to include in the bitset, so we need at at least
	// bit + 1 bits. If any arguments indicate a 
	// a bit higher than the default number of bits (0 means default size)
	// then Add() will take care
	// of it.
	//
	BitsetType* bitset  = new BitsetType();

	if	(this != NULL)
	{
		// Now we can add the element bits into the set
		//
		ANTLR_UINT32 count=0;
		while (count < m_length)
		{
			if( bitset->get_blist().get_length() <= count)
				bitset->grow(count+1);

			typename ImplTraits::BitsetListType& blist = bitset->get_blist();
			blist.m_bits[count] = *(m_bits+count);
			count++;
		}
	}

	// return the new bitset
	//
	return  bitset;
}

template <class ImplTraits>
typename BitsetList<ImplTraits>::BitsetType* BitsetList<ImplTraits>::bitsetCopy()
{
	BitsetType*  bitset;
	ANTLR_UINT32 numElements = m_length;

    // Avoid memory thrashing at the expense of a few more bytes
    //
    if	(numElements < 8)
		numElements = 8;

    // Allocate memory for the bitset structure itself
    //
    bitset  = new Bitset<ImplTraits>(numElements);
	memcpy(bitset->get_blist().get_bits(), m_bits, numElements * sizeof(ANTLR_BITWORD));

    // All seems good
    //
    return  bitset;
}

template <class ImplTraits>
Bitset<ImplTraits>::Bitset( ANTLR_UINT32 numBits )
{
	// Avoid memory thrashing at the up front expense of a few bytes
	if	(numBits < (8 * ANTLR_BITSET_BITS))
		numBits = 8 * ANTLR_BITSET_BITS;

	// No we need to allocate the memory for the number of bits asked for
	// in multiples of ANTLR3_UINT64. 
	//
	ANTLR_UINT32 numelements	= ((numBits -1) >> ANTLR_BITSET_LOG_BITS) + 1;

	m_blist.set_bits( (ANTLR_BITWORD*) AllocPolicyType::alloc0(numelements * sizeof(ANTLR_BITWORD)));

	m_blist.set_length( numelements );
}

template <class ImplTraits>
Bitset<ImplTraits>::Bitset( const Bitset& bitset )
	:m_blist(bitset.m_blist)
{
}

template <class ImplTraits>
ANTLR_INLINE Bitset<ImplTraits>*  Bitset<ImplTraits>::clone() const
{
	Bitset*  bitset;

    // Allocate memory for the bitset structure itself
    //
    bitset  = new Bitset( ANTLR_BITSET_BITS * m_blist.get_length() );

    // Install the actual bits in the source set
    //
    memcpy(bitset->m_blist.get_bits(), m_blist.get_bits(), 
				m_blist.get_length() * sizeof(ANTLR_BITWORD) );

    // All seems good
    //
    return  bitset;
}

template <class ImplTraits>
Bitset<ImplTraits>*  Bitset<ImplTraits>::bor(Bitset* bitset2)
{
	Bitset*  bitset;

    if	(this == NULL)
		return bitset2->clone();

    if	(bitset2 == NULL)
		return	this->clone();

    // Allocate memory for the newly ordered bitset structure itself.
    //
    bitset  = this->clone();
    bitset->bitsetORInPlace(bitset2);
    return  bitset;
}

template <class ImplTraits>
void	 Bitset<ImplTraits>::borInPlace(Bitset* bitset2)
{
	ANTLR_UINT32   minimum;

    if	(bitset2 == NULL)
		return;

	// First make sure that the target bitset is big enough
    // for the new bits to be ored in.
    //
    if	( m_blist.get_length() < bitset2->m_blist.get_length() )
		this->growToInclude( bitset2->m_blist.get_length() * sizeof(ANTLR_BITWORD) );
    
    // Or the miniimum number of bits after any resizing went on
    //
    if	( m_blist.get_length() < bitset2->m_blist.get_length() )
		minimum = m_blist.get_length();
	else
		minimum = bitset2->m_blist.get_length();

	ANTLR_BITWORD* bits1 = m_blist.get_bits();
	ANTLR_BITWORD* bits2 = bitset2->m_blist.get_bits();
	for	(ANTLR_UINT32 i = minimum; i > 0; i--)
		bits1[i-1] |= bits2[i-1];
}

template <class ImplTraits>
ANTLR_UINT32 Bitset<ImplTraits>::size() const
{
    ANTLR_UINT32   degree;
    ANTLR_INT32   i;
    ANTLR_INT8    bit;
    
    // TODO: Come back to this, it may be faster to & with 0x01
    // then shift right a copy of the 4 bits, than shift left a constant of 1.
    // But then again, the optimizer might just work this out
    // anyway.
    //
    degree  = 0;
	ANTLR_BITWORD* bits = m_blist.get_bits();
    for	(i = m_blist.get_length() - 1; i>= 0; i--)
    {
		if  (bits[i] != 0)
		{
			for(bit = ANTLR_BITSET_BITS - 1; bit >= 0; bit--)
			{
				if((bits[i] & (((ANTLR_BITWORD)1) << bit)) != 0)
				{
					degree++;
				}
			}
		}
    }
    return degree;
}

template <class ImplTraits>
ANTLR_INLINE void	Bitset<ImplTraits>::add(ANTLR_INT32 bit)
{
	ANTLR_UINT32   word = Bitset::WordNumber(bit);

    if	(word	>= m_blist.get_length() )
		this->growToInclude(bit);
 
	ANTLR_BITWORD* bits = m_blist.get_bits();
	bits[word] |= Bitset::BitMask(bit);
}

template <class ImplTraits>
void	Bitset<ImplTraits>::grow(ANTLR_INT32 newSize)
{
	ANTLR_BITWORD*   newBits;

    // Space for newly sized bitset - TODO: come back to this and use realloc?, it may
    // be more efficient...
    //
    newBits =  (ANTLR_BITWORD*) AllocPolicyType::alloc0(newSize * sizeof(ANTLR_BITWORD) );
    if	( m_blist.get_bits() != NULL)
    {
		// Copy existing bits
		//
		memcpy( newBits, m_blist.get_bits(), m_blist.get_length() * sizeof(ANTLR_BITWORD) );

		// Out with the old bits... de de de derrr
		//
		AllocPolicyType::free( m_blist.get_bits() );
    }

    // In with the new bits... keerrrang.
    //
    m_blist.set_bits(newBits);
    m_blist.set_length(newSize);
}

template <class ImplTraits>
bool	Bitset<ImplTraits>::equals(Bitset* bitset2) const
{
    ANTLR_UINT32   minimum;
    ANTLR_UINT32   i;

    if	(this == NULL || bitset2 == NULL)
		return	false;

    // Work out the minimum comparison set
    //
    if	( m_blist.get_length() < bitset2->m_blist.get_length() )
		minimum = m_blist.get_length();
    else
		minimum = bitset2->m_blist.get_length();

    // Make sure explict in common bits are equal
    //
    for	(i = minimum - 1; i < minimum ; i--)
    {
		ANTLR_BITWORD* bits1 = m_blist.get_bits();
		ANTLR_BITWORD* bits2 = bitset2->m_blist.get_bits();
		if  ( bits1[i] != bits2[i])
			return false;
    }

    // Now make sure the bits of the larger set are all turned
    // off.
    //
    if	( m_blist.get_length() > minimum)
    {
		for (i = minimum ; i < m_blist.get_length(); i++)
		{
			ANTLR_BITWORD* bits = m_blist.get_bits();
			if(bits[i] != 0)
				return false;
		}
    }
    else if (bitset2->m_blist.get_length() > minimum)
    {
		ANTLR_BITWORD* bits = m_blist.get_bits();
		for (i = minimum; i < bitset2->m_blist.get_length(); i++)
		{
			if	( bits[i] != 0 )
				return	false;
		}
    }

    return  true;
}

template <class ImplTraits>
bool	Bitset<ImplTraits>::isMember(ANTLR_UINT32 bit) const
{
    ANTLR_UINT32    wordNo = Bitset::WordNumber(bit);

    if	(wordNo >= m_blist.get_length())
		return false;
    
	ANTLR_BITWORD* bits = m_blist.get_bits();
    if	( (bits[wordNo] & Bitset::BitMask(bit)) == 0)
		return false;
    else
		return true;
}

template <class ImplTraits>
ANTLR_INLINE ANTLR_UINT32 Bitset<ImplTraits>::numBits() const
{
	return  m_blist.get_length() << ANTLR_BITSET_LOG_BITS;
}

template <class ImplTraits>
ANTLR_INLINE typename ImplTraits::BitsetListType& Bitset<ImplTraits>::get_blist()
{
	return m_blist;
}

template <class ImplTraits>
ANTLR_INLINE void Bitset<ImplTraits>::remove(ANTLR_UINT32 bit)
{
    ANTLR_UINT32    wordNo = Bitset::WordNumber(bit);

    if	(wordNo < m_blist.get_length())
	{
		ANTLR_BITWORD* bits = m_blist.get_bits();
		bits[wordNo] &= ~(Bitset::BitMask(bit));
	}
}

template <class ImplTraits>
ANTLR_INLINE bool Bitset<ImplTraits>::isNilNode() const
{
	ANTLR_UINT32    i;
	ANTLR_BITWORD* bits = m_blist.get_bits();
	for	(i = m_blist.get_length() -1 ; i < m_blist.get_length(); i--)
	{
		if(bits[i] != 0)
			return false;
	}
	return  true;
}

template <class ImplTraits>
ANTLR_INT32* Bitset<ImplTraits>::toIntList() const
{
	ANTLR_UINT32   numInts;	    // How many integers we will need
    ANTLR_UINT32   numBits;	    // How many bits are in the set
    ANTLR_UINT32   i;
    ANTLR_UINT32   index;

    ANTLR_INT32*  intList;

    numInts = this->size() + 1;
    numBits = this->numBits();
 
    intList = (ANTLR_INT32*) AllocPolicyType::alloc(numInts * sizeof(ANTLR_INT32));
    
    intList[0] = numInts;

    // Enumerate the bits that are turned on
    //
    for	(i = 0, index = 1; i<numBits; i++)
    {
		if  (this->isMember(i) == true)
			intList[index++]    = i;
    }

    // Result set
    //
    return  intList;
}

template <class ImplTraits>
ANTLR_INLINE Bitset<ImplTraits>::~Bitset()
{
	if	(m_blist.get_bits() != NULL)
		AllocPolicyType::free(m_blist.get_bits());
    return;
}

template <class ImplTraits>
void	Bitset<ImplTraits>::growToInclude(ANTLR_INT32 bit)
{
	ANTLR_UINT32	bl;
	ANTLR_UINT32	nw;

	bl = (m_blist.get_length() << 1);
	nw = Bitset::NumWordsToHold(bit);

	if	(bl > nw)
		this->grow(bl);
	else
		this->grow(nw);
}

template <class ImplTraits>
ANTLR_INLINE ANTLR_UINT64	Bitset<ImplTraits>::BitMask(ANTLR_UINT32 bitNumber)
{
	return  ((ANTLR_UINT64)1) << (bitNumber & (ANTLR_BITSET_MOD_MASK));
}

template <class ImplTraits>
ANTLR_INLINE ANTLR_UINT32	Bitset<ImplTraits>::NumWordsToHold(ANTLR_UINT32 bit)
{
	return  (bit >> ANTLR_BITSET_LOG_BITS) + 1;
}

template <class ImplTraits>
ANTLR_INLINE ANTLR_UINT32	Bitset<ImplTraits>::WordNumber(ANTLR_UINT32 bit)
{
	return  bit >> ANTLR_BITSET_LOG_BITS;
}

template <class ImplTraits>
void Bitset<ImplTraits>::bitsetORInPlace(Bitset* bitset2)
{
	ANTLR_UINT32   minimum;
    ANTLR_UINT32   i;

    if	(bitset2 == NULL)
		return;

    // First make sure that the target bitset is big enough
    // for the new bits to be ored in.
    //
    if	( m_blist.get_length() < bitset2->m_blist.get_length() )
		this->growToInclude( bitset2->m_blist.get_length() * sizeof(ANTLR_BITWORD) );
    
    // Or the miniimum number of bits after any resizing went on
    //
    if	( m_blist.get_length() < bitset2->m_blist.get_length() )
		minimum = m_blist.get_length();
	else
		minimum = bitset2->m_blist.get_length();

	ANTLR_BITWORD* bits1 = m_blist.get_bits();
	ANTLR_BITWORD* bits2 = bitset2->m_blist.get_bits();
    for	(i = minimum; i > 0; i--)
		bits1[i-1] |= bits2[i-1];
}

template <class ImplTraits>
Bitset<ImplTraits>* Bitset<ImplTraits>::BitsetOf(ANTLR_INT32 bit)
{
	// Allocate memory for the bitset structure itself
    // the input parameter is the bit number (0 based)
    // to include in the bitset, so we need at at least
    // bit + 1 bits. If any arguments indicate a 
    // a bit higher than the default number of bits (0 menas default size)
    // then Add() will take care
    // of it.
    //
	Bitset<ImplTraits>* bitset = new Bitset<ImplTraits>(0);
	bitset->add(bit);
	return bitset;
}

template <class ImplTraits>
Bitset<ImplTraits>* Bitset<ImplTraits>::BitsetOf(ANTLR_INT32 bit1, ANTLR_INT32 bit2)
{
	Bitset<ImplTraits>* bitset = Bitset<ImplTraits>::BitsetOf(bit1);
	bitset->add(bit2);
	return bitset;
}

//static 
template <class ImplTraits>
Bitset<ImplTraits>* Bitset<ImplTraits>::BitsetFromList(const IntListType& list)
{
	// We have no idea what exactly is in the list
    // so create a default bitset and then just add stuff
    // as we enumerate.
    //
    Bitset<ImplTraits>* bitset  = new Bitset<ImplTraits>(0);
	for( int i = 0; i < list.size(); ++i )
		bitset->add( list[i] );

	return bitset;
}

}