home *** CD-ROM | disk | FTP | other *** search
- // This may look like C code, but it is really -*- C++ -*-
- /*
- Copyright (C) 1988 Free Software Foundation
- written by Doug Lea (dl@rocky.oswego.edu)
- based on code by Marc Shapiro (shapiro@sor.inria.fr)
-
- This file is part of GNU CC.
-
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the GNU CC General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- GNU CC, but only under the conditions described in the
- GNU CC General Public License. A copy of this license is
- supposed to have been given to you along with GNU CC so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies.
- */
-
- #include <stream.h>
- #include "<T>.Plex.h"
-
- // IChunk support
-
- void <T>IChunk::error(char* msg)
- {
- (*lib_error_handler)("<T>IChunk", msg);
- }
-
- void <T>IChunk::index_error()
- {
- error("attempt to use invalid index");
- }
-
- void <T>IChunk::empty_error()
- {
- error("invalid use of empty chunk");
- }
-
- void <T>IChunk::full_error()
- {
- error("attempt to extend chunk beyond bounds");
- }
-
- <T>IChunk::<T>IChunk(<T>* d,
- int baseidx,
- int lowidx,
- int fenceidx,
- int topidx)
- {
- if (d == 0 || baseidx > lowidx || lowidx > fenceidx || fenceidx > topidx)
- error("inconsistent specification");
- data = d;
- base = baseidx;
- low = lowidx;
- fence = fenceidx;
- top = topidx;
- nxt = prv = this;
- }
-
- void <T>IChunk:: re_index(int lo)
- {
- int delta = lo - low;
- base += delta;
- low += delta;
- fence += delta;
- top += delta;
- }
-
-
- void <T>IChunk::clear(int lo)
- {
- int s = top - base;
- low = base = fence = lo;
- top = base + s;
- }
-
- int <T>IChunk:: OK()
- {
- int v = data != 0; // have some data
- v &= base <= low; // ok, index-wise
- v &= low <= fence;
- v &= fence <= top;
-
- v &= nxt->prv == this; // and links are OK
- v &= prv->nxt == this;
- if (!v) error("invariant failure");
- return(v);
- }
-
-
- // error handling
-
-
- void <T>Plex::error(char* msg)
- {
- (*lib_error_handler)("Plex", msg);
- }
-
- void <T>Plex::index_error()
- {
- error("attempt to access invalid index");
- }
-
- void <T>Plex::empty_error()
- {
- error("attempted operation on empty plex");
- }
-
- void <T>Plex::full_error()
- {
- error("attempt to increase size of plex past limit");
- }
-
- // generic plex ops
-
-
- void <T>Plex::append (const <T>Plex& a)
- {
- for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]);
- }
-
- void <T>Plex::prepend (const <T>Plex& a)
- {
- for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]);
- }
-
- void <T>Plex::reverse()
- {
- <T> tmp;
- int l = low();
- int h = high();
- while (l < h)
- {
- tmp = (*this)[l];
- (*this)[l] = (*this)[h];
- (*this)[h] = tmp;
- next(l);
- prev(h);
- }
- }
-
-
- void <T>Plex::fill(<T&> x)
- {
- for (int i = lo; i < fnc; ++i) (*this)[i] = x;
- }
-
- void <T>Plex::fill(<T&> x, int lo, int hi)
- {
- for (int i = lo; i <= hi; ++i) (*this)[i] = x;
- }
-
- void <T>Plex::del_chunk(<T>IChunk* x)
- {
- if (x != 0)
- {
- x->unlink();
- int sz = x->size();
- <T>* data = (<T>*)(x->invalidate());
- delete [sz] data;
- }
- }
-
-
- void <T>Plex::invalidate()
- {
- <T>IChunk* t = hd;
- if (t != 0)
- {
- <T>IChunk* tail = tl();
- while (t != tail)
- {
- <T>IChunk* nxt = t->next();
- del_chunk(t);
- t = nxt;
- }
- del_chunk(t);
- hd = 0;
- }
- }
-
- int <T>Plex::reset_low(int l)
- {
- int old = lo;
- int diff = l - lo;
- if (diff != 0)
- {
- record_change();
- lo += diff;
- fnc += diff;
- <T>IChunk* t = hd;
- do
- {
- t->re_index(t->low_index() + diff);
- t = t->next();
- } while (t != hd);
- }
- return old;
- }
-
- // non-implemented virtuals
- // these are defined to do nonsensical but type-legal things
- // They need to be defined in order to fill the vtable
-
- <T>& <T>Plex::operator [](int){ error("undefined operation"); return *(<T>*)0;}
- <T>& <T>Plex::operator ()(Pix){ error("undefined operation"); return *(<T>*)0;}
- <T>& <T>Plex::high_element(){ error("undefined operation"); return *(<T>*)0;}
- <T>& <T>Plex::low_element (){ error("undefined operation"); return *(<T>*)0;}
- int <T>Plex::valid(int) { error("undefined operation"); return 0; }
- int <T>Plex::owns(Pix) { error("undefined operation"); return 0; }
- int <T>Plex::low() { error("undefined operation"); return 0; }
- int <T>Plex::high() { error("undefined operation"); return 0; }
- void <T>Plex::next(int&) { error("undefined operation"); }
- void <T>Plex::prev(int&) { error("undefined operation"); }
- int <T>Plex::Pix_to_index(Pix) { error("undefined operation"); return 0; }
- Pix <T>Plex::index_to_Pix(int) { error("undefined operation"); return 0; }
- int <T>Plex::add_high(const <T&>) { error("undefined operation"); return 0; }
- int <T>Plex::add_low(const <T&>) { error("undefined operation"); return 0; }
- int <T>Plex::del_high() { error("undefined operation"); return 0; }
- int <T>Plex::del_low() { error("undefined operation"); return 0; }
- int <T>Plex::can_add_high() { error("undefined operation"); return 0; }
- int <T>Plex::can_add_low() { error("undefined operation"); return 0; }
- int <T>Plex::full() { error("undefined operation"); return 0; }
- int <T>Plex::OK() { error("undefined operation"); return 0; }
- void <T>Plex::clear() { error("undefined operation"); }
- Pix <T>Plex::first() { error("undefined operation"); return 0; }
- Pix <T>Plex::last() { error("undefined operation"); return 0; }
- void <T>Plex::prev(Pix&) { error("undefined operation"); }
- void <T>Plex::next(Pix&) { error("undefined operation"); }
-
-
-