home *** CD-ROM | disk | FTP | other *** search
- // This may look like C code, but it is really -*- C++ -*-
- /*
- Copyright (C) 1988 Free Software Foundation
- written by Doug Lea (dl@rocky.oswego.edu)
-
- This file is part of GNU CC.
-
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the GNU CC General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- GNU CC, but only under the conditions described in the
- GNU CC General Public License. A copy of this license is
- supposed to have been given to you along with GNU CC so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies.
- */
-
- #include <Obstack.h>
- #include <BitVec.h>
-
-
- // error handling
-
- void default_BitVec_error_handler(char* msg)
- {
- cerr << "Fatal BitVec error. " << msg << "\n";
- exit(1);
- }
-
- one_arg_error_handler_t BitVec_error_handler = default_BitVec_error_handler;
-
- one_arg_error_handler_t Vec_BitVec_error_handler(one_arg_error_handler_t f)
- {
- one_arg_error_handler_t old = BitVec_error_handler;
- BitVec_error_handler = f;
- return old;
- }
-
- void BitVec::error(char* msg)
- {
- (*BitVec_error_handler)(msg);
- }
-
- // break things up into .s indices and positions
-
- inline static int word_length(int l)
- {
- return (unsigned)(l) / BITVEC_BPW + ((l & (BITVEC_BPW - 1))? 1 : 0);
- }
-
- inline static int bit_position(int l)
- {
- return l & (BITVEC_BPW - 1);
- }
-
- void BitVec::resize(int newlen)
- {
- unsigned long* olds = s;
- int sz = word_length(len);
- int newsz = word_length(newlen);
- s = new unsigned long[newsz];
- bcopy(olds, s, sz * sizeof(unsigned long));
- if (newsz > sz)
- bzero(&s[sz], newsz - sz);
- delete olds;
- }
-
- int operator == (BitVec& x, BitVec& y)
- {
- return x.len == y.len &&
- bcmp((void*)x.s, (void*)y.s, word_length(x.len) * sizeof(long)) == 0;
- }
-
- int operator <= (BitVec& x, BitVec& y)
- {
- unsigned long xl = x.len;
- unsigned long yl = y.len;
- if (xl > yl)
- return 0;
-
- unsigned long* xs = x.s;
- unsigned long* ys = y.s;
- unsigned long* topx = &(xs[word_length(xl)]);
-
- while (xs < topx)
- {
- unsigned long a = *xs++;
- unsigned long b = *ys++;
- if ((a | b) != b)
- return 0;
- }
- return 1;
- }
-
- int operator < (BitVec& x, BitVec& y)
- {
- unsigned long xl = x.len;
- unsigned long yl = y.len;
- if (xl >= yl)
- return 0;
-
- unsigned long* xs = x.s;
- unsigned long* ys = y.s;
- unsigned long* topx = &(xs[word_length(xl)]);
- unsigned long* topy = &(xs[word_length(yl)]);
- int one_diff = 0;
- while (xs < topx)
- {
- unsigned long a = *xs++;
- unsigned long b = *ys++;
- unsigned long c = a | b;
- if (c != b)
- return 0;
- else if (c != a)
- one_diff = 1;
- }
- if (one_diff)
- return 1;
- else
- {
- while (ys < topy)
- if (*ys++ != 0)
- return 1;
- return 0;
- }
- }
-
- int BitVec::empty()
- {
- int xwds = word_length(len);
- int xlast = bit_position(len);
- int l = 0;
- unsigned long* p = s;
- unsigned long* tops = &(s[xwds]);
- while (p < tops)
- if (*p++ != 0)
- return 0;
- return 1;
- }
-
-
- int BitVec::count(int b = 1)
- {
- int xwds = word_length(len);
- int xlast = bit_position(len);
- int l = 0;
- unsigned long* p = s;
- unsigned long* tops = &(s[xwds - 1]);
- unsigned long a;
- int i;
- if (b != 0)
- {
- while (p < tops)
- {
- a = *p++;
- for (i = 0; i < BITVEC_BPW && a != 0; ++i)
- {
- if (a & 1)
- ++l;
- a >>= 1;
- }
- }
- a = *p;
- for (i = 0; i < xlast && a != 0; ++i)
- {
- if (a & 1)
- ++l;
- a >>= 1;
- }
- }
- else
- {
- unsigned long maxbit = 1 << (BITVEC_BPW - 1);
- while (p < tops)
- {
- a = *p++;
- for (i = 0; i < BITVEC_BPW; ++i)
- {
- if ((a & maxbit) == 0)
- ++l;
- a <<= 1;
- }
- }
- maxbit = 1 << (xlast - 1);
- a = *p;
- for (i = 0; i < xlast; ++i)
- {
- if ((a & maxbit) == 0)
- ++l;
- a <<= 1;
- }
- }
- return l;
- }
-
- BitVec& BitVec::complement()
- {
- unsigned long* rs = s;
- unsigned long* topr = &(rs[word_length(len)]);
- while (rs < topr)
- {
- unsigned long cmp = ~(*rs);
- *rs++ = cmp;
- }
- return *this;
- }
-
- BitVec BitVec:: operator ~()
- {
- unsigned long* r = new unsigned long[word_length(len)];
- unsigned long* rs = r;
- unsigned long* xs = s;
- unsigned long* topr = &(rs[word_length(len)]);
- while (rs < topr) *rs++ = ~(*xs++);
- return BitVec(r, len);
- }
-
- BitVec operator & (BitVec& a, BitVec& b)
- {
- if (a.len != b.len)
- a.error("nonconformant vectors");
- unsigned long* r = new unsigned long[word_length(a.len)];
- unsigned long* rs = r;
- unsigned long* xs = a.s;
- unsigned long* ys = b.s;
- unsigned long* topr = &(rs[word_length(a.len)]);
- while (rs < topr) *rs++ = *xs++ & *ys++;
- return BitVec(r, a.len);
- }
-
- BitVec operator | (BitVec& a, BitVec& b)
- {
- if (a.len != b.len)
- a.error("nonconformant vectors");
- unsigned long* r = new unsigned long[word_length(a.len)];
- unsigned long* rs = r;
- unsigned long* xs = a.s;
- unsigned long* ys = b.s;
- unsigned long* topr = &(rs[word_length(a.len)]);
- while (rs < topr) *rs++ = *xs++ | *ys++;
- return BitVec(r, a.len);
- }
-
- BitVec operator ^ (BitVec& a, BitVec& b)
- {
- if (a.len != b.len)
- a.error("nonconformant vectors");
- unsigned long* r = new unsigned long[word_length(a.len)];
- unsigned long* rs = r;
- unsigned long* xs = a.s;
- unsigned long* ys = b.s;
- unsigned long* topr = &(rs[word_length(a.len)]);
- while (rs < topr) *rs++ = *xs++ ^ *ys++;
- return BitVec(r, a.len);
- }
-
- BitVec operator - (BitVec& a, BitVec& b)
- {
- if (a.len != b.len)
- a.error("nonconformant vectors");
- unsigned long* r = new unsigned long[word_length(a.len)];
- unsigned long* rs = r;
- unsigned long* xs = a.s;
- unsigned long* ys = b.s;
- unsigned long* topr = &(rs[word_length(a.len)]);
- while (rs < topr) *rs++ = *xs++ & ~(*ys++);
- return BitVec(r, a.len);
- }
-
- BitVec& BitVec::operator &= (BitVec& b)
- {
- if (len != b.len)
- error("nonconformant vectors");
- unsigned long* xs = s;
- unsigned long* ys = b.s;
- unsigned long* top = &(s[word_length(len)]);
- while (xs < top) *xs++ &= *ys++;
- return *this;
- }
-
- BitVec& BitVec::operator |= (BitVec& b)
- {
- if (len != b.len)
- error("nonconformant vectors");
- unsigned long* xs = s;
- unsigned long* ys = b.s;
- unsigned long* top = &(s[word_length(len)]);
- while (xs < top) *xs++ |= *ys++;
- return *this;
- }
-
- BitVec& BitVec::operator ^= (BitVec& b)
- {
- if (len != b.len)
- error("nonconformant vectors");
- unsigned long* xs = s;
- unsigned long* ys = b.s;
- unsigned long* top = &(s[word_length(len)]);
- while (xs < top) *xs++ ^= *ys++;
- return *this;
- }
-
- BitVec& BitVec::operator -= (BitVec& b)
- {
- if (len != b.len)
- error("nonconformant vectors");
- unsigned long* xs = s;
- unsigned long* ys = b.s;
- unsigned long* top = &(s[word_length(len)]);
- while (xs < top) *xs++ &= ~(*ys++);
- return *this;
- }
-
- extern Obstack _libgxx_io_ob;
- extern char* _libgxx_io_oblast;
-
-
- const char* BitVectoa(BitVec& x, char f = '0', char t = '1')
- {
- if (_libgxx_io_oblast) _libgxx_io_ob.free(_libgxx_io_oblast);
- unsigned long xl = x.len;
- unsigned long* p = x.s;
- unsigned long a;
-
- for (unsigned long i = 0; i < xl; ++i)
- {
- if (i % BITVEC_BPW == 0)
- a = *p++;
- _libgxx_io_ob.grow((a & 1)? t : f);
- a >>= 1;
- }
-
- return _libgxx_io_oblast = (char*)(_libgxx_io_ob.finish(0));
- }
-
- BitVec atoBitVec(const char* s, char f = '0', char t = '1')
- {
- int rl = 0;
- int sl = strlen(s);
- unsigned long* r = new unsigned long[word_length(sl)];
- int i = 0;
- if (sl != 0)
- {
- unsigned long* rs = r;
- unsigned long a = 0;
- unsigned long m = 1;
- for(;;)
- {
- char ch = s[i];
- if (ch != t && ch != f)
- {
- *rs = a;
- break;
- }
- ++rl;
- if (ch == t)
- a |= m;
- if (++i == sl)
- {
- *rs = a;
- break;
- }
- else if (i % BITVEC_BPW == 0)
- {
- *rs++ = a;
- a = 0;
- m = 1;
- }
- else
- m <<= 1;
- }
- }
- return BitVec(r, i);
- }
-
- ostream& operator << (ostream& s, BitVec& x)
- {
- return s << BitVectoa(x);
- }
-
-
-
-