|
|
1.1 root 1: /*ident "@(#)ctrans:src/Bits.h 1.2" */
2:
3: #ifndef _BITS_H
4: #define _BITS_H
5:
6: #include "Block.h"
7:
8: typedef unsigned long Bits_chunk;
9: static const int Bits_shift_ATTLC = 5;
10: static const int Bits_len_ATTLC = 1 << Bits_shift_ATTLC;
11: static const int Bits_mask_ATTLC = Bits_len_ATTLC - 1;
12:
13: Blockdeclare(Bits_chunk)
14:
15: class Bits {
16: private:
17: Block(Bits_chunk) b;
18: unsigned n;
19:
20: // the chunk number that contains bit n
21: unsigned chunk(unsigned n) const {
22: return n >> Bits_shift_ATTLC;
23: }
24:
25: // the number of chunks needed to contain an n-bit string
26: unsigned bound(unsigned n) const {
27: return (n + Bits_len_ATTLC - 1) >> Bits_shift_ATTLC;
28: }
29:
30: // a pointer to the (non-existent) chunk immediately
31: // after the last one in this Bits
32: Bits_chunk* limit() {
33: return b + bound(n);
34: }
35: const Bits_chunk* limit() const {
36: return b + bound(n);
37: }
38:
39: // turn off unused high-order bits in the high-order chunk
40: void normalize() {
41: register int ct = n & Bits_mask_ATTLC;
42: if (ct)
43: b[chunk(n)] &= ~(~Bits_chunk(0) << ct);
44: }
45:
46: int compare(const Bits&) const;
47: int equal(const Bits&) const;
48:
49: public:
50: Bits() { n = 0; }
51: Bits(Bits_chunk, unsigned = 1);
52: unsigned size() const { return n; }
53: unsigned size(unsigned);
54: friend Bits operator& (const Bits&, const Bits&);
55: friend Bits operator| (const Bits&, const Bits&);
56: friend Bits operator^ (const Bits&, const Bits&);
57: friend Bits operator~ (const Bits&);
58: friend Bits operator<< (const Bits&, int);
59: friend Bits operator>> (const Bits&, int);
60: friend int operator< (const Bits&, const Bits&);
61: friend int operator> (const Bits&, const Bits&);
62: friend int operator<= (const Bits&, const Bits&);
63: friend int operator>= (const Bits&, const Bits&);
64: friend int operator== (const Bits&, const Bits&);
65: friend int operator!= (const Bits&, const Bits&);
66: Bits& operator&= (const Bits&);
67: Bits& operator|= (const Bits&);
68: Bits& operator^= (const Bits&);
69: Bits& operator<<= (int);
70: Bits& operator>>= (int);
71: Bits& compl();
72: Bits& concat(const Bits&);
73: Bits& set(unsigned i) {
74: if (i < n)
75: b[chunk(i)] |= Bits_chunk(1) << (i&Bits_mask_ATTLC);
76: return *this;
77: }
78: Bits& set(unsigned i, unsigned long x) {
79: if (i < n) {
80: register Bits_chunk* p = &b[chunk(i)];
81: register Bits_chunk mask = Bits_chunk(1) << (i&Bits_mask_ATTLC);
82: if (x)
83: *p |= mask;
84: else
85: *p &= ~mask;
86: }
87: return *this;
88: }
89: Bits& reset(unsigned i) {
90: if (i < n)
91: b[chunk(i)] &= ~(Bits_chunk(1) << (i&Bits_mask_ATTLC));
92: return *this;
93: }
94: Bits& compl(unsigned i) {
95: if (i < n)
96: b[chunk(i)] ^= Bits_chunk(1) << (i&Bits_mask_ATTLC);
97: return *this;
98: }
99: unsigned count() const;
100: operator Bits_chunk() const;
101: int operator[] (unsigned i) const {
102: if (i >= n)
103: return 0;
104: else
105: return (b[chunk(i)] >> (i&Bits_mask_ATTLC)) & 1;
106: }
107: unsigned signif() const;
108: unsigned trim() { return size(signif()); }
109: };
110:
111: inline int
112: operator< (const Bits& a, const Bits& b)
113: {
114: return a.compare(b) < 0;
115: }
116:
117: inline int
118: operator> (const Bits& a, const Bits& b)
119: {
120: return a.compare(b) > 0;
121: }
122:
123: inline int
124: operator<= (const Bits& a, const Bits& b)
125: {
126: return a.compare(b) <= 0;
127: }
128:
129: inline int
130: operator>= (const Bits& a, const Bits& b)
131: {
132: return a.compare(b) >= 0;
133: }
134:
135: inline int
136: operator== (const Bits& a, const Bits& b)
137: {
138: return a.equal(b);
139: }
140:
141: inline int
142: operator!= (const Bits& a, const Bits& b)
143: {
144: return !a.equal(b);
145: }
146:
147: Bits concat(const Bits&, const Bits&);
148:
149: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.