home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / libg_ / libgpp / !libgpp / gen / ccp / Plex < prev    next >
Text File  |  1995-06-16  |  4KB  |  223 lines

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