modules/up/src/gnug++/unsigned.OXPSet.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- seek
- add
- del
- OK
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
6 This file is part of the GNU C++ Library. This library is free
7 software; you can redistribute it and/or modify it under the terms of
8 the GNU Library General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version. This library is distributed in the hope
11 that it will be useful, but WITHOUT ANY WARRANTY; without even the
12 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 PURPOSE. See the GNU Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #ifdef __GNUG__
20 #pragma implementation
21 #endif
22 #include "config.h"
23 #include "unsigned.OXPSet.h"
24
25
26 Pix unsignedOXPSet::seek(unsigned item)
/* [<][>][^][v][top][bottom][index][help] */
27 {
28 int l = p.low();
29 int h = p.high();
30 while (l <= h)
31 {
32 int mid = (l + h) / 2;
33 int cmp = unsignedCMP(item, p[mid]);
34 if (cmp == 0)
35 return p.index_to_Pix(mid);
36 else if (cmp < 0)
37 h = mid - 1;
38 else
39 l = mid + 1;
40 }
41 return 0;
42 }
43
44 Pix unsignedOXPSet::add(unsigned item)
/* [<][>][^][v][top][bottom][index][help] */
45 {
46 if (count == 0)
47 {
48 ++count;
49 return p.index_to_Pix(p.add_high(item));
50 }
51 int l = p.low();
52 int h = p.high();
53 while (l <= h)
54 {
55 int mid = (l + h) / 2;
56 int cmp = unsignedCMP(item, p[mid]);
57 if (cmp == 0)
58 return p.index_to_Pix(mid);
59 else if (cmp < 0)
60 h = mid - 1;
61 else
62 l = mid + 1;
63 }
64 // add on whichever side is shortest
65 ++count;
66 if (l == p.fence())
67 return p.index_to_Pix(p.add_high(item));
68 else if (l == p.low())
69 return p.index_to_Pix(p.add_low(item));
70 else
71 {
72 if (p.fence() - l < l - p.low())
73 {
74 h = p.add_high(p.high_element());
75 for (int i = h - 1; i > l; --i) p[i] = p[i-1];
76 }
77 else
78 {
79 --l;
80 h = p.add_low(p.low_element());
81 for (int i = h + 1; i < l; ++i) p[i] = p[i+1];
82 }
83 p[l] = item;
84 return p.index_to_Pix(l);
85 }
86 }
87
88 void unsignedOXPSet::del(unsigned item)
/* [<][>][^][v][top][bottom][index][help] */
89 {
90 int l = p.low();
91 int h = p.high();
92 while (l <= h)
93 {
94 int mid = (l + h) / 2;
95 int cmp = unsignedCMP(item, p[mid]);
96 if (cmp == 0)
97 {
98 --count;
99 if (p.high() - mid < mid - p.low())
100 {
101 for (int i = mid; i < p.high(); ++i) p[i] = p[i+1];
102 p.del_high();
103 }
104 else
105 {
106 for (int i = mid; i > p.low(); --i) p[i] = p[i-1];
107 p.del_low();
108 }
109 return;
110 }
111 else if (cmp < 0)
112 h = mid - 1;
113 else
114 l = mid + 1;
115 }
116 }
117
118 int unsignedOXPSet::operator <= (const unsignedOXPSet& b)
119 {
120 if (count > b.count) return 0;
121 int i = p.low();
122 int j = b.p.low();
123 for (;;)
124 {
125 if (i >= p.fence())
126 return 1;
127 else if (j >= b.p.fence())
128 return 0;
129 int cmp = unsignedCMP(p[i], b.p[j]);
130 if (cmp == 0)
131 {
132 ++i; ++j;
133 }
134 else if (cmp < 0)
135 return 0;
136 else
137 ++j;
138 }
139 }
140
141 int unsignedOXPSet::operator == (const unsignedOXPSet& b)
142 {
143 int n = count;
144 if (n != b.count) return 0;
145 if (n == 0) return 1;
146 int i = p.low();
147 int j = b.p.low();
148 while (n-- > 0) if (!unsignedEQ(p[i++], b.p[j++])) return 0;
149 return 1;
150 }
151
152
153 void unsignedOXPSet::operator |= (const unsignedOXPSet& b)
154 {
155 if (&b == this || b.count == 0)
156 return;
157 else if (b.count <= 2) // small b -- just add
158 for (Pix i = b.first(); i; b.next(i)) add(b(i));
159 else
160 {
161 // strategy: merge into top of p, simultaneously killing old bottom
162 int oldfence = p.fence();
163 int i = p.low();
164 int j = b.p.low();
165 for (;;)
166 {
167 if (i == oldfence)
168 {
169 while (j < b.p.fence()) p.add_high(b.p[j++]);
170 break;
171 }
172 else if (j == b.p.fence())
173 {
174 while (i++ < oldfence)
175 {
176 p.add_high(p.low_element());
177 p.del_low();
178 }
179 break;
180 }
181 int cmp = unsignedCMP(p[i], b.p[j]);
182 if (cmp <= 0)
183 {
184 ++i;
185 if (cmp == 0) ++j;
186 p.add_high(p.low_element());
187 p.del_low();
188 }
189 else
190 p.add_high(b.p[j++]);
191 }
192 count = p.length();
193 }
194 }
195
196
197
198 void unsignedOXPSet::operator -= (const unsignedOXPSet& b)
199 {
200 if (&b == this)
201 clear();
202 else if (count != 0 && b.count != 0)
203 {
204 int i = p.low();
205 int k = i;
206 int j = b.p.low();
207 int oldfence = p.fence();
208 for (;;)
209 {
210 if (i >= oldfence)
211 break;
212 else if (j >= b.p.fence())
213 {
214 if (k != i)
215 while (i < oldfence) p[k++] = p[i++];
216 else
217 k = oldfence;
218 break;
219 }
220 int cmp = unsignedCMP(p[i], b.p[j]);
221 if (cmp == 0)
222 {
223 ++i; ++j;
224 }
225 else if (cmp < 0)
226 {
227 if (k != i) p[k] = p[i];
228 ++i; ++k;
229 }
230 else
231 j++;
232 }
233 while (k++ < oldfence)
234 {
235 --count;
236 p.del_high();
237 }
238 }
239 }
240
241 void unsignedOXPSet::operator &= (const unsignedOXPSet& b)
242 {
243 if (b.count == 0)
244 clear();
245 else if (&b != this && count != 0)
246 {
247 int i = p.low();
248 int k = i;
249 int j = b.p.low();
250 int oldfence = p.fence();
251 for (;;)
252 {
253 if (i >= oldfence || j >= b.p.fence())
254 break;
255 int cmp = unsignedCMP(p[i], b.p[j]);
256 if (cmp == 0)
257 {
258 if (k != i) p[k] = p[i];
259 ++i; ++k; ++j;
260 }
261 else if (cmp < 0)
262 ++i;
263 else
264 ++j;
265 }
266 while (k++ < oldfence)
267 {
268 --count;
269 p.del_high();
270 }
271 }
272 }
273
274 int unsignedOXPSet::OK()
/* [<][>][^][v][top][bottom][index][help] */
275 {
276 int v = p.OK();
277 v &= count == p.length();
278 for (int i = p.low(); i < p.high(); ++i) v &= unsignedCMP(p[i], p[i+1]) < 0;
279 if (!v) error("invariant failure");
280 return v;
281 }