1// This may look like C code, but it is really -*- C++ -*- 2/* 3Copyright (C) 1988 Free Software Foundation 4 written by Doug Lea (dl@rocky.oswego.edu) 5 based on code by Marc Shapiro (shapiro@sor.inria.fr) 6 7This file is part of GNU CC. 8 9GNU CC is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY. No author or distributor 11accepts responsibility to anyone for the consequences of using it 12or for whether it serves any particular purpose or works at all, 13unless he says so in writing. Refer to the GNU CC General Public 14License for full details. 15 16Everyone is granted permission to copy, modify and redistribute 17GNU CC, but only under the conditions described in the 18GNU CC General Public License. A copy of this license is 19supposed to have been given to you along with GNU CC so you 20can know your rights and responsibilities. It should be in a 21file named COPYING. Among other things, the copyright notice 22and this notice must be preserved on all copies. 23*/ 24 25#ifdef __GNUG__ 26#pragma implementation 27#endif 28#include <stream.h> 29#include "<T>.Plex.h" 30 31// IChunk support 32 33volatile void <T>IChunk::error(const char* msg) const 34{ 35 (*lib_error_handler)("<T>IChunk", msg); 36} 37 38volatile void <T>IChunk::index_error() const 39{ 40 error("attempt to use invalid index"); 41} 42 43volatile void <T>IChunk::empty_error() const 44{ 45 error("invalid use of empty chunk"); 46} 47 48volatile void <T>IChunk::full_error() const 49{ 50 error("attempt to extend chunk beyond bounds"); 51} 52 53<T>IChunk:: ~<T>IChunk() {} 54 55<T>IChunk::<T>IChunk(<T>* d, 56 int baseidx, 57 int lowidx, 58 int fenceidx, 59 int topidx) 60{ 61 if (d == 0 || baseidx > lowidx || lowidx > fenceidx || fenceidx > topidx) 62 error("inconsistent specification"); 63 data = d; 64 base = baseidx; 65 low = lowidx; 66 fence = fenceidx; 67 top = topidx; 68 nxt = prv = this; 69} 70 71void <T>IChunk:: re_index(int lo) 72{ 73 int delta = lo - low; 74 base += delta; 75 low += delta; 76 fence += delta; 77 top += delta; 78} 79 80 81void <T>IChunk::clear(int lo) 82{ 83 int s = top - base; 84 low = base = fence = lo; 85 top = base + s; 86} 87 88void <T>IChunk::cleardown(int hi) 89{ 90 int s = top - base; 91 low = top = fence = hi; 92 base = top - s; 93} 94 95int <T>IChunk:: OK() const 96{ 97 int v = data != 0; // have some data 98 v &= base <= low; // ok, index-wise 99 v &= low <= fence; 100 v &= fence <= top; 101 102 v &= nxt->prv == this; // and links are OK 103 v &= prv->nxt == this; 104 if (!v) error("invariant failure"); 105 return(v); 106} 107 108 109// error handling 110 111 112volatile void <T>Plex::error(const char* msg) const 113{ 114 (*lib_error_handler)("Plex", msg); 115} 116 117volatile void <T>Plex::index_error() const 118{ 119 error("attempt to access invalid index"); 120} 121 122volatile void <T>Plex::empty_error() const 123{ 124 error("attempted operation on empty plex"); 125} 126 127volatile void <T>Plex::full_error() const 128{ 129 error("attempt to increase size of plex past limit"); 130} 131 132// generic plex ops 133 134<T>Plex:: ~<T>Plex() 135{ 136 invalidate(); 137} 138 139 140void <T>Plex::append (const <T>Plex& a) 141{ 142 for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]); 143} 144 145void <T>Plex::prepend (const <T>Plex& a) 146{ 147 for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]); 148} 149 150void <T>Plex::reverse() 151{ 152 <T> tmp; 153 int l = low(); 154 int h = high(); 155 while (l < h) 156 { 157 tmp = (*this)[l]; 158 (*this)[l] = (*this)[h]; 159 (*this)[h] = tmp; 160 next(l); 161 prev(h); 162 } 163} 164 165 166void <T>Plex::fill(const <T&> x) 167{ 168 for (int i = lo; i < fnc; ++i) (*this)[i] = x; 169} 170 171void <T>Plex::fill(const <T&> x, int lo, int hi) 172{ 173 for (int i = lo; i <= hi; ++i) (*this)[i] = x; 174} 175 176 177void <T>Plex::del_chunk(<T>IChunk* x) 178{ 179 if (x != 0) 180 { 181 x->unlink(); 182 int sz = x->size(); 183 <T>* data = (<T>*)(x->invalidate()); 184 delete [sz] data; 185 delete x; 186 } 187} 188 189 190void <T>Plex::invalidate() 191{ 192 <T>IChunk* t = hd; 193 if (t != 0) 194 { 195 <T>IChunk* tail = tl(); 196 while (t != tail) 197 { 198 <T>IChunk* nxt = t->next(); 199 del_chunk(t); 200 t = nxt; 201 } 202 del_chunk(t); 203 hd = 0; 204 } 205} 206 207int <T>Plex::reset_low(int l) 208{ 209 int old = lo; 210 int diff = l - lo; 211 if (diff != 0) 212 { 213 lo += diff; 214 fnc += diff; 215 <T>IChunk* t = hd; 216 do 217 { 218 t->re_index(t->low_index() + diff); 219 t = t->next(); 220 } while (t != hd); 221 } 222 return old; 223} 224 225 226 227 228