1 // This may look like C code, but it is really -*- C++ -*-
3 Copyright (C) 1988 Free Software Foundation
4 written by Doug Lea (dl@rocky.oswego.edu)
6 This file is part of GNU CC.
8 GNU CC is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY. No author or distributor
10 accepts responsibility to anyone for the consequences of using it
11 or for whether it serves any particular purpose or works at all,
12 unless he says so in writing. Refer to the GNU CC General Public
13 License for full details.
15 Everyone is granted permission to copy, modify and redistribute
16 GNU CC, but only under the conditions described in the
17 GNU CC General Public License. A copy of this license is
18 supposed to have been given to you along with GNU CC so you
19 can know your rights and responsibilities. It should be in a
20 file named COPYING. Among other things, the copyright notice
21 and this notice must be preserved on all copies.
30 #define _BitString_h 1
35 #define BITSTRBITS BITS(short)
39 unsigned int len
; // length in bits
40 unsigned short sz
; // allocated slots
41 unsigned short s
[1]; // bits start here
44 extern BitStrRep
* BStr_alloc(BitStrRep
*, const unsigned short*, int, int,int);
45 extern BitStrRep
* BStr_resize(BitStrRep
*, int);
46 extern BitStrRep
* BStr_copy(BitStrRep
*, const BitStrRep
*);
47 extern BitStrRep
* cmpl(const BitStrRep
*, BitStrRep
*);
48 extern BitStrRep
* and(const BitStrRep
*, const BitStrRep
*, BitStrRep
*);
49 extern BitStrRep
* or(const BitStrRep
*, const BitStrRep
*, BitStrRep
*);
50 extern BitStrRep
* xor(const BitStrRep
*, const BitStrRep
*, BitStrRep
*);
51 extern BitStrRep
* diff(const BitStrRep
*, const BitStrRep
*, BitStrRep
*);
52 extern BitStrRep
* cat(const BitStrRep
*, const BitStrRep
*, BitStrRep
*);
53 extern BitStrRep
* cat(const BitStrRep
*, unsigned int, BitStrRep
*);
54 extern BitStrRep
* lshift(const BitStrRep
*, int, BitStrRep
*);
67 BitStrBit(BitString
& v
, int p
);
68 BitStrBit(const BitStrBit
& b
);
70 operator unsigned int() const;
71 int operator = (unsigned int b
);
72 int operator == (unsigned int b
) const ;
73 int operator != (unsigned int b
) const ;
78 friend class BitString
;
79 friend class BitPattern
;
87 BitSubString(BitString
& x
, int p
, int l
);
88 BitSubString(const BitSubString
& x
);
92 void operator = (const BitString
&);
93 void operator = (const BitSubString
&);
103 friend class BitSubString
;
104 friend class BitPattern
;
108 int search(int, int, const unsigned short*, int, int) const;
109 int match(int, int, int, const unsigned short*,int,int) const;
110 BitSubString
_substr(int first
, int l
);
116 BitString(const BitString
&);
117 BitString(const BitSubString
& y
);
121 void operator = (unsigned int bit
);
122 void operator = (const BitString
& y
);
123 void operator = (const BitSubString
& y
);
125 // equality & subset tests
127 friend int operator == (const BitString
&, const BitString
&);
128 friend int operator != (const BitString
&, const BitString
&);
129 friend int operator < (const BitString
&, const BitString
&);
130 friend int operator <= (const BitString
&, const BitString
&);
131 friend int operator > (const BitString
&, const BitString
&);
132 friend int operator >= (const BitString
&, const BitString
&);
134 // procedural versions of operators
137 friend void and(const BitString
&, const BitString
&, BitString
&);
138 friend void or(const BitString
&, const BitString
&, BitString
&);
139 friend void xor(const BitString
&, const BitString
&, BitString
&);
140 friend void diff(const BitString
&, const BitString
&, BitString
&);
141 friend void cat(const BitString
&, const BitString
&, BitString
&);
142 friend void cat(const BitString
&, unsigned int, BitString
&);
143 friend void lshift(const BitString
&, int, BitString
&);
144 friend void rshift(const BitString
&, int, BitString
&);
146 friend void complement(const BitString
&, BitString
&);
148 friend int lcompare(const BitString
&, const BitString
&);
150 // assignment-based operators
151 // (constuctive versions decalred inline below
153 void operator |= (const BitString
&);
154 void operator &= (const BitString
&);
155 void operator -= (const BitString
&);
156 void operator ^= (const BitString
&);
157 void operator += (const BitString
&);
158 void operator += (unsigned int b
);
159 void operator <<=(int s
);
160 void operator >>=(int s
);
164 // individual bit manipulation
167 void set(int from
, int to
);
171 void clear(int from
, int to
);
174 void invert(int pos
);
175 void invert(int from
, int to
);
177 int test(int pos
) const;
178 int test(int from
, int to
) const;
180 void assign(int p
, unsigned int bit
);
184 BitStrBit
operator [] (int pos
);
188 int first(unsigned int bit
= 1) const;
189 int last(unsigned int b
= 1) const;
191 int next(int pos
, unsigned int b
= 1) const;
192 int previous(int pos
, unsigned int b
= 1) const;
194 // searching & matching
196 int index(unsigned int bit
, int startpos
= 0) const ;
197 int index(const BitString
&, int startpos
= 0) const;
198 int index(const BitSubString
&, int startpos
= 0) const;
199 int index(const BitPattern
&, int startpos
= 0) const;
201 int contains(const BitString
&) const;
202 int contains(const BitSubString
&) const;
203 int contains(const BitPattern
&) const;
205 int contains(const BitString
&, int pos
) const;
206 int contains(const BitSubString
&, int pos
) const;
207 int contains(const BitPattern
&, int pos
) const;
209 int matches(const BitString
&, int pos
= 0) const;
210 int matches(const BitSubString
&, int pos
= 0) const;
211 int matches(const BitPattern
&, int pos
= 0) const;
213 // BitSubString extraction
215 BitSubString
at(int pos
, int len
);
216 BitSubString
at(const BitString
&, int startpos
= 0);
217 BitSubString
at(const BitSubString
&, int startpos
= 0);
218 BitSubString
at(const BitPattern
&, int startpos
= 0);
220 BitSubString
before(int pos
);
221 BitSubString
before(const BitString
&, int startpos
= 0);
222 BitSubString
before(const BitSubString
&, int startpos
= 0);
223 BitSubString
before(const BitPattern
&, int startpos
= 0);
225 BitSubString
after(int pos
);
226 BitSubString
after(const BitString
&, int startpos
= 0);
227 BitSubString
after(const BitSubString
&, int startpos
= 0);
228 BitSubString
after(const BitPattern
&, int startpos
= 0);
230 // other friends & utilities
232 friend BitString
common_prefix(const BitString
&, const BitString
&,
234 friend BitString
common_suffix(const BitString
&, const BitString
&,
236 friend BitString
reverse(const BitString
&);
238 void right_trim(unsigned int bit
);
239 void left_trim(unsigned int bit
);
244 int count(unsigned int bit
= 1) const;
249 friend BitString
atoBitString(const char* s
, char f
='0', char t
='1');
250 friend const char* BitStringtoa(const BitString
&, char f
='0', char t
='1');
252 friend BitString
shorttoBitString(unsigned short);
253 friend BitString
longtoBitString(unsigned long);
255 friend ostream
& operator << (ostream
& s
, const BitString
&);
259 volatile void error(const char* msg
) const;
263 friend const char* BitPatterntoa(const BitPattern
& p
,
264 char f
='0',char t
='1',char x
='X');
265 friend BitPattern
atoBitPattern(const char* s
,
266 char f
='0',char t
='1',char x
='X');
279 BitPattern(const BitPattern
&);
280 BitPattern(const BitString
& p
, const BitString
& m
);
284 friend const char* BitPatterntoa(const BitPattern
&, char f
, char t
, char x
);
285 friend BitPattern
atoBitPattern(const char* s
, char f
,char t
, char x
);
286 friend ostream
& operator << (ostream
& s
, const BitPattern
&);
288 int search(const unsigned short*, int, int) const;
289 int match(const unsigned short* xs
, int, int, int) const;
294 BitString
operator & (const BitString
& x
, const BitString
& y
);
295 BitString
operator | (const BitString
& x
, const BitString
& y
);
296 BitString
operator ^ (const BitString
& x
, const BitString
& y
);
297 BitString
operator << (const BitString
& x
, int y
);
298 BitString
operator >> (const BitString
& x
, int y
);
299 BitString
operator - (const BitString
& x
, const BitString
& y
);
300 BitString
operator + (const BitString
& x
, const BitString
& y
);
301 BitString
operator + (const BitString
& x
, unsigned int y
);
302 BitString
operator ~ (const BitString
& x
);
303 int operator != (const BitString
& x
, const BitString
& y
);
304 int operator>(const BitString
& x
, const BitString
& y
);
305 int operator>=(const BitString
& x
, const BitString
& y
);
307 extern BitStrRep _nilBitStrRep
;
308 extern BitString _nil_BitString
;
310 // primitive bit extraction
312 // These must be inlined regardless of optimization.
314 inline int BitStr_index(int l
) { return (unsigned)(l
) / BITSTRBITS
; }
316 inline int BitStr_pos(int l
) { return l
& (BITSTRBITS
- 1); }
318 #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
320 // constructors & assignment
322 inline BitString::BitString() :rep(&_nilBitStrRep
) {}
324 inline BitString::BitString(const BitString
& x
) :rep(BStr_copy(0, x
.rep
)) {}
326 inline BitString::BitString(const BitSubString
& y
)
327 :rep (BStr_alloc(0, y
.S
.rep
->s
, y
.pos
, y
.pos
+y
.len
, y
.len
)) {}
329 inline BitString::~BitString()
331 if (rep
!= &_nilBitStrRep
) delete rep
;
334 #if defined(__GNUG__) && !defined(NO_NRV)
336 inline BitString
shorttoBitString(unsigned short w
) return r
338 r
.rep
= BStr_alloc(0, &w
, 0, BITSTRBITS
, BITSTRBITS
);
341 inline BitString
longtoBitString(unsigned long w
) return r
344 u
[0] = w
& ((unsigned short)(~(0)));
345 u
[1] = w
>> BITSTRBITS
;
346 r
.rep
= BStr_alloc(0, &u
[0], 0, 2*BITSTRBITS
, 2*BITSTRBITS
);
351 inline BitString
shorttoBitString(unsigned short w
)
353 BitString r
; r
.rep
= BStr_alloc(0, &w
, 0, BITSTRBITS
, BITSTRBITS
); return r
;
356 inline BitString
longtoBitString(unsigned long w
)
360 u
[0] = w
& ((unsigned short)(~(0)));
361 u
[1] = w
>> BITSTRBITS
;
362 r
.rep
= BStr_alloc(0, &u
[0], 0, 2*BITSTRBITS
, 2*BITSTRBITS
);
368 inline void BitString::operator = (const BitString
& y
)
370 rep
= BStr_copy(rep
, y
.rep
);
373 inline void BitString::operator = (unsigned int b
)
375 unsigned short bit
= b
;
376 rep
= BStr_alloc(rep
, &bit
, 0, 1, 1);
379 inline void BitString::operator=(const BitSubString
& y
)
381 rep
= BStr_alloc(rep
, y
.S
.rep
->s
, y
.pos
, y
.pos
+y
.len
, y
.len
);
384 inline BitSubString::BitSubString(const BitSubString
& x
)
385 :S(x
.S
), pos(x
.pos
), len(x
.len
) {}
387 inline BitSubString::BitSubString(BitString
& x
, int p
, int l
)
388 : S(x
), pos(p
), len(l
) {}
390 inline BitSubString::~BitSubString() {}
392 inline BitPattern::BitPattern(const BitString
& p
, const BitString
& m
)
393 :pattern(p
), mask(m
) {}
395 inline BitPattern::BitPattern(const BitPattern
& b
)
396 :pattern(b
.pattern
), mask(b
.mask
) {}
398 inline BitPattern::BitPattern() {}
399 inline BitPattern::~BitPattern() {}
402 // procedural versions of operators
404 inline void and(const BitString
& x
, const BitString
& y
, BitString
& r
)
406 r
.rep
= and(x
.rep
, y
.rep
, r
.rep
);
409 inline void or(const BitString
& x
, const BitString
& y
, BitString
& r
)
411 r
.rep
= or(x
.rep
, y
.rep
, r
.rep
);
414 inline void xor(const BitString
& x
, const BitString
& y
, BitString
& r
)
416 r
.rep
= xor(x
.rep
, y
.rep
, r
.rep
);
419 inline void diff(const BitString
& x
, const BitString
& y
, BitString
& r
)
421 r
.rep
= diff(x
.rep
, y
.rep
, r
.rep
);
424 inline void cat(const BitString
& x
, const BitString
& y
, BitString
& r
)
426 r
.rep
= cat(x
.rep
, y
.rep
, r
.rep
);
429 inline void cat(const BitString
& x
, unsigned int y
, BitString
& r
)
431 r
.rep
= cat(x
.rep
, y
, r
.rep
);
434 inline void rshift(const BitString
& x
, int y
, BitString
& r
)
436 r
.rep
= lshift(x
.rep
, -y
, r
.rep
);
439 inline void lshift(const BitString
& x
, int y
, BitString
& r
)
441 r
.rep
= lshift(x
.rep
, y
, r
.rep
);
444 inline void complement(const BitString
& x
, BitString
& r
)
446 r
.rep
= cmpl(x
.rep
, r
.rep
);
452 inline void BitString::operator &= (const BitString
& y
)
454 and(*this, y
, *this);
458 inline void BitString::operator |= (const BitString
& y
)
463 inline void BitString::operator ^= (const BitString
& y
)
465 xor(*this, y
, *this);
468 inline void BitString::operator <<= (int y
)
470 lshift(*this, y
, *this);
473 inline void BitString::operator >>= (int y
)
475 rshift(*this, y
, *this);
478 inline void BitString::operator -= (const BitString
& y
)
480 diff(*this, y
, *this);
483 inline void BitString::operator += (const BitString
& y
)
485 cat(*this, y
, *this);
488 inline void BitString::operator += (unsigned int y
)
490 cat(*this, y
, *this);
493 inline void BitString::complement()
495 ::complement(*this, *this);
498 #if defined(__GNUG__) && !defined(NO_NRV)
500 inline BitString
operator & (const BitString
& x
, const BitString
& y
) return r
505 inline BitString
operator | (const BitString
& x
, const BitString
& y
) return r
510 inline BitString
operator ^ (const BitString
& x
, const BitString
& y
) return r
515 inline BitString
operator << (const BitString
& x
, int y
) return r
520 inline BitString
operator >> (const BitString
& x
, int y
) return r
525 inline BitString
operator - (const BitString
& x
, const BitString
& y
) return r
530 inline BitString
operator + (const BitString
& x
, const BitString
& y
) return r
535 inline BitString
operator + (const BitString
& x
, unsigned int y
) return r
540 inline BitString
operator ~ (const BitString
& x
) return r
547 inline BitString
operator & (const BitString
& x
, const BitString
& y
)
549 BitString r
; and(x
, y
, r
); return r
;
552 inline BitString
operator | (const BitString
& x
, const BitString
& y
)
554 BitString r
; or(x
, y
, r
); return r
;
557 inline BitString
operator ^ (const BitString
& x
, const BitString
& y
)
559 BitString r
; xor(x
, y
, r
); return r
;
562 inline BitString
operator << (const BitString
& x
, int y
)
564 BitString r
; lshift(x
, y
, r
); return r
;
567 inline BitString
operator >> (const BitString
& x
, int y
)
569 BitString r
; rshift(x
, y
, r
); return r
;
572 inline BitString
operator - (const BitString
& x
, const BitString
& y
)
574 BitString r
; diff(x
, y
, r
); return r
;
577 inline BitString
operator + (const BitString
& x
, const BitString
& y
)
579 BitString r
; cat(x
, y
, r
); return r
;
582 inline BitString
operator + (const BitString
& x
, unsigned int y
)
584 BitString r
; cat(x
, y
, r
); return r
;
587 inline BitString
operator ~ (const BitString
& x
)
589 BitString r
; complement(x
, r
); return r
;
596 inline int BitString::length() const
601 inline int BitString::empty() const
603 return rep
->len
== 0;
606 inline int BitString::index(const BitString
& y
, int startpos
) const
608 return search(startpos
, rep
->len
, y
.rep
->s
, 0, y
.rep
->len
);
611 inline int BitString::index(const BitSubString
& y
, int startpos
) const
613 return search(startpos
, rep
->len
, y
.S
.rep
->s
, y
.pos
, y
.pos
+y
.len
);
616 inline int BitString::contains(const BitString
& y
) const
618 return search(0, rep
->len
, y
.rep
->s
, 0, y
.rep
->len
) >= 0;
621 inline int BitString::contains(const BitSubString
& y
) const
623 return search(0, rep
->len
, y
.S
.rep
->s
, y
.pos
, y
.pos
+y
.len
) >= 0;
626 inline int BitString::contains(const BitString
& y
, int p
) const
628 return match(p
, rep
->len
, 0, y
.rep
->s
, 0, y
.rep
->len
);
631 inline int BitString::matches(const BitString
& y
, int p
) const
633 return match(p
, rep
->len
, 1, y
.rep
->s
, 0, y
.rep
->len
);
636 inline int BitString::contains(const BitSubString
& y
, int p
) const
638 return match(p
, rep
->len
, 0, y
.S
.rep
->s
, y
.pos
, y
.pos
+y
.len
);
641 inline int BitString::matches(const BitSubString
& y
, int p
) const
643 return match(p
, rep
->len
, 1, y
.S
.rep
->s
, y
.pos
, y
.pos
+y
.len
);
646 inline int BitString::contains(const BitPattern
& r
) const
648 return r
.search(rep
->s
, 0, rep
->len
) >= 0;
651 inline int BitString::contains(const BitPattern
& r
, int p
) const
653 return r
.match(rep
->s
, p
, rep
->len
, 0);
656 inline int BitString::matches(const BitPattern
& r
, int p
) const
658 return r
.match(rep
->s
, p
, rep
->len
, 1);
661 inline int BitString::index(const BitPattern
& r
, int startpos
) const
663 return r
.search(rep
->s
, startpos
, rep
->len
);
666 inline int BitSubString::length() const
671 inline int BitSubString::empty() const
676 inline int operator != (const BitString
& x
, const BitString
& y
)
681 inline int operator>(const BitString
& x
, const BitString
& y
)
686 inline int operator>=(const BitString
& x
, const BitString
& y
)
691 inline int BitString::first(unsigned int b
) const
696 inline int BitString::last(unsigned int b
) const
698 return previous(rep
->len
, b
);
701 inline int BitString::index(unsigned int bit
, int startpos
) const
704 return next(startpos
- 1, bit
);
706 return previous(rep
->len
+ startpos
+ 1, bit
);
709 inline void BitString::right_trim(unsigned int b
)
711 int nb
= (b
== 0)? 1 : 0;
712 rep
= BStr_resize(rep
, previous(rep
->len
, nb
) + 1);
715 inline void BitString::left_trim(unsigned int b
)
717 int nb
= (b
== 0)? 1 : 0;
718 int p
= next(-1, nb
);
719 rep
= BStr_alloc(rep
, rep
->s
, p
, rep
->len
, rep
->len
- p
);
722 inline int BitString::test(int i
) const
724 return ((unsigned)(i
) >= rep
->len
)? 0 :
725 ((rep
->s
[BitStr_index(i
)] & (1 << (BitStr_pos(i
)))) != 0);
731 inline BitStrBit::BitStrBit(const BitStrBit
& b
) :src(b
.src
), pos(b
.pos
) {}
733 inline BitStrBit::BitStrBit(BitString
& v
, int p
) :src(v
), pos(p
) {}
735 inline BitStrBit::~BitStrBit() {}
737 inline BitStrBit::operator unsigned int() const
739 return src
.test(pos
);
742 inline int BitStrBit::operator = (unsigned int b
)
744 src
.assign(pos
, b
); return b
;
747 inline int BitStrBit::operator == (unsigned int b
) const
749 return src
.test(pos
) == b
;
752 inline int BitStrBit::operator != (unsigned int b
) const
754 return src
.test(pos
) != b
;
757 inline BitStrBit
BitString::operator [] (int i
)
759 if ((unsigned)(i
) >= rep
->len
) error("illegal bit index");
760 return BitStrBit(*this, i
);
763 inline BitSubString
BitString::_substr(int first
, int l
)
765 if (first
< 0 || l
<= 0 || (unsigned)(first
+ l
) > rep
->len
)
766 return BitSubString(_nil_BitString
, 0, 0) ;
768 return BitSubString(*this, first
, l
);