|
|
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.