modules/up/src/rpsl/gnu/PrefixRange.Plex.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- error
- index_error
- empty_error
- full_error
- PrefixRangeIChunk
- PrefixRangeIChunk
- re_index
- clear
- cleardown
- OK
- error
- index_error
- empty_error
- full_error
- PrefixRangePlex
- 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 "PrefixRange.Plex.h"
24 #include <builtin.h>
25
26 // IChunk support
27
28 void PrefixRangeIChunk::error(const char* msg) const
/* [<][>][^][v][top][bottom][index][help] */
29 {
30 (*lib_error_handler)("PrefixRangeIChunk", msg);
31 }
32
33 void PrefixRangeIChunk::index_error() const
/* [<][>][^][v][top][bottom][index][help] */
34 {
35 error("attempt to use invalid index");
36 }
37
38 void PrefixRangeIChunk::empty_error() const
/* [<][>][^][v][top][bottom][index][help] */
39 {
40 error("invalid use of empty chunk");
41 }
42
43 void PrefixRangeIChunk::full_error() const
/* [<][>][^][v][top][bottom][index][help] */
44 {
45 error("attempt to extend chunk beyond bounds");
46 }
47
48 PrefixRangeIChunk:: ~PrefixRangeIChunk() {}
/* [<][>][^][v][top][bottom][index][help] */
49
50 PrefixRangeIChunk::PrefixRangeIChunk(PrefixRange* d,
/* [<][>][^][v][top][bottom][index][help] */
51 int baseidx,
52 int lowidx,
53 int fenceidx,
54 int topidx)
55 {
56 if (d == 0 || baseidx > lowidx || lowidx > fenceidx || fenceidx > topidx)
57 error("inconsistent specification");
58 data = d;
59 base = baseidx;
60 low = lowidx;
61 fence = fenceidx;
62 top = topidx;
63 nxt = prv = this;
64 }
65
66 void PrefixRangeIChunk:: re_index(int lo)
/* [<][>][^][v][top][bottom][index][help] */
67 {
68 int delta = lo - low;
69 base += delta;
70 low += delta;
71 fence += delta;
72 top += delta;
73 }
74
75
76 void PrefixRangeIChunk::clear(int lo)
/* [<][>][^][v][top][bottom][index][help] */
77 {
78 int s = top - base;
79 low = base = fence = lo;
80 top = base + s;
81 }
82
83 void PrefixRangeIChunk::cleardown(int hi)
/* [<][>][^][v][top][bottom][index][help] */
84 {
85 int s = top - base;
86 low = top = fence = hi;
87 base = top - s;
88 }
89
90 int PrefixRangeIChunk:: OK() const
/* [<][>][^][v][top][bottom][index][help] */
91 {
92 int v = data != 0; // have some data
93 v &= base <= low; // ok, index-wise
94 v &= low <= fence;
95 v &= fence <= top;
96
97 v &= nxt->prv == this; // and links are OK
98 v &= prv->nxt == this;
99 if (!v) error("invariant failure");
100 return(v);
101 }
102
103
104 // error handling
105
106
107 void PrefixRangePlex::error(const char* msg) const
/* [<][>][^][v][top][bottom][index][help] */
108 {
109 (*lib_error_handler)("Plex", msg);
110 }
111
112 void PrefixRangePlex::index_error() const
/* [<][>][^][v][top][bottom][index][help] */
113 {
114 error("attempt to access invalid index");
115 }
116
117 void PrefixRangePlex::empty_error() const
/* [<][>][^][v][top][bottom][index][help] */
118 {
119 error("attempted operation on empty plex");
120 }
121
122 void PrefixRangePlex::full_error() const
/* [<][>][^][v][top][bottom][index][help] */
123 {
124 error("attempt to increase size of plex past limit");
125 }
126
127 // generic plex ops
128
129 PrefixRangePlex:: ~PrefixRangePlex()
/* [<][>][^][v][top][bottom][index][help] */
130 {
131 invalidate();
132 }
133
134
135 void PrefixRangePlex::append (const PrefixRangePlex& a)
/* [<][>][^][v][top][bottom][index][help] */
136 {
137 for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]);
138 }
139
140 void PrefixRangePlex::prepend (const PrefixRangePlex& a)
/* [<][>][^][v][top][bottom][index][help] */
141 {
142 for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]);
143 }
144
145 void PrefixRangePlex::reverse()
/* [<][>][^][v][top][bottom][index][help] */
146 {
147 PrefixRange tmp;
148 int l = low();
149 int h = high();
150 while (l < h)
151 {
152 tmp = (*this)[l];
153 (*this)[l] = (*this)[h];
154 (*this)[h] = tmp;
155 next(l);
156 prev(h);
157 }
158 }
159
160
161 void PrefixRangePlex::fill(const PrefixRange& x)
/* [<][>][^][v][top][bottom][index][help] */
162 {
163 for (int i = lo; i < fnc; ++i) (*this)[i] = x;
164 }
165
166 void PrefixRangePlex::fill(const PrefixRange& x, int lo, int hi)
/* [<][>][^][v][top][bottom][index][help] */
167 {
168 for (int i = lo; i <= hi; ++i) (*this)[i] = x;
169 }
170
171
172 void PrefixRangePlex::del_chunk(PrefixRangeIChunk* x)
/* [<][>][^][v][top][bottom][index][help] */
173 {
174 if (x != 0)
175 {
176 x->unlink();
177 PrefixRange* data = (PrefixRange*)(x->invalidate());
178 delete [] data;
179 delete x;
180 }
181 }
182
183
184 void PrefixRangePlex::invalidate()
/* [<][>][^][v][top][bottom][index][help] */
185 {
186 PrefixRangeIChunk* t = hd;
187 if (t != 0)
188 {
189 PrefixRangeIChunk* tail = tl();
190 while (t != tail)
191 {
192 PrefixRangeIChunk* nxt = t->next();
193 del_chunk(t);
194 t = nxt;
195 }
196 del_chunk(t);
197 hd = 0;
198 }
199 }
200
201 int PrefixRangePlex::reset_low(int l)
/* [<][>][^][v][top][bottom][index][help] */
202 {
203 int old = lo;
204 int diff = l - lo;
205 if (diff != 0)
206 {
207 lo += diff;
208 fnc += diff;
209 PrefixRangeIChunk* t = hd;
210 do
211 {
212 t->re_index(t->low_index() + diff);
213 t = t->next();
214 } while (t != hd);
215 }
216 return old;
217 }
218
219
220
221