Removed definition "LIB= rpc". We want libc.a to contain librpc.a, not
[unix-history] / .ref-BSD-4_3_Net_2 / usr / src / lib / libg++ / libg++ / BitString.cc
CommitLineData
a2f66f9a
WJ
1/*
2Copyright (C) 1988 Free Software Foundation
3 written by Doug Lea (dl@rocky.oswego.edu)
4
5This file is part of GNU CC.
6
7GNU CC is distributed in the hope that it will be useful,
8but WITHOUT ANY WARRANTY. No author or distributor
9accepts responsibility to anyone for the consequences of using it
10or for whether it serves any particular purpose or works at all,
11unless he says so in writing. Refer to the GNU CC General Public
12License for full details.
13
14Everyone is granted permission to copy, modify and redistribute
15GNU CC, but only under the conditions described in the
16GNU CC General Public License. A copy of this license is
17supposed to have been given to you along with GNU CC so you
18can know your rights and responsibilities. It should be in a
19file named COPYING. Among other things, the copyright notice
20and this notice must be preserved on all copies.
21*/
22
23/*
24 BitString class implementation
25 */
26
27#ifdef __GNUG__
28#pragma implementation
29#endif
30#include <BitString.h>
31#include <std.h>
32#include <values.h>
33#include <Obstack.h>
34#include <AllocRing.h>
35#include <new.h>
36
37volatile void BitString::error(const char* msg) const
38{
39 (*lib_error_handler)("BitString", msg);
40}
41
42// globals
43
44BitStrRep _nilBitStrRep = { 0, 1, {0} };
45
46BitString _nil_BitString;
47
48#define MINBitStrRep_SIZE 8
49#define MAXBitStrRep_SIZE ((1 << (SHORTBITS - 1)) - 1)
50
51#ifndef MALLOC_MIN_OVERHEAD
52#define MALLOC_MIN_OVERHEAD 4
53#endif
54
55#define ONES ((unsigned short)(~0L))
56#define MAXBIT (1 << (BITSTRBITS - 1))
57
58/*
59 * bit manipulation utilities
60*/
61
62// break things up into .s indices and positions
63
64inline static int BitStr_len(int l)
65{
66 return (unsigned)(l) / BITSTRBITS + 1;
67}
68
69
70// mask out low bits
71
72static inline unsigned short lmask(int p)
73{
74 if (p <= 0)
75 return ONES;
76 else
77 return ONES << p;
78}
79
80// mask out high bits
81
82static inline unsigned short rmask(int p)
83{
84 int s = BITSTRBITS - 1 - p;
85 if (s <= 0)
86 return ONES;
87 else
88 return ONES >> s;
89}
90
91
92// mask out unused bits in last word of rep
93
94inline static void check_last(BitStrRep* r)
95{
96 r->s[r->len / BITSTRBITS] &= ONES >> (BITSTRBITS - (r->len & (BITSTRBITS - 1)));
97}
98
99// merge bits from next word
100
101static inline unsigned short borrow_hi(const unsigned short a[], int ind,
102 int maxind, int p)
103{
104 if (ind < maxind)
105 return (a[ind] >> p) | (a[ind+1] << (BITSTRBITS - p));
106 else
107 return (a[ind] >> p);
108}
109
110// merge bits from prev word
111
112static inline unsigned short borrow_lo(const unsigned short a[], int ind,
113 int minind, int p)
114{
115 if (ind > minind)
116 return (a[ind] << (BITSTRBITS - 1 - p)) | (a[ind-1] >> (p + 1));
117 else
118 return (a[ind] << (BITSTRBITS - 1 - p));
119}
120
121// same with bounds check (for masks shorter than patterns)
122
123static inline unsigned short safe_borrow_hi(const unsigned short a[], int ind,
124 int maxind, int p)
125{
126 if (ind > maxind)
127 return 0;
128 else if (ind == maxind)
129 return(a[ind] >> p);
130 else
131 return (a[ind] >> p) | (a[ind+1] << (BITSTRBITS - p));
132}
133
134
135static inline unsigned short safe_borrow_lo(const unsigned short a[], int ind,
136 int minind, int p)
137{
138 if (ind < minind)
139 return 0;
140 else if (ind == minind)
141 return (a[ind] << (BITSTRBITS - 1 - p));
142 else
143 return (a[ind] << (BITSTRBITS - 1 - p)) | (a[ind-1] >> (p + 1));
144}
145
146// copy bits from a word boundary
147
148static inline void bit_copy(const unsigned short* ss, unsigned short* ds,
149 int nbits)
150{
151 if (ss != ds)
152 {
153 int n = (unsigned)(nbits) / BITSTRBITS;
154 if (n > 0) bcopy((void*)ss, (void*)ds, n * sizeof(short));
155 unsigned short m = ONES << (nbits & (BITSTRBITS - 1));
156 ds[n] = (ss[n] & ~m) | (ds[n] & m);
157 }
158}
159
160// clear bits from a word boundary
161
162static inline void bit_clear(unsigned short* ds, int nbits)
163{
164 int n = (unsigned)(nbits) / BITSTRBITS;
165 if (n > 0) bzero((void*)ds, n * sizeof(short));
166 ds[n] &= ONES << (nbits & (BITSTRBITS - 1));
167}
168
169
170
171// Copy ss from starts to fences-1 into ds starting at startd.
172// This will work even if ss & ds overlap.
173// The g++ optimizer does very good things with the messy shift expressions!
174
175static void bit_transfer(const unsigned short* ss, int starts, int fences,
176 unsigned short* ds, int startd)
177{
178 if (starts >= fences || ss == 0 || (ss == ds && starts == startd))
179 return;
180
181 int sind = BitStr_index(starts);
182 int spos = BitStr_pos(starts);
183 int dind = BitStr_index(startd);
184 int dpos = BitStr_pos(startd);
185
186 if (spos == 0 && dpos == 0)
187 {
188 bit_copy(&ss[sind], &ds[dind], fences - starts);
189 return;
190 }
191
192 int ends = fences - 1;
193 int endsind = BitStr_index(ends);
194 int endspos = BitStr_pos(ends);
195 int endd = startd + (ends - starts);
196 int enddind = BitStr_index(endd);
197 int enddpos = BitStr_pos(endd);
198
199 if (dind == enddind)
200 {
201 if (sind == endsind)
202 ds[dind] = (ds[dind] & ((ONES >> (BITSTRBITS - dpos)) |
203 (ONES << (enddpos + 1)))) |
204 (((ss[sind] >> spos) << dpos) &
205 ~((ONES >> (BITSTRBITS - dpos)) |
206 (ONES << (enddpos + 1))));
207 else
208 ds[dind] = (ds[dind] & ((ONES >> (BITSTRBITS - dpos)) |
209 (ONES << (enddpos + 1)))) |
210 ((((ss[sind] >> spos) |
211 (ss[sind+1] << (BITSTRBITS - spos)))
212 << dpos) &
213 ~((ONES >> (BITSTRBITS - dpos)) |
214 (ONES << (enddpos + 1))));
215 return;
216 }
217 else if (sind == endsind)
218 {
219 unsigned short saveend = (ds[enddind] & (ONES << (enddpos + 1))) |
220 (((ss[sind] << (BITSTRBITS - 1 - endspos)) >>
221 (BITSTRBITS - 1 - enddpos)) & ~(ONES << (enddpos + 1)));
222 ds[dind] = (ds[dind] & (ONES >> (BITSTRBITS - dpos))) |
223 (((ss[sind] >> spos) << dpos) & ~(ONES >> (BITSTRBITS - dpos)));
224 ds[enddind] = saveend;
225 return;
226 }
227
228 unsigned short saveend = (ds[enddind] & (ONES << (enddpos + 1))) |
229 ((((ss[endsind] << (BITSTRBITS - 1 - endspos)) |
230 (ss[endsind-1] >> (endspos + 1))) >>
231 (BITSTRBITS - 1 - enddpos)) & ~(ONES << (enddpos + 1)));
232 unsigned short savestart = (ds[dind] & (ONES >> (BITSTRBITS - dpos))) |
233 ((((ss[sind] >> spos) | (ss[sind+1] << (BITSTRBITS - spos))) << dpos)
234 & ~(ONES >> (BITSTRBITS - dpos)));
235
236
237 if (ds != ss || startd < starts)
238 {
239 int pos = spos - dpos;
240 if (pos < 0)
241 pos += BITSTRBITS;
242 else
243 ++sind;
244
245 for (;;) // lag by one in case of overlaps
246 {
247 if (dind == enddind - 1)
248 {
249 ds[dind] = savestart;
250 ds[enddind] = saveend;
251 return;
252 }
253 else
254 {
255 unsigned short tmp = ss[sind] >> pos;
256 if (++sind <= endsind) tmp |= ss[sind] << (BITSTRBITS - pos);
257 ds[dind++] = savestart;
258 savestart = tmp;
259 }
260 }
261 }
262 else
263 {
264 int pos = endspos - enddpos;
265 if (pos <= 0)
266 {
267 pos += BITSTRBITS;
268 --endsind;
269 }
270 for (;;)
271 {
272 if (enddind == dind + 1)
273 {
274 ds[enddind] = saveend;
275 ds[dind] = savestart;
276 return;
277 }
278 else
279 {
280 unsigned short tmp = ss[endsind] << (BITSTRBITS - pos);
281 if (--endsind >= sind) tmp |= ss[endsind] >> pos;
282 ds[enddind--] = saveend;
283 saveend = tmp;
284 }
285 }
286 }
287}
288
289// allocate a new rep; pad to near a power of two
290
291inline static BitStrRep* BSnew(int newlen)
292{
293 unsigned int siz = sizeof(BitStrRep) + BitStr_len(newlen) * sizeof(short)
294 + MALLOC_MIN_OVERHEAD;
295 unsigned int allocsiz = MINBitStrRep_SIZE;;
296 while (allocsiz < siz) allocsiz <<= 1;
297 allocsiz -= MALLOC_MIN_OVERHEAD;
298 if (allocsiz >= MAXBitStrRep_SIZE * sizeof(short))
299 (*lib_error_handler)("BitString", "Requested length out of range");
300
301 BitStrRep* rep = (BitStrRep *) new char[allocsiz];
302 bzero(rep, allocsiz);
303 rep->sz = (allocsiz - sizeof(BitStrRep) + sizeof(short)) / sizeof(short);
304 return rep;
305}
306
307BitStrRep* BStr_alloc(BitStrRep* old, const unsigned short* src,
308 int startpos, int endp, int newlen)
309{
310 if (old == &_nilBitStrRep) old = 0;
311 if (newlen < 0) newlen = 0;
312 int news = BitStr_len(newlen);
313 BitStrRep* rep;
314 if (old == 0 || news > old->sz)
315 rep = BSnew(newlen);
316 else
317 rep = old;
318 rep->len = newlen;
319
320 if (src != 0 && endp > 0 && (src != rep->s || startpos > 0))
321 bit_transfer(src, startpos, endp, rep->s, 0);
322
323 check_last(rep);
324
325 if (old != rep && old != 0) delete old;
326
327 return rep;
328}
329
330BitStrRep* BStr_resize(BitStrRep* old, int newlen)
331{
332 BitStrRep* rep;
333 if (newlen < 0) newlen = 0;
334 int news = BitStr_len(newlen);
335 if (old == 0 || old == &_nilBitStrRep)
336 {
337 rep = BSnew(newlen);
338 }
339 else if (news > old->sz)
340 {
341 rep = BSnew(newlen);
342 bcopy(old->s, rep->s, BitStr_len(old->len) * sizeof(short));
343 delete old;
344 }
345 else
346 rep = old;
347
348 rep->len = newlen;
349 check_last(rep);
350 return rep;
351}
352
353BitStrRep* BStr_copy(BitStrRep* old, const BitStrRep* src)
354{
355 BitStrRep* rep;
356 if (old == src && old != &_nilBitStrRep) return old;
357 if (old == &_nilBitStrRep) old = 0;
358 if (src == &_nilBitStrRep) src = 0;
359 if (src == 0)
360 {
361 if (old == 0)
362 rep = BSnew(0);
363 else
364 rep = old;
365 rep->len = 0;
366 }
367 else
368 {
369 int newlen = src->len;
370 int news = BitStr_len(newlen);
371 if (old == 0 || news > old->sz)
372 {
373 rep = BSnew(newlen);
374 if (old != 0) delete old;
375 }
376 else
377 rep = old;
378
379 bcopy(src->s, rep->s, news * sizeof(short));
380 rep->len = newlen;
381 }
382 check_last(rep);
383 return rep;
384}
385
386
387int operator == (const BitString& x, const BitString& y)
388{
389 return x.rep->len == y.rep->len &&
390 bcmp((void*)x.rep->s, (void*)y.rep->s,
391 BitStr_len(x.rep->len) * sizeof(short)) == 0;
392}
393
394int operator <= (const BitString& x, const BitString& y)
395{
396 unsigned int xl = x.rep->len;
397 unsigned int yl = y.rep->len;
398 if (xl > yl)
399 return 0;
400
401 const unsigned short* xs = x.rep->s;
402 const unsigned short* topx = &(xs[BitStr_len(xl)]);
403 const unsigned short* ys = y.rep->s;
404
405 while (xs < topx)
406 {
407 unsigned short a = *xs++;
408 unsigned short b = *ys++;
409 if ((a | b) != b)
410 return 0;
411 }
412 return 1;
413}
414
415int operator < (const BitString& x, const BitString& y)
416{
417 unsigned short xl = x.rep->len;
418 unsigned short yl = y.rep->len;
419 if (xl > yl)
420 return 0;
421
422 const unsigned short* xs = x.rep->s;
423 const unsigned short* ys = y.rep->s;
424 const unsigned short* topx = &(xs[BitStr_len(xl)]);
425 const unsigned short* topy = &(ys[BitStr_len(yl)]);
426 int one_diff = 0;
427 while (xs < topx)
428 {
429 unsigned short a = *xs++;
430 unsigned short b = *ys++;
431 unsigned short c = a | b;
432 if (c != b)
433 return 0;
434 else if (c != a)
435 one_diff = 1;
436 }
437 if (one_diff)
438 return 1;
439 else
440 {
441 while (ys < topy)
442 if (*ys++ != 0)
443 return 1;
444 return 0;
445 }
446}
447
448int lcompare(const BitString& x, const BitString& y)
449{
450 unsigned int xl = x.rep->len;
451 unsigned int yl = y.rep->len;
452
453 const unsigned short* xs = x.rep->s;
454 const unsigned short* topx = &(xs[BitStr_len(xl)]);
455 const unsigned short* ys = y.rep->s;
456 const unsigned short* topy = &(ys[BitStr_len(yl)]);
457
458 while (xs < topx && ys < topy)
459 {
460 unsigned short a = *xs++;
461 unsigned short b = *ys++;
462 if (a != b)
463 {
464 unsigned short mask = 1;
465 for (;;)
466 {
467 unsigned short abit = (a & mask) != 0;
468 unsigned short bbit = (b & mask) != 0;
469 int diff = abit - bbit;
470 if (diff != 0)
471 return diff;
472 else
473 mask <<= 1;
474 }
475 }
476 }
477 return xl - yl;
478}
479
480int BitString::count(unsigned int b) const
481{
482 check_last(rep);
483 int xwds = BitStr_len(rep->len);
484 int xlast = BitStr_pos(rep->len);
485 int l = 0;
486 const unsigned short* s = rep->s;
487 const unsigned short* tops = &(s[xwds - 1]);
488 unsigned short a;
489 int i;
490 if (b != 0)
491 {
492 while (s < tops)
493 {
494 a = *s++;
495 for (i = 0; i < BITSTRBITS && a != 0; ++i)
496 {
497 if (a & 1)
498 ++l;
499 a >>= 1;
500 }
501 }
502 a = *s;
503 for (i = 0; i < xlast && a != 0; ++i)
504 {
505 if (a & 1)
506 ++l;
507 a >>= 1;
508 }
509 }
510 else
511 {
512 unsigned short maxbit = 1 << (BITSTRBITS - 1);
513 while (s < tops)
514 {
515 a = *s++;
516 for (i = 0; i < BITSTRBITS; ++i)
517 {
518 if ((a & maxbit) == 0)
519 ++l;
520 a <<= 1;
521 }
522 }
523 maxbit = 1 << (xlast - 1);
524 a = *s;
525 for (i = 0; i < xlast; ++i)
526 {
527 if ((a & maxbit) == 0)
528 ++l;
529 a <<= 1;
530 }
531 }
532 return l;
533}
534
535
536BitStrRep* cmpl(const BitStrRep* src, BitStrRep* r)
537{
538 r = BStr_copy(r, src);
539 unsigned short* rs = r->s;
540 unsigned short* topr = &(rs[BitStr_len(r->len)]);
541 while (rs < topr)
542 {
543 unsigned short cmp = ~(*rs);
544 *rs++ = cmp;
545 }
546 check_last(r);
547 return r;
548}
549
550
551BitStrRep* and(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
552{
553 int xrsame = x == r;
554 int yrsame = y == r;
555
556 unsigned int xl = x->len;
557 unsigned int yl = y->len;
558 unsigned int rl = (xl <= yl)? xl : yl;
559
560 r = BStr_resize(r, rl);
561
562 unsigned short* rs = r->s;
563 unsigned short* topr = &(rs[BitStr_len(rl)]);
564 const unsigned short* xs = (xrsame)? rs : x->s;
565 const unsigned short* ys = (yrsame)? rs : y->s;
566
567 while (rs < topr) *rs++ = *xs++ & *ys++;
568 check_last(r);
569 return r;
570}
571
572BitStrRep* or(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
573{
574 unsigned int xl = x->len;
575 unsigned int yl = y->len;
576 unsigned int rl = (xl >= yl)? xl : yl;
577 int xrsame = x == r;
578 int yrsame = y == r;
579
580 r = BStr_resize(r, rl);
581
582 unsigned short* rs = r->s;
583 const unsigned short* xs = (xrsame)? rs : x->s;
584 const unsigned short* topx = &(xs[BitStr_len(xl)]);
585 const unsigned short* ys = (yrsame)? rs : y->s;
586 const unsigned short* topy = &(ys[BitStr_len(yl)]);
587
588 if (xl <= yl)
589 {
590 while (xs < topx) *rs++ = *xs++ | *ys++;
591 if (rs != ys) while (ys < topy) *rs++ = *ys++;
592 }
593 else
594 {
595 while (ys < topy) *rs++ = *xs++ | *ys++;
596 if (rs != xs) while (xs < topx) *rs++ = *xs++;
597 }
598 check_last(r);
599 return r;
600}
601
602
603BitStrRep* xor(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
604{
605 unsigned int xl = x->len;
606 unsigned int yl = y->len;
607 unsigned int rl = (xl >= yl)? xl : yl;
608 int xrsame = x == r;
609 int yrsame = y == r;
610
611 r = BStr_resize(r, rl);
612
613 unsigned short* rs = r->s;
614 const unsigned short* xs = (xrsame)? rs : x->s;
615 const unsigned short* topx = &(xs[BitStr_len(xl)]);
616 const unsigned short* ys = (yrsame)? rs : y->s;
617 const unsigned short* topy = &(ys[BitStr_len(yl)]);
618
619 if (xl <= yl)
620 {
621 while (xs < topx) *rs++ = *xs++ ^ *ys++;
622 if (rs != ys) while (ys < topy) *rs++ = *ys++;
623 }
624 else
625 {
626 while (ys < topy) *rs++ = *xs++ ^ *ys++;
627 if (rs != xs) while (xs < topx) *rs++ = *xs++;
628 }
629 check_last(r);
630 return r;
631}
632
633
634BitStrRep* diff(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
635{
636 unsigned int xl = x->len;
637 unsigned int yl = y->len;
638 int xrsame = x == y;
639 int yrsame = y == r;
640
641 r = BStr_resize(r, xl);
642
643 unsigned short* rs = r->s;
644 const unsigned short* xs = (xrsame)? rs : x->s;
645 const unsigned short* topx = &(xs[BitStr_len(xl)]);
646 const unsigned short* ys = (yrsame)? rs : y->s;
647 const unsigned short* topy = &(ys[BitStr_len(yl)]);
648
649 if (xl <= yl)
650 {
651 while (xs < topx) *rs++ = *xs++ & ~(*ys++);
652 }
653 else
654 {
655 while (ys < topy) *rs++ = *xs++ & ~(*ys++);
656 if (rs != xs) while (xs < topx) *rs++ = *xs++;
657 }
658 check_last(r);
659 return r;
660}
661
662
663BitStrRep* cat(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
664{
665 unsigned int xl = x->len;
666 unsigned int yl = y->len;
667 unsigned int rl = xl + yl;
668 int xrsame = x == r;
669 int yrsame = y == r;
670
671 if (yrsame)
672 {
673 if (xrsame)
674 {
675 r = BStr_resize(r, rl);
676 bit_transfer(r->s, 0, yl, r->s, xl);
677 }
678 else
679 {
680 BitStrRep* tmp = BStr_copy(0, y);
681 r = BStr_resize(r, rl);
682 bit_copy(x->s, r->s, xl);
683 bit_transfer(tmp->s, 0, yl, r->s, xl);
684 delete tmp;
685 }
686 }
687 else
688 {
689 r = BStr_resize(r, rl);
690 if (!xrsame) bit_copy(x->s, r->s, xl);
691 bit_transfer(y->s, 0, yl, r->s, xl);
692 }
693 check_last(r);
694 return r;
695}
696
697BitStrRep* cat(const BitStrRep* x, unsigned int bit, BitStrRep* r)
698{
699 unsigned int xl = x->len;
700 int xrsame = x == r;
701 r = BStr_resize(r, xl+1);
702 if (!xrsame) bit_copy(x->s, r->s, xl);
703 if (bit)
704 r->s[BitStr_index(xl)] |= (1 << (BitStr_pos(xl)));
705 else
706 r->s[BitStr_index(xl)] &= ~(1 << (BitStr_pos(xl)));
707 check_last(r);
708 return r;
709}
710
711BitStrRep* lshift(const BitStrRep* x, int s, BitStrRep* r)
712{
713 int xrsame = x == r;
714 int xl = x->len;
715 int rl = xl + s;
716 if (s == 0)
717 r = BStr_copy(r, x);
718 else if (rl <= 0)
719 {
720 r = BStr_resize(r, 0);
721 r->len = 0;
722 r->s[0] = 0;
723 }
724 else if (s > 0)
725 {
726 r = BStr_resize(r, rl);
727 const unsigned short* xs = (xrsame)? r->s : x->s;
728 bit_transfer(xs, 0, xl, r->s, s);
729 bit_clear(r->s, s);
730 }
731 else if (xrsame)
732 {
733 r = BStr_resize(r, xl);
734 r->len = rl;
735 bit_transfer(r->s, -s, xl, r->s, 0);
736 }
737 else
738 {
739 r = BStr_resize(r, rl);
740 bit_transfer(x->s, -s, xl, r->s, 0);
741 }
742 check_last(r);
743 return r;
744}
745
746
747void BitString::set(int p)
748{
749 if (p < 0) error("Illegal bit index");
750 if (p >= rep->len) rep = BStr_resize(rep, p + 1);
751 rep->s[BitStr_index(p)] |= (1 << (BitStr_pos(p)));
752}
753
754void BitString::assign(int p, unsigned int bit)
755{
756 if (p < 0) error("Illegal bit index");
757 if (p >= rep->len) rep = BStr_resize(rep, p + 1);
758 if (bit)
759 rep->s[BitStr_index(p)] |= (1 << (BitStr_pos(p)));
760 else
761 rep->s[BitStr_index(p)] &= ~(1 << (BitStr_pos(p)));
762}
763
764void BitString::clear(int p)
765{
766 if (p < 0) error("Illegal bit index");
767 if (p >= rep->len) rep = BStr_resize(rep, p + 1);
768 rep->s[BitStr_index(p)] &= ~(1 << (BitStr_pos(p)));
769}
770
771void BitString::clear()
772{
773 if (rep == &_nilBitStrRep) return;
774 bit_clear(rep->s, rep->len);
775}
776
777void BitString::set()
778{
779 if (rep == &_nilBitStrRep) return;
780 unsigned short* s = rep->s;
781 unsigned short* tops = &(s[BitStr_len(rep->len)]);
782 while (s < tops) *s++ = ONES;
783 check_last(rep);
784}
785
786void BitString::invert(int p)
787{
788 if (p < 0) error("Illegal bit index");
789 if (p >= rep->len) rep = BStr_resize(rep, p + 1);
790 rep->s[BitStr_index(p)] ^= (1 << (BitStr_pos(p)));
791}
792
793
794
795void BitString::set(int from, int to)
796{
797 if (from < 0 || from > to) error("Illegal bit index");
798 if (to >= rep->len) rep = BStr_resize(rep, to+1);
799
800 int ind1 = BitStr_index(from);
801 int pos1 = BitStr_pos(from);
802 int ind2 = BitStr_index(to);
803 int pos2 = BitStr_pos(to);
804 unsigned short* s = &(rep->s[ind1]);
805 unsigned short m1 = lmask(pos1);
806 unsigned short m2 = rmask(pos2);
807 if (ind2 == ind1)
808 *s |= m1 & m2;
809 else
810 {
811 *s++ |= m1;
812 unsigned short* top = &(rep->s[ind2]);
813 *top |= m2;
814 while (s < top)
815 *s++ = ONES;
816 }
817}
818
819void BitString::clear(int from, int to)
820{
821 if (from < 0 || from > to) error("Illegal bit index");
822 if (to >= rep->len) rep = BStr_resize(rep, to+1);
823
824 int ind1 = BitStr_index(from);
825 int pos1 = BitStr_pos(from);
826 int ind2 = BitStr_index(to);
827 int pos2 = BitStr_pos(to);
828 unsigned short* s = &(rep->s[ind1]);
829 unsigned short m1 = lmask(pos1);
830 unsigned short m2 = rmask(pos2);
831 if (ind2 == ind1)
832 *s &= ~(m1 & m2);
833 else
834 {
835 *s++ &= ~m1;
836 unsigned short* top = &(rep->s[ind2]);
837 *top &= ~m2;
838 while (s < top)
839 *s++ = 0;
840 }
841}
842
843void BitString::invert(int from, int to)
844{
845 if (from < 0 || from > to) error("Illegal bit index");
846 if (to >= rep->len) rep = BStr_resize(rep, to+1);
847
848 int ind1 = BitStr_index(from);
849 int pos1 = BitStr_pos(from);
850 int ind2 = BitStr_index(to);
851 int pos2 = BitStr_pos(to);
852 unsigned short* s = &(rep->s[ind1]);
853 unsigned short m1 = lmask(pos1);
854 unsigned short m2 = rmask(pos2);
855 if (ind2 == ind1)
856 *s ^= m1 & m2;
857 else
858 {
859 *s++ ^= m1;
860 unsigned short* top = &(rep->s[ind2]);
861 *top ^= m2;
862 while (s < top)
863 {
864 unsigned short cmp = ~(*s);
865 *s++ = cmp;
866 }
867 }
868}
869
870
871int BitString::test(int from, int to) const
872{
873 if (from < 0 || from > to || from >= rep->len) return 0;
874
875 int ind1 = BitStr_index(from);
876 int pos1 = BitStr_pos(from);
877 int ind2 = BitStr_index(to);
878 int pos2 = BitStr_pos(to);
879
880 if (to >= rep->len)
881 {
882 ind2 = BitStr_index(rep->len - 1);
883 pos2 = BitStr_pos(rep->len - 1);
884 }
885
886 const unsigned short* s = &(rep->s[ind1]);
887 unsigned short m1 = lmask(pos1);
888 unsigned short m2 = rmask(pos2);
889
890 if (ind2 == ind1)
891 return (*s & m1 & m2) != 0;
892 else
893 {
894 if (*s++ & m1)
895 return 1;
896 unsigned short* top = &(rep->s[ind2]);
897 if (*top & m2)
898 return 1;
899 while (s < top)
900 if (*s++ != 0)
901 return 1;
902 return 0;
903 }
904}
905
906int BitString::next(int p, unsigned int b) const
907{
908 if (++p >= rep->len)
909 return -1;
910
911 int ind = BitStr_index(p);
912 int pos = BitStr_pos(p);
913 int l = BitStr_len(rep->len);
914
915 int j = ind;
916 const unsigned short* s = rep->s;
917 unsigned short a = s[j] >> pos;
918 int i = pos;
919
920 if (b != 0)
921 {
922 for (; i < BITSTRBITS && a != 0; ++i)
923 {
924 if (a & 1)
925 return j * BITSTRBITS + i;
926 a >>= 1;
927 }
928 for (++j; j < l; ++j)
929 {
930 a = s[j];
931 for (i = 0; i < BITSTRBITS && a != 0; ++i)
932 {
933 if (a & 1)
934 return j * BITSTRBITS + i;
935 a >>= 1;
936 }
937 }
938 return -1;
939 }
940 else
941 {
942 int last = BitStr_pos(rep->len);
943 if (j == l - 1)
944 {
945 for (; i < last; ++i)
946 {
947 if ((a & 1) == 0)
948 return j * BITSTRBITS + i;
949 a >>= 1;
950 }
951 return -1;
952 }
953
954 for (; i < BITSTRBITS; ++i)
955 {
956 if ((a & 1) == 0)
957 return j * BITSTRBITS + i;
958 a >>= 1;
959 }
960 for (++j; j < l - 1; ++j)
961 {
962 a = s[j];
963 if (a != ONES)
964 {
965 for (i = 0; i < BITSTRBITS; ++i)
966 {
967 if ((a & 1) == 0)
968 return j * BITSTRBITS + i;
969 a >>= 1;
970 }
971 }
972 }
973 a = s[j];
974 for (i = 0; i < last; ++i)
975 {
976 if ((a & 1) == 0)
977 return j * BITSTRBITS + i;
978 a >>= 1;
979 }
980 return -1;
981 }
982}
983
984int BitString::previous(int p, unsigned int b) const
985{
986 if (--p < 0)
987 return -1;
988
989 int ind = BitStr_index(p);
990 int pos = BitStr_pos(p);
991
992 const unsigned short* s = rep->s;
993
994 if (p >= rep->len)
995 {
996 ind = BitStr_index(rep->len - 1);
997 pos = BitStr_pos(rep->len - 1);
998 }
999
1000 int j = ind;
1001 unsigned short a = s[j];
1002
1003 int i = pos;
1004 unsigned short maxbit = 1 << pos;
1005
1006 if (b != 0)
1007 {
1008 for (; i >= 0 && a != 0; --i)
1009 {
1010 if (a & maxbit)
1011 return j * BITSTRBITS + i;
1012 a <<= 1;
1013 }
1014 maxbit = 1 << (BITSTRBITS - 1);
1015 for (--j; j >= 0; --j)
1016 {
1017 a = s[j];
1018 for (i = BITSTRBITS - 1; i >= 0 && a != 0; --i)
1019 {
1020 if (a & maxbit)
1021 return j * BITSTRBITS + i;
1022 a <<= 1;
1023 }
1024 }
1025 return -1;
1026 }
1027 else
1028 {
1029 if (a != ONES)
1030 {
1031 for (; i >= 0; --i)
1032 {
1033 if ((a & maxbit) == 0)
1034 return j * BITSTRBITS + i;
1035 a <<= 1;
1036 }
1037 }
1038 maxbit = 1 << (BITSTRBITS - 1);
1039 for (--j; j >= 0; --j)
1040 {
1041 a = s[j];
1042 if (a != ONES)
1043 {
1044 for (i = BITSTRBITS - 1; i >= 0; --i)
1045 {
1046 if ((a & maxbit) == 0)
1047 return j * BITSTRBITS + i;
1048 a <<= 1;
1049 }
1050 }
1051 }
1052 return -1;
1053 }
1054}
1055
1056
1057int BitString::search(int startx, int lengthx,
1058 const unsigned short* ys, int starty, int lengthy) const
1059{
1060 const unsigned short* xs = rep->s;
1061 int ylen = lengthy - starty;
1062 int righty = lengthy - 1;
1063 int rev = startx < 0;
1064 if (rev)
1065 {
1066 int leftx = 0;
1067 int rightx = lengthx + startx;
1068 startx = rightx - ylen + 1;
1069 if (ylen == 0) return startx;
1070 if (starty < 0 || righty < 0 || startx < 0 || startx >= lengthx) return -1;
1071
1072 int xind = BitStr_index(startx);
1073 int xpos = BitStr_pos(startx);
1074 int yind = BitStr_index(starty);
1075 int ypos = BitStr_pos(starty);
1076
1077 int rightxind = BitStr_index(rightx);
1078
1079 unsigned short x = borrow_hi(xs, xind, rightxind, xpos);
1080
1081 int rightyind = BitStr_index(righty);
1082 int rightypos = BitStr_pos(righty);
1083 unsigned short y = borrow_hi(ys, yind, rightyind, ypos);
1084 unsigned short ymask;
1085 if (yind == rightyind)
1086 ymask = rmask(rightypos);
1087 else if (yind+1 == rightyind)
1088 ymask = rmask(BITSTRBITS - ypos + rightypos + 1);
1089 else
1090 ymask = ONES;
1091
1092 int p = startx;
1093 for (;;)
1094 {
1095 if ((x & ymask) == y)
1096 {
1097 int xi = xind;
1098 int yi = yind;
1099 for (;;)
1100 {
1101 if (++yi > rightyind || ++xi > rightxind)
1102 return p;
1103 unsigned short tx = borrow_hi(xs, xi, rightxind, xpos);
1104 unsigned short ty = borrow_hi(ys, yi, rightyind, ypos);
1105 if (yi == rightyind)
1106 tx &= rmask(rightypos);
1107 else if (yi+1 == rightyind)
1108 tx &= rmask(BITSTRBITS - ypos + rightypos + 1);
1109 if (tx != ty)
1110 break;
1111 }
1112 }
1113 if (--p < leftx)
1114 return -1;
1115 if (--xpos < 0)
1116 {
1117 xpos = BITSTRBITS - 1;
1118 --xind;
1119 }
1120 x = borrow_hi(xs, xind, rightxind, xpos);
1121 }
1122 }
1123 else
1124 {
1125
1126 int rightx = lengthx - 1;
1127 if (ylen == 0) return startx;
1128 if (starty < 0 || righty < 0 || startx < 0 || startx >= lengthx) return -1;
1129
1130 int xind = BitStr_index(startx);
1131 int xpos = BitStr_pos(startx);
1132 int yind = BitStr_index(starty);
1133 int ypos = BitStr_pos(starty);
1134
1135 int rightxind = BitStr_index(rightx);
1136
1137 unsigned short x = borrow_hi(xs, xind, rightxind, xpos);
1138 unsigned short nextx = (xind >= rightxind) ? 0 : (xs[xind+1] >> xpos);
1139
1140 int rightyind = BitStr_index(righty);
1141 int rightypos = BitStr_pos(righty);
1142 unsigned short y = borrow_hi(ys, yind, rightyind, ypos);
1143 unsigned short ymask;
1144 if (yind == rightyind)
1145 ymask = rmask(rightypos);
1146 else if (yind+1 == rightyind)
1147 ymask = rmask(BITSTRBITS - ypos + rightypos + 1);
1148 else
1149 ymask = ONES;
1150
1151 int p = startx;
1152 for (;;)
1153 {
1154 if ((x & ymask) == y)
1155 {
1156 int xi = xind;
1157 int yi = yind;
1158 for (;;)
1159 {
1160 if (++yi > rightyind || ++xi > rightxind)
1161 return p;
1162 unsigned short tx = borrow_hi(xs, xi, rightxind, xpos);
1163 unsigned short ty = borrow_hi(ys, yi, rightyind, ypos);
1164 if (yi == rightyind)
1165 tx &= rmask(rightypos);
1166 else if (yi+1 == rightyind)
1167 tx &= rmask(BITSTRBITS - ypos + rightypos + 1);
1168 if (tx != ty)
1169 break;
1170 }
1171 }
1172 if (++p > rightx)
1173 return -1;
1174 if (++xpos == BITSTRBITS)
1175 {
1176 xpos = 0;
1177 x = xs[++xind];
1178 nextx = (xind >= rightxind) ? 0 : xs[xind+1];
1179 }
1180 else
1181 {
1182 x >>= 1;
1183 if (nextx & 1)
1184 x |= MAXBIT;
1185 nextx >>= 1;
1186 }
1187 }
1188 }
1189}
1190
1191
1192int BitPattern::search(const unsigned short* xs, int startx, int lengthx) const
1193{
1194 const unsigned short* ys = pattern.rep->s;
1195 const unsigned short* ms = mask.rep->s;
1196 int righty = pattern.rep->len - 1;
1197 int rightm = mask.rep->len - 1;
1198
1199 int rev = startx < 0;
1200 if (rev)
1201 {
1202 int leftx = 0;
1203 int rightx = lengthx + startx;
1204 startx = rightx - righty;
1205
1206 if (righty < 0) return startx;
1207 if (startx < 0 || startx >= lengthx) return -1;
1208
1209 int xind = BitStr_index(startx);
1210 int xpos = BitStr_pos(startx);
1211
1212 int rightxind = BitStr_index(rightx);
1213
1214 int rightmind = BitStr_index(rightm);
1215 int rightyind = BitStr_index(righty);
1216
1217 unsigned short x = safe_borrow_hi(xs, xind, rightxind, xpos);
1218 unsigned short m = safe_borrow_hi(ms, 0, rightmind, 0);
1219 unsigned short y = safe_borrow_hi(ys, 0, rightyind, 0) & m;
1220
1221 int p = startx;
1222 for (;;)
1223 {
1224 if ((x & m) == y)
1225 {
1226 int xi = xind;
1227 int yi = 0;
1228 for (;;)
1229 {
1230 if (++yi > rightyind || ++xi > rightxind)
1231 return p;
1232 unsigned short tm = safe_borrow_hi(ms, yi, rightmind, 0);
1233 unsigned short ty = safe_borrow_hi(ys, yi, rightyind, 0);
1234 unsigned short tx = safe_borrow_hi(xs, xi, rightxind, xpos);
1235 if ((tx & tm) != (ty & tm))
1236 break;
1237 }
1238 }
1239 if (--p < leftx)
1240 return -1;
1241 if (--xpos < 0)
1242 {
1243 xpos = BITSTRBITS - 1;
1244 --xind;
1245 }
1246 x = safe_borrow_hi(xs, xind, rightxind, xpos);
1247 }
1248 }
1249 else
1250 {
1251
1252 int rightx = lengthx - 1;
1253
1254 if (righty < 0) return startx;
1255 if (startx < 0 || startx >= lengthx) return -1;
1256
1257 int xind = BitStr_index(startx);
1258 int xpos = BitStr_pos(startx);
1259
1260 int rightxind = BitStr_index(rightx);
1261
1262 int rightmind = BitStr_index(rightm);
1263 int rightyind = BitStr_index(righty);
1264
1265 unsigned short x = safe_borrow_hi(xs, xind, rightxind, xpos);
1266 unsigned short m = safe_borrow_hi(ms, 0, rightmind, 0);
1267 unsigned short y = safe_borrow_hi(ys, 0, rightyind, 0) & m;
1268
1269 unsigned short nextx = (xind >= rightxind) ? 0 : (xs[xind+1] >> xpos);
1270
1271 int p = startx;
1272 for (;;)
1273 {
1274 if ((x & m) == y)
1275 {
1276 int xi = xind;
1277 int yi = 0;
1278 for (;;)
1279 {
1280 if (++yi > rightyind || ++xi > rightxind)
1281 return p;
1282 unsigned short tm = safe_borrow_hi(ms, yi, rightmind, 0);
1283 unsigned short ty = safe_borrow_hi(ys, yi, rightyind, 0);
1284 unsigned short tx = safe_borrow_hi(xs, xi, rightxind, xpos);
1285 if ((tx & tm) != (ty & tm))
1286 break;
1287 }
1288 }
1289 if (++p > rightx)
1290 return -1;
1291 if (++xpos == BITSTRBITS)
1292 {
1293 xpos = 0;
1294 x = xs[++xind];
1295 nextx = (xind >= rightxind) ? 0 : xs[xind+1];
1296 }
1297 else
1298 {
1299 x >>= 1;
1300 if (nextx & 1)
1301 x |= MAXBIT;
1302 nextx >>= 1;
1303 }
1304 }
1305 }
1306}
1307
1308int BitString::match(int startx, int lengthx, int exact,
1309 const unsigned short* ys, int starty, int yl) const
1310{
1311 const unsigned short* xs = rep->s;
1312 int ylen = yl - starty;
1313 int righty = yl - 1;
1314
1315 int rightx;
1316 int rev = startx < 0;
1317 if (rev)
1318 {
1319 rightx = lengthx + startx;
1320 startx = rightx - ylen + 1;
1321 if (exact && startx != 0)
1322 return 0;
1323 }
1324 else
1325 {
1326 rightx = lengthx - 1;
1327 if (exact && rightx - startx != righty)
1328 return 0;
1329 }
1330
1331 if (ylen == 0) return 1;
1332 if (righty < 0 || startx < 0 || startx >= lengthx) return 0;
1333
1334 int xi = BitStr_index(startx);
1335 int xpos = BitStr_pos(startx);
1336 int yi = BitStr_index(starty);
1337 int ypos = BitStr_pos(starty);
1338
1339 int rightxind = BitStr_index(rightx);
1340 int rightyind = BitStr_index(righty);
1341 int rightypos = BitStr_pos(righty);
1342
1343 for (;;)
1344 {
1345 unsigned short x = borrow_hi(xs, xi, rightxind, xpos);
1346 unsigned short y = borrow_hi(ys, yi, rightyind, ypos);
1347 if (yi == rightyind)
1348 x &= rmask(rightypos);
1349 else if (yi+1 == rightyind)
1350 x &= rmask(BITSTRBITS - ypos + rightypos + 1);
1351 if (x != y)
1352 return 0;
1353 else if (++yi > rightyind || ++xi > rightxind)
1354 return 1;
1355 }
1356}
1357
1358int BitPattern::match(const unsigned short* xs, int startx,
1359 int lengthx, int exact) const
1360{
1361 const unsigned short* ys = pattern.rep->s;
1362 int righty = pattern.rep->len - 1;
1363 unsigned short* ms = mask.rep->s;
1364 int rightm = mask.rep->len - 1;
1365
1366 int rightx;
1367 int rev = startx < 0;
1368 if (rev)
1369 {
1370 rightx = lengthx + startx;
1371 startx = rightx - righty;
1372 if (exact && startx != 0)
1373 return 0;
1374 }
1375 else
1376 {
1377 rightx = lengthx - 1;
1378 if (exact && rightx - startx != righty)
1379 return 0;
1380 }
1381
1382 if (righty < 0) return 1;
1383 if (startx < 0 || startx >= lengthx) return 0;
1384
1385 int xind = BitStr_index(startx);
1386 int xpos = BitStr_pos(startx);
1387 int yind = 0;
1388
1389 int rightxind = BitStr_index(rightx);
1390 int rightyind = BitStr_index(righty);
1391 int rightmind = BitStr_index(rightm);
1392
1393 for(;;)
1394 {
1395 unsigned short m = safe_borrow_hi(ms, yind, rightmind, 0);
1396 unsigned short x = safe_borrow_hi(xs, xind, rightxind, xpos) & m;
1397 unsigned short y = safe_borrow_hi(ys, yind, rightyind, 0) & m;
1398 if (x != y)
1399 return 0;
1400 else if (++yind > rightyind || ++xind > rightxind)
1401 return 1;
1402 }
1403}
1404
1405void BitSubString::operator = (const BitString& y)
1406{
1407 if (&S == &_nil_BitString) return;
1408 BitStrRep* targ = S.rep;
1409
1410 int ylen = y.rep->len;
1411 int sl = targ->len - len + ylen;
1412
1413 if (y.rep == targ || ylen > len)
1414 {
1415 BitStrRep* oldtarg = targ;
1416 targ = BStr_alloc(0, 0, 0, 0, sl);
1417 bit_transfer(oldtarg->s, 0, pos, targ->s, 0);
1418 bit_transfer(y.rep->s, 0, ylen, targ->s, pos);
1419 bit_transfer(oldtarg->s, pos+len, oldtarg->len, targ->s, pos + ylen);
1420 delete oldtarg;
1421 }
1422 else if (len == ylen)
1423 bit_transfer(y.rep->s, 0, len, targ->s, pos);
1424 else if (ylen < len)
1425 {
1426 bit_transfer(y.rep->s, 0, ylen, targ->s, pos);
1427 bit_transfer(targ->s, pos+len, targ->len, targ->s, pos + ylen);
1428 targ->len = sl;
1429 }
1430 check_last(targ);
1431 S.rep = targ;
1432}
1433
1434void BitSubString::operator = (const BitSubString& y)
1435{
1436 if (&S == &_nil_BitString) return;
1437 BitStrRep* targ = S.rep;
1438
1439 if (len == 0 || pos >= targ->len)
1440 return;
1441
1442 int sl = targ->len - len + y.len;
1443
1444 if (y.S.rep == targ || y.len > len)
1445 {
1446 BitStrRep* oldtarg = targ;
1447 targ = BStr_alloc(0, 0, 0, 0, sl);
1448 bit_copy(oldtarg->s, targ->s, pos);
1449 bit_transfer(y.S.rep->s, y.pos, y.pos+y.len, targ->s, pos);
1450 bit_transfer(oldtarg->s, pos+len, oldtarg->len, targ->s, pos + y.len);
1451 delete oldtarg;
1452 }
1453 else if (len == y.len)
1454 bit_transfer(y.S.rep->s, y.pos, y.pos+y.len, targ->s, pos);
1455 else if (y.len < len)
1456 {
1457 bit_transfer(y.S.rep->s, y.pos, y.pos+y.len, targ->s, pos);
1458 bit_transfer(targ->s, pos+len, targ->len, targ->s, pos + y.len);
1459 targ->len = sl;
1460 }
1461 check_last(targ);
1462 S.rep = targ;
1463}
1464
1465BitSubString BitString::at(int first, int len)
1466{
1467 return _substr(first, len);
1468}
1469
1470BitSubString BitString::before(int pos)
1471{
1472 return _substr(0, pos);
1473}
1474
1475BitSubString BitString::after(int pos)
1476{
1477 return _substr(pos + 1, rep->len - (pos + 1));
1478}
1479
1480BitSubString BitString::at(const BitString& y, int startpos)
1481{
1482 int first = search(startpos, rep->len, y.rep->s, 0, y.rep->len);
1483 return _substr(first, y.rep->len);
1484}
1485
1486BitSubString BitString::before(const BitString& y, int startpos)
1487{
1488 int last = search(startpos, rep->len, y.rep->s, 0, y.rep->len);
1489 return _substr(0, last);
1490}
1491
1492BitSubString BitString::after(const BitString& y, int startpos)
1493{
1494 int first = search(startpos, rep->len, y.rep->s, 0, y.rep->len);
1495 if (first >= 0) first += y.rep->len;
1496 return _substr(first, rep->len - first);
1497}
1498
1499
1500BitSubString BitString::at(const BitSubString& y, int startpos)
1501{
1502 int first = search(startpos, rep->len, y.S.rep->s, y.pos, y.len);
1503 return _substr(first, y.len);
1504}
1505
1506BitSubString BitString::before(const BitSubString& y, int startpos)
1507{
1508 int last = search(startpos, rep->len, y.S.rep->s, y.pos, y.len);
1509 return _substr(0, last);
1510}
1511
1512BitSubString BitString::after(const BitSubString& y, int startpos)
1513{
1514 int first = search(startpos, rep->len, y.S.rep->s, y.pos, y.len);
1515 if (first >= 0) first += y.len;
1516 return _substr(first, rep->len - first);
1517}
1518
1519BitSubString BitString::at(const BitPattern& r, int startpos)
1520{
1521 int first = r.search(rep->s, startpos, rep->len);
1522 return _substr(first, r.pattern.rep->len);
1523}
1524
1525
1526BitSubString BitString::before(const BitPattern& r, int startpos)
1527{
1528 int first = r.search(rep->s, startpos, rep->len);
1529 return _substr(0, first);
1530}
1531
1532BitSubString BitString::after(const BitPattern& r, int startpos)
1533{
1534 int first = r.search(rep->s, startpos, rep->len);
1535 if (first >= 0) first += r.pattern.rep->len;
1536 return _substr(first, rep->len - first);
1537}
1538
1539#if defined(__GNUG__) && !defined(NO_NRV)
1540
1541BitString common_prefix(const BitString& x, const BitString& y, int startpos)
1542 return r
1543{
1544 unsigned int xl = x.rep->len;
1545 unsigned int yl = y.rep->len;
1546
1547 int startx, starty;
1548 if (startpos < 0)
1549 {
1550 startx = xl + startpos;
1551 starty = yl + startpos;
1552 }
1553 else
1554 startx = starty = startpos;
1555
1556 if (startx < 0 || startx >= xl || starty < 0 || starty >= yl)
1557 return;
1558
1559 const unsigned short* xs = &(x.rep->s[BitStr_index(startx)]);
1560 unsigned short a = *xs++;
1561 int xp = startx;
1562
1563 const unsigned short* ys = &(y.rep->s[BitStr_index(starty)]);
1564 unsigned short b = *ys++;
1565 int yp = starty;
1566
1567 for(; xp < xl && yp < yl; ++xp, ++yp)
1568 {
1569 unsigned short xbit = 1 << (BitStr_pos(xp));
1570 unsigned short ybit = 1 << (BitStr_pos(yp));
1571 if (((a & xbit) == 0) != ((b & ybit) == 0))
1572 break;
1573 if (xbit == MAXBIT)
1574 a = *xs++;
1575 if (ybit == MAXBIT)
1576 b = *ys++;
1577 }
1578 r.rep = BStr_alloc(0, x.rep->s, startx, xp, xp - startx);
1579}
1580
1581
1582BitString common_suffix(const BitString& x, const BitString& y, int startpos)
1583 return r;
1584{
1585 unsigned int xl = x.rep->len;
1586 unsigned int yl = y.rep->len;
1587
1588 int startx, starty;
1589 if (startpos < 0)
1590 {
1591 startx = xl + startpos;
1592 starty = yl + startpos;
1593 }
1594 else
1595 startx = starty = startpos;
1596
1597 if (startx < 0 || startx >= xl || starty < 0 || starty >= yl)
1598 return;
1599
1600 const unsigned short* xs = &(x.rep->s[BitStr_index(startx)]);
1601 unsigned short a = *xs--;
1602 int xp = startx;
1603
1604 const unsigned short* ys = &(y.rep->s[BitStr_index(starty)]);
1605 unsigned short b = *ys--;
1606 int yp = starty;
1607
1608 for(; xp >= 0 && yp >= 0; --xp, --yp)
1609 {
1610 unsigned short xbit = 1 << (BitStr_pos(xp));
1611 unsigned short ybit = 1 << (BitStr_pos(yp));
1612 if (((a & xbit) == 0) != ((b & ybit) == 0))
1613 break;
1614 if (xbit == 1)
1615 a = *xs--;
1616 if (ybit == 1)
1617 b = *ys--;
1618 }
1619 r.rep = BStr_alloc(0, x.rep->s, xp+1, startx+1, startx - xp);
1620}
1621
1622BitString reverse(const BitString& x) return r
1623{
1624 unsigned int yl = x.rep->len;
1625 BitStrRep* y = BStr_resize(0, yl);
1626 if (yl > 0)
1627 {
1628 const unsigned short* ls = x.rep->s;
1629 unsigned short lm = 1;
1630 unsigned short* rs = &(y->s[BitStr_index(yl - 1)]);
1631 unsigned short rm = 1 << (BitStr_pos(yl - 1));
1632 for (unsigned int l = 0; l < yl; ++l)
1633 {
1634 if (*ls & lm)
1635 *rs |= rm;
1636 if (lm == MAXBIT)
1637 {
1638 ++ls;
1639 lm = 1;
1640 }
1641 else
1642 lm <<= 1;
1643 if (rm == 1)
1644 {
1645 --rs;
1646 rm = MAXBIT;
1647 }
1648 else
1649 rm >>= 1;
1650 }
1651 }
1652 r.rep = y;
1653}
1654
1655BitString atoBitString(const char* s, char f, char t) return res
1656{
1657 int sl = strlen(s);
1658 BitStrRep* r = BStr_resize(0, sl);
1659 if (sl != 0)
1660 {
1661 unsigned int rl = 0;
1662 unsigned short* rs = r->s;
1663 unsigned short a = 0;
1664 unsigned short m = 1;
1665 unsigned int i = 0;
1666 for(;;)
1667 {
1668 char ch = s[i];
1669 if (ch != t && ch != f)
1670 {
1671 *rs = a;
1672 break;
1673 }
1674 ++rl;
1675 if (ch == t)
1676 a |= m;
1677 if (++i == sl)
1678 {
1679 *rs = a;
1680 break;
1681 }
1682 else if (i % BITSTRBITS == 0)
1683 {
1684 *rs++ = a;
1685 a = 0;
1686 m = 1;
1687 }
1688 else
1689 m <<= 1;
1690 }
1691 r = BStr_resize(r, rl);
1692 }
1693 res.rep = r;
1694}
1695
1696BitPattern atoBitPattern(const char* s, char f,char t,char x) return r
1697{
1698 int sl = strlen(s);
1699 if (sl != 0)
1700 {
1701 unsigned int rl = 0;
1702 r.pattern.rep = BStr_resize(r.pattern.rep, sl);
1703 r.mask.rep = BStr_resize(r.mask.rep, sl);
1704 unsigned short* rs = r.pattern.rep->s;
1705 unsigned short* ms = r.mask.rep->s;
1706 unsigned short a = 0;
1707 unsigned short b = 0;
1708 unsigned short m = 1;
1709 unsigned int i = 0;
1710 for(;;)
1711 {
1712 char ch = s[i];
1713 if (ch != t && ch != f && ch != x)
1714 {
1715 *rs = a;
1716 *ms = b;
1717 break;
1718 }
1719 ++rl;
1720 if (ch == t)
1721 {
1722 a |= m;
1723 b |= m;
1724 }
1725 else if (ch == f)
1726 {
1727 b |= m;
1728 }
1729 if (++i == sl)
1730 {
1731 *rs = a;
1732 *ms = b;
1733 break;
1734 }
1735 else if (i % BITSTRBITS == 0)
1736 {
1737 *rs++ = a;
1738 *ms++ = b;
1739 a = 0;
1740 b = 0;
1741 m = 1;
1742 }
1743 else
1744 m <<= 1;
1745 }
1746 r.pattern.rep = BStr_resize(r.pattern.rep, rl);
1747 r.mask.rep = BStr_resize(r.mask.rep, rl);
1748 }
1749 return;
1750}
1751
1752#else /* NO_NRV */
1753
1754BitString common_prefix(const BitString& x, const BitString& y, int startpos)
1755{
1756 BitString r;
1757
1758 unsigned int xl = x.rep->len;
1759 unsigned int yl = y.rep->len;
1760
1761 int startx, starty;
1762 if (startpos < 0)
1763 {
1764 startx = xl + startpos;
1765 starty = yl + startpos;
1766 }
1767 else
1768 startx = starty = startpos;
1769
1770 if (startx < 0 || startx >= xl || starty < 0 || starty >= yl)
1771 return r;
1772
1773 const unsigned short* xs = &(x.rep->s[BitStr_index(startx)]);
1774 unsigned short a = *xs++;
1775 int xp = startx;
1776
1777 const unsigned short* ys = &(y.rep->s[BitStr_index(starty)]);
1778 unsigned short b = *ys++;
1779 int yp = starty;
1780
1781 for(; xp < xl && yp < yl; ++xp, ++yp)
1782 {
1783 unsigned short xbit = 1 << (BitStr_pos(xp));
1784 unsigned short ybit = 1 << (BitStr_pos(yp));
1785 if (((a & xbit) == 0) != ((b & ybit) == 0))
1786 break;
1787 if (xbit == MAXBIT)
1788 a = *xs++;
1789 if (ybit == MAXBIT)
1790 b = *ys++;
1791 }
1792 r.rep = BStr_alloc(0, x.rep->s, startx, xp, xp - startx);
1793 return r;
1794}
1795
1796
1797BitString common_suffix(const BitString& x, const BitString& y, int startpos)
1798{
1799 BitString r;
1800 unsigned int xl = x.rep->len;
1801 unsigned int yl = y.rep->len;
1802
1803 int startx, starty;
1804 if (startpos < 0)
1805 {
1806 startx = xl + startpos;
1807 starty = yl + startpos;
1808 }
1809 else
1810 startx = starty = startpos;
1811
1812 if (startx < 0 || startx >= xl || starty < 0 || starty >= yl)
1813 return r;
1814
1815 const unsigned short* xs = &(x.rep->s[BitStr_index(startx)]);
1816 unsigned short a = *xs--;
1817 int xp = startx;
1818
1819 const unsigned short* ys = &(y.rep->s[BitStr_index(starty)]);
1820 unsigned short b = *ys--;
1821 int yp = starty;
1822
1823 for(; xp >= 0 && yp >= 0; --xp, --yp)
1824 {
1825 unsigned short xbit = 1 << (BitStr_pos(xp));
1826 unsigned short ybit = 1 << (BitStr_pos(yp));
1827 if (((a & xbit) == 0) != ((b & ybit) == 0))
1828 break;
1829 if (xbit == 1)
1830 a = *xs--;
1831 if (ybit == 1)
1832 b = *ys--;
1833 }
1834 r.rep = BStr_alloc(0, x.rep->s, xp+1, startx+1, startx - xp);
1835 return r;
1836}
1837
1838BitString reverse(const BitString& x)
1839{
1840 BitString r;
1841 unsigned int yl = x.rep->len;
1842 BitStrRep* y = BStr_resize(0, yl);
1843 if (yl > 0)
1844 {
1845 const unsigned short* ls = x.rep->s;
1846 unsigned short lm = 1;
1847 unsigned short* rs = &(y->s[BitStr_index(yl - 1)]);
1848 unsigned short rm = 1 << (BitStr_pos(yl - 1));
1849 for (unsigned int l = 0; l < yl; ++l)
1850 {
1851 if (*ls & lm)
1852 *rs |= rm;
1853 if (lm == MAXBIT)
1854 {
1855 ++ls;
1856 lm = 1;
1857 }
1858 else
1859 lm <<= 1;
1860 if (rm == 1)
1861 {
1862 --rs;
1863 rm = MAXBIT;
1864 }
1865 else
1866 rm >>= 1;
1867 }
1868 }
1869 r.rep = y;
1870 return r;
1871}
1872
1873BitString atoBitString(const char* s, char f, char t)
1874{
1875 BitString res;
1876 int sl = strlen(s);
1877 BitStrRep* r = BStr_resize(0, sl);
1878 if (sl != 0)
1879 {
1880 unsigned int rl = 0;
1881 unsigned short* rs = r->s;
1882 unsigned short a = 0;
1883 unsigned short m = 1;
1884 unsigned int i = 0;
1885 for(;;)
1886 {
1887 char ch = s[i];
1888 if (ch != t && ch != f)
1889 {
1890 *rs = a;
1891 break;
1892 }
1893 ++rl;
1894 if (ch == t)
1895 a |= m;
1896 if (++i == sl)
1897 {
1898 *rs = a;
1899 break;
1900 }
1901 else if (i % BITSTRBITS == 0)
1902 {
1903 *rs++ = a;
1904 a = 0;
1905 m = 1;
1906 }
1907 else
1908 m <<= 1;
1909 }
1910 r = BStr_resize(r, rl);
1911 }
1912 res.rep = r;
1913 return res;
1914}
1915
1916BitPattern atoBitPattern(const char* s, char f,char t,char x)
1917{
1918 BitPattern r;
1919 int sl = strlen(s);
1920 if (sl != 0)
1921 {
1922 unsigned int rl = 0;
1923 r.pattern.rep = BStr_resize(r.pattern.rep, sl);
1924 r.mask.rep = BStr_resize(r.mask.rep, sl);
1925 unsigned short* rs = r.pattern.rep->s;
1926 unsigned short* ms = r.mask.rep->s;
1927 unsigned short a = 0;
1928 unsigned short b = 0;
1929 unsigned short m = 1;
1930 unsigned int i = 0;
1931 for(;;)
1932 {
1933 char ch = s[i];
1934 if (ch != t && ch != f && ch != x)
1935 {
1936 *rs = a;
1937 *ms = b;
1938 break;
1939 }
1940 ++rl;
1941 if (ch == t)
1942 {
1943 a |= m;
1944 b |= m;
1945 }
1946 else if (ch == f)
1947 {
1948 b |= m;
1949 }
1950 if (++i == sl)
1951 {
1952 *rs = a;
1953 *ms = b;
1954 break;
1955 }
1956 else if (i % BITSTRBITS == 0)
1957 {
1958 *rs++ = a;
1959 *ms++ = b;
1960 a = 0;
1961 b = 0;
1962 m = 1;
1963 }
1964 else
1965 m <<= 1;
1966 }
1967 r.pattern.rep = BStr_resize(r.pattern.rep, rl);
1968 r.mask.rep = BStr_resize(r.mask.rep, rl);
1969 }
1970 return r;
1971}
1972
1973#endif
1974
1975extern AllocRing _libgxx_fmtq;
1976
1977const char* BitStringtoa(const BitString& x, char f, char t)
1978{
1979 int wrksiz = x.length() + 2;
1980 char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
1981 char* fmt = fmtbase;
1982 unsigned int xl = x.rep->len;
1983 const unsigned short* s = x.rep->s;
1984 unsigned short a = 0;
1985
1986 for (unsigned int i = 0; i < xl; ++i)
1987 {
1988 if (i % BITSTRBITS == 0)
1989 a = *s++;
1990 *fmt++ = (a & 1)? t : f;
1991 a >>= 1;
1992 }
1993
1994 *fmt = 0;
1995
1996 return fmtbase;
1997}
1998
1999
2000ostream& operator << (ostream& s, const BitString& x)
2001{
2002 return s << BitStringtoa(x);
2003}
2004
2005const char* BitPatterntoa(const BitPattern& p, char f,char t,char x)
2006{
2007 unsigned int pl = p.pattern.rep->len;
2008 unsigned int ml = p.mask.rep->len;
2009 unsigned int l = (pl <= ml)? pl : ml;
2010
2011 int wrksiz = l + 2;
2012 char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
2013 char* fmt = fmtbase;
2014
2015 const unsigned short* ps = p.pattern.rep->s;
2016 const unsigned short* ms = p.mask.rep->s;
2017 unsigned short a = 0;
2018 unsigned short m = 0;
2019
2020 for (unsigned int i = 0; i < l; ++i)
2021 {
2022 if (i % BITSTRBITS == 0)
2023 {
2024 a = *ps++;
2025 m = *ms++;
2026 }
2027 if (m & 1)
2028 *fmt++ =(a & 1)? t : f;
2029 else
2030 *fmt++ = x;
2031 a >>= 1;
2032 m >>= 1;
2033 }
2034
2035 *fmt = 0;
2036 return fmtbase;
2037}
2038
2039
2040ostream& operator << (ostream& s, const BitPattern& x)
2041{
2042 return s << BitPatterntoa(x);
2043}
2044
2045
2046int BitString::OK() const
2047{
2048 int v = rep != 0; // have a rep;
2049 v &= BitStr_len(rep->len) <= rep->sz; // within allocated size
2050 if (!v) error("invariant failure");
2051 return v;
2052}
2053
2054int BitSubString::OK() const
2055{
2056 int v = S.OK(); // valid BitString
2057 v &= pos >= 0 && len >= 0; // valid indices
2058 v &= pos + len <= S.rep->len; // within bounds of targ
2059 if (!v) S.error("BitSubString invariant failure");
2060 return v;
2061}
2062
2063int BitPattern::OK() const
2064{
2065 int v = pattern.OK() && mask.OK();
2066 if (!v) pattern.error("BitPattern invariant failure");
2067 return v;
2068}
2069