## modules/up/src/gnug++/unsigned.Plex.cc

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. error
2. index_error
3. empty_error
4. full_error
5. unsignedIChunk
6. unsignedIChunk
7. re_index
8. clear
9. cleardown
10. OK
11. error
12. index_error
13. empty_error
14. full_error
15. unsignedPlex
16. append
17. prepend
18. reverse
19. fill
20. fill
21. del_chunk
22. invalidate
23. 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

/* [<][>][^][v][top][bottom][index][help] */