modules/up/src/gnug++/unsigned.Plex.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- error
- index_error
- empty_error
- full_error
- unsignedIChunk
- unsignedIChunk
- re_index
- clear
- cleardown
- OK
- error
- index_error
- empty_error
- full_error
- unsignedPlex
- append
- prepend
- reverse
- fill
- fill
- del_chunk
- invalidate
- reset_low
1 // This may look like C code, but it is really -*- C++ -*-
2 /*
3 Copyright (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
7 This file is part of the GNU C++ Library. This library is free
8 software; you can redistribute it and/or modify it under the terms of
9 the GNU Library General Public License as published by the Free
10 Software Foundation; either version 2 of the License, or (at your
11 option) any later version. This library is distributed in the hope
12 that it will be useful, but WITHOUT ANY WARRANTY; without even the
13 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the GNU Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #ifdef __GNUG__
21 #pragma implementation
22 #endif
23 #include "config.h"
24 #include <stream.h>
25 #include <builtin.h>
26 #include "unsigned.Plex.h"
27
28 // IChunk support
29
30 void unsignedIChunk::error(const char* msg) const
/* [<][>][^][v][top][bottom][index][help] */
31 {
32 (*lib_error_handler)("unsignedIChunk", msg);
33 }
34
35 void unsignedIChunk::index_error() const
/* [<][>][^][v][top][bottom][index][help] */
36 {
37 error("attempt to use invalid index");
38 }
39
40 void unsignedIChunk::empty_error() const
/* [<][>][^][v][top][bottom][index][help] */
41 {
42 error("invalid use of empty chunk");
43 }
44
45 void unsignedIChunk::full_error() const
/* [<][>][^][v][top][bottom][index][help] */
46 {
47 error("attempt to extend chunk beyond bounds");
48 }
49
50 unsignedIChunk:: ~unsignedIChunk() {}
/* [<][>][^][v][top][bottom][index][help] */
51
52 unsignedIChunk::unsignedIChunk(unsigned* d,
/* [<][>][^][v][top][bottom][index][help] */
53 int baseidx,
54 int lowidx,
55 int fenceidx,
56 int topidx)
57 {
58 if (d == 0 || baseidx > lowidx || lowidx > fenceidx || fenceidx > topidx)
59 error("inconsistent specification");
60 data = d;
61 base = baseidx;
62 low = lowidx;
63 fence = fenceidx;
64 top = topidx;
65 nxt = prv = this;
66 }
67
68 void unsignedIChunk:: re_index(int lo)
/* [<][>][^][v][top][bottom][index][help] */
69 {
70 int delta = lo - low;
71 base += delta;
72 low += delta;
73 fence += delta;
74 top += delta;
75 }
76
77
78 void unsignedIChunk::clear(int lo)
/* [<][>][^][v][top][bottom][index][help] */
79 {
80 int s = top - base;
81 low = base = fence = lo;
82 top = base + s;
83 }
84
85 void unsignedIChunk::cleardown(int hi)
/* [<][>][^][v][top][bottom][index][help] */
86 {
87 int s = top - base;
88 low = top = fence = hi;
89 base = top - s;
90 }
91
92 int unsignedIChunk:: OK() const
/* [<][>][^][v][top][bottom][index][help] */
93 {
94 int v = data != 0; // have some data
95 v &= base <= low; // ok, index-wise
96 v &= low <= fence;
97 v &= fence <= top;
98
99 v &= nxt->prv == this; // and links are OK
100 v &= prv->nxt == this;
101 if (!v) error("invariant failure");
102 return(v);
103 }
104
105
106 // error handling
107
108
109 void unsignedPlex::error(const char* msg) const
/* [<][>][^][v][top][bottom][index][help] */
110 {
111 (*lib_error_handler)("Plex", msg);
112 }
113
114 void unsignedPlex::index_error() const
/* [<][>][^][v][top][bottom][index][help] */
115 {
116 error("attempt to access invalid index");
117 }
118
119 void unsignedPlex::empty_error() const
/* [<][>][^][v][top][bottom][index][help] */
120 {
121 error("attempted operation on empty plex");
122 }
123
124 void unsignedPlex::full_error() const
/* [<][>][^][v][top][bottom][index][help] */
125 {
126 error("attempt to increase size of plex past limit");
127 }
128
129 // generic plex ops
130
131 unsignedPlex:: ~unsignedPlex()
/* [<][>][^][v][top][bottom][index][help] */
132 {
133 invalidate();
134 }
135
136
137 void unsignedPlex::append (const unsignedPlex& a)
/* [<][>][^][v][top][bottom][index][help] */
138 {
139 for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]);
140 }
141
142 void unsignedPlex::prepend (const unsignedPlex& a)
/* [<][>][^][v][top][bottom][index][help] */
143 {
144 for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]);
145 }
146
147 void unsignedPlex::reverse()
/* [<][>][^][v][top][bottom][index][help] */
148 {
149 unsigned tmp;
150 int l = low();
151 int h = high();
152 while (l < h)
153 {
154 tmp = (*this)[l];
155 (*this)[l] = (*this)[h];
156 (*this)[h] = tmp;
157 next(l);
158 prev(h);
159 }
160 }
161
162
163 void unsignedPlex::fill(const unsigned x)
/* [<][>][^][v][top][bottom][index][help] */
164 {
165 for (int i = lo; i < fnc; ++i) (*this)[i] = x;
166 }
167
168 void unsignedPlex::fill(const unsigned x, int lo, int hi)
/* [<][>][^][v][top][bottom][index][help] */
169 {
170 for (int i = lo; i <= hi; ++i) (*this)[i] = x;
171 }
172
173
174 void unsignedPlex::del_chunk(unsignedIChunk* x)
/* [<][>][^][v][top][bottom][index][help] */
175 {
176 if (x != 0)
177 {
178 x->unlink();
179 unsigned* data = (unsigned*)(x->invalidate());
180 delete [] data;
181 delete x;
182 }
183 }
184
185
186 void unsignedPlex::invalidate()
/* [<][>][^][v][top][bottom][index][help] */
187 {
188 unsignedIChunk* t = hd;
189 if (t != 0)
190 {
191 unsignedIChunk* tail = tl();
192 while (t != tail)
193 {
194 unsignedIChunk* nxt = t->next();
195 del_chunk(t);
196 t = nxt;
197 }
198 del_chunk(t);
199 hd = 0;
200 }
201 }
202
203 int unsignedPlex::reset_low(int l)
/* [<][>][^][v][top][bottom][index][help] */
204 {
205 int old = lo;
206 int diff = l - lo;
207 if (diff != 0)
208 {
209 lo += diff;
210 fnc += diff;
211 unsignedIChunk* t = hd;
212 do
213 {
214 t->re_index(t->low_index() + diff);
215 t = t->next();
216 } while (t != hd);
217 }
218 return old;
219 }
220
221
222
223