|
|
1.1 root 1: /*ident "@(#)ctrans:src/Block.h 1.2" */
2:
3: #ifndef BLOCK_H
4: #define BLOCK_H
5: #include <new.h>
6:
7: PT_names
8: Block(T) Block_ T
9: PT_end
10:
11: PT_define Blockdeclare(T)
12:
13: class Block(T) {
14: public:
15: unsigned size() const { return n; }
16: unsigned size(unsigned);
17: Block(T)() { n = 0; p = 0; }
18: Block(T)(unsigned k) { n = 0; p = 0; size(k); }
19: Block(T)(const Block(T)& b) { copy(b); }
20: ~Block(T)();
21: Block(T)& operator=(const Block(T)&);
22: operator T*() { return p; }
23: operator const T*() const { return p; }
24: T* end() { return p + n; }
25: const T* end() const { return p + n; }
26: T& operator[](int i) { return p[i]; }
27: const T& operator[](int i) const { return p[i]; }
28: int reserve(unsigned k) { return k<n || grow(k); }
29: void swap(Block(T)& b);
30: private:
31: T* p;
32: unsigned n;
33: void move(T*, unsigned);
34: void transfer(T*, unsigned);
35: void clear(T*, unsigned);
36: void copy(const Block(T)&);
37: unsigned grow(unsigned);
38: static T* default_value();
39: };
40:
41: PT_end
42:
43: PT_define Blockimplement(T)
44:
45: unsigned Block(T)::size(unsigned k)
46: {
47: if (k != n)
48: move(new T[k], k);
49: return n;
50: }
51: Block(T)::~Block(T)()
52: {
53: delete[] p;
54: }
55: Block(T)& Block(T)::operator=(const Block(T)& b)
56: {
57: delete[] p;
58: copy(b);
59: return *this;
60: }
61:
62: /* Clear k elements starting at v */
63: void
64: Block(T)::clear(T* v, unsigned k)
65: {
66: register T* p = v;
67: register T* lim = v + k;
68: T* valptr = default_value();
69: while (p < lim) {
70: *p++ = *valptr;
71: }
72: }
73:
74: /* Make this a copy of b */
75: void
76: Block(T)::copy(const Block(T)& b)
77: {
78: // assert (p is 0 or garbage)
79: p = new T[b.n];
80: if (p) {
81: n = b.n;
82: transfer(b.p, n);
83: } else
84: n = 0;
85: }
86:
87: /* Grow this Block by 1.5 until it can contain at least k+1 */
88: unsigned
89: Block(T)::grow(unsigned k)
90: {
91: unsigned nn = n;
92: if (nn == 0)
93: nn++;
94: while (nn <= k)
95: nn += (nn >> 1) + 1;
96: T* np = new T[nn];
97: if (!np) {
98: nn = k+1;
99: np = new T[nn];
100: }
101: move(np, nn);
102: return n;
103: }
104:
105: /* Transfer len (or fewer) elements into this Block. */
106: void
107: Block(T)::transfer(T* source, unsigned len)
108: {
109: register T* plim;
110: register T* pp = p;
111: register T* q = source;
112:
113: if (n > len) {
114: plim = p + len;
115: clear(plim, n - len);
116: } else
117: plim = p + n;
118:
119: while (pp < plim)
120: *pp++ = *q++;
121: }
122:
123: /*
124: * The contents of this Block now live in memory starting at np
125: * If np is 0, null out this Block.
126: */
127: void
128: Block(T)::move(T* np, unsigned nn)
129: {
130: T* oldp = p;
131: unsigned oldn = n;
132: p = np;
133: if (np) {
134: n = nn;
135: transfer(oldp, oldn);
136: } else
137: n = 0;
138: delete[] oldp;
139: }
140:
141: /* Exchange the contents of this Block with another Block */
142: void
143: Block(T)::swap(Block(T)& b)
144: {
145: T* bp = b.p;
146: unsigned bn = b.n;
147: b.p = p;
148: b.n = n;
149: p = bp;
150: n = bn;
151: }
152:
153: T*
154: Block(T)::default_value() {
155: static T default_item;
156: return(&default_item);
157: }
158:
159: PT_end
160:
161:
162: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.