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