modules/up/src/gnug++/unsigned.XPlex.cc

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

FUNCTIONS

This source file includes following functions.
  1. unsignedXPlex
  2. unsignedXPlex
  3. unsignedXPlex
  4. make_initial_chunks
  5. unsignedXPlex
  6. unsignedXPlex
  7. cache
  8. cache
  9. owns
  10. dosucc
  11. dopred
  12. add_high
  13. del_high
  14. add_low
  15. del_low
  16. reverse
  17. fill
  18. fill
  19. clear
  20. 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     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 "unsigned.XPlex.h"
  25 
  26 
  27 unsignedXPlex:: unsignedXPlex()
     /* [<][>][^][v][top][bottom][index][help] */
  28 {
  29   lo = fnc = 0;
  30   csize = DEFAULT_INITIAL_CAPACITY;
  31   unsigned* data = new unsigned[csize];
  32   set_cache(new unsignedIChunk(data,  lo, lo, fnc, lo+csize));
  33   hd = ch;
  34 }
  35 
  36 unsignedXPlex:: unsignedXPlex(int chunksize)
     /* [<][>][^][v][top][bottom][index][help] */
  37 {
  38   if (chunksize == 0) error("invalid constructor specification");
  39   lo = fnc = 0;
  40   if (chunksize > 0)
  41   {
  42     csize = chunksize;
  43     unsigned* data = new unsigned[csize];
  44     set_cache(new unsignedIChunk(data,  lo, lo, fnc, csize));
  45     hd = ch;
  46   }
  47   else
  48   {
  49     csize = -chunksize;
  50     unsigned* data = new unsigned[csize];
  51     set_cache(new unsignedIChunk(data,  chunksize, lo, fnc, fnc));
  52     hd = ch;
  53   }
  54 }
  55 
  56 
  57 unsignedXPlex:: unsignedXPlex(int l, int chunksize)
     /* [<][>][^][v][top][bottom][index][help] */
  58 {
  59   if (chunksize == 0) error("invalid constructor specification");
  60   lo = fnc = l;
  61   if (chunksize > 0)
  62   {
  63     csize = chunksize;
  64     unsigned* data = new unsigned[csize];
  65     set_cache(new unsignedIChunk(data,  lo, lo, fnc, csize+lo));
  66     hd = ch;
  67   }
  68   else
  69   {
  70     csize = -chunksize;
  71     unsigned* data = new unsigned[csize];
  72     set_cache(new unsignedIChunk(data,  chunksize+lo, lo, fnc, fnc));
  73     hd = ch;
  74   }
  75 }
  76 
  77 void unsignedXPlex::make_initial_chunks(int up)
     /* [<][>][^][v][top][bottom][index][help] */
  78 {
  79   int need = fnc - lo;
  80   hd = 0;
  81   if (up)
  82   {
  83     int l = lo;
  84     do
  85     {
  86       int sz;
  87       if (need >= csize)
  88         sz = csize;
  89       else
  90         sz = need;
  91       unsigned* data = new unsigned [csize];
  92       unsignedIChunk* h = new unsignedIChunk(data,  l, l, l+sz, l+csize);
  93       if (hd != 0)
  94         h->link_to_next(hd);
  95       else
  96         hd = h;
  97       l += sz;
  98       need -= sz;
  99     } while (need > 0);
 100   }
 101   else
 102   {
 103     int hi = fnc;
 104     do
 105     {
 106       int sz;
 107       if (need >= csize)
 108         sz = csize;
 109       else
 110         sz = need;
 111       unsigned* data = new unsigned [csize];
 112       unsignedIChunk* h = new unsignedIChunk(data,  hi-csize, hi-sz, hi, hi);
 113       if (hd != 0)
 114         h->link_to_next(hd);
 115       hd = h;
 116       hi -= sz;
 117       need -= sz;
 118     } while (need > 0);
 119   }
 120   set_cache(hd);
 121 }
 122 
 123 unsignedXPlex:: unsignedXPlex(int l, int hi, const unsigned  initval, int chunksize)
     /* [<][>][^][v][top][bottom][index][help] */
 124 {
 125   lo = l;
 126   fnc = hi + 1;
 127   if (chunksize == 0)
 128   {
 129     csize = fnc - l;
 130     make_initial_chunks(1);
 131   }
 132   else if (chunksize < 0)
 133   {
 134     csize = -chunksize;
 135     make_initial_chunks(0);
 136   }
 137   else
 138   {
 139     csize = chunksize;
 140     make_initial_chunks(1);
 141   }
 142   fill(initval);
 143 }
 144 
 145 unsignedXPlex::unsignedXPlex(const unsignedXPlex& a)
     /* [<][>][^][v][top][bottom][index][help] */
 146 {
 147   lo = a.lo;
 148   fnc = a.fnc;
 149   csize = a.csize;
 150   make_initial_chunks();
 151   for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
 152 }
 153 
 154 void unsignedXPlex::operator= (const unsignedXPlex& a)
 155 {
 156   if (&a != this)
 157   {
 158     invalidate();
 159     lo = a.lo;
 160     fnc = a.fnc;
 161     csize = a.csize;
 162     make_initial_chunks();
 163     for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
 164   }
 165 }
 166 
 167 
 168 void unsignedXPlex::cache(int idx) const
     /* [<][>][^][v][top][bottom][index][help] */
 169 {
 170   const unsignedIChunk* tail = tl();
 171   const unsignedIChunk* t = ch;
 172   while (idx >= t->fence_index())
 173   {
 174     if (t == tail) index_error();
 175     t = (t->next());
 176   }
 177   while (idx < t->low_index())
 178   {
 179     if (t == hd) index_error();
 180     t = (t->prev());
 181   }
 182   set_cache(t);
 183 }
 184 
 185 
 186 void unsignedXPlex::cache(const unsigned* p) const
     /* [<][>][^][v][top][bottom][index][help] */
 187 {
 188   const unsignedIChunk* old = ch;
 189   const unsignedIChunk* t = ch;
 190   while (!t->actual_pointer(p))
 191   {
 192     t = (t->next());
 193     if (t == old) index_error();
 194   }
 195   set_cache(t);
 196 }
 197 
 198 int unsignedXPlex::owns(Pix px) const
     /* [<][>][^][v][top][bottom][index][help] */
 199 {
 200   unsigned* p = (unsigned*)px;
 201   const unsignedIChunk* old = ch;
 202   const unsignedIChunk* t = ch;
 203   while (!t->actual_pointer(p))
 204   {
 205     t = (t->next());
 206     if (t == old) { set_cache(t); return 0; }
 207   }
 208   set_cache(t);
 209   return 1;
 210 }
 211 
 212 
 213 unsigned* unsignedXPlex::dosucc(const unsigned* p) const
     /* [<][>][^][v][top][bottom][index][help] */
 214 {
 215   if (p == 0) return 0;
 216   const unsignedIChunk* old = ch;
 217   const unsignedIChunk* t = ch;
 218  
 219   while (!t->actual_pointer(p))
 220   {
 221     t = (t->next());
 222     if (t == old)  return 0;
 223   }
 224   int i = t->index_of(p) + 1;
 225   if (i >= fnc) return 0;
 226   if (i >= t->fence_index()) t = (t->next());
 227   set_cache(t);
 228   return (t->pointer_to(i));
 229 }
 230 
 231 unsigned* unsignedXPlex::dopred(const unsigned* p) const
     /* [<][>][^][v][top][bottom][index][help] */
 232 {
 233   if (p == 0) return 0;
 234   const unsignedIChunk* old = ch;
 235   const unsignedIChunk* t = ch;
 236   while (!t->actual_pointer(p))
 237   {
 238     t = (t->prev());
 239     if (t == old) return 0;
 240   }
 241   int i = t->index_of(p) - 1;
 242   if (i < lo) return 0;
 243   if (i < t->low_index()) t = (t->prev());
 244   set_cache(t);
 245   return (t->pointer_to(i));
 246 }
 247 
 248 
 249 int unsignedXPlex::add_high(const unsigned  elem)
     /* [<][>][^][v][top][bottom][index][help] */
 250 {
 251   unsignedIChunk* t = tl();
 252   if (!t->can_grow_high())
 253   {
 254     if (t->unsignedIChunk::empty() && one_chunk())
 255       t->clear(fnc);
 256     else
 257     {
 258       unsigned* data = new unsigned [csize];
 259       t = (new unsignedIChunk(data,  fnc, fnc, fnc,fnc+csize));
 260       t->link_to_prev(tl());
 261     }
 262   }
 263   *((t->unsignedIChunk::grow_high())) = elem;
 264   set_cache(t);
 265   return fnc++;
 266 }
 267 
 268 int unsignedXPlex::del_high ()
     /* [<][>][^][v][top][bottom][index][help] */
 269 {
 270   if (empty()) empty_error();
 271   unsignedIChunk* t = tl();
 272   t->unsignedIChunk::shrink_high();
 273   if (t->unsignedIChunk::empty() && !one_chunk())
 274   {
 275     unsignedIChunk* pred = t->prev();
 276     del_chunk(t);
 277     t = pred;
 278   }
 279   set_cache(t);
 280   return --fnc - 1;
 281 }
 282 
 283 int unsignedXPlex::add_low (const unsigned  elem)
     /* [<][>][^][v][top][bottom][index][help] */
 284 {
 285   unsignedIChunk* t = hd;
 286   if (!t->can_grow_low())
 287   {
 288     if (t->unsignedIChunk::empty() && one_chunk())
 289       t->cleardown(lo);
 290     else
 291     {
 292       unsigned* data = new unsigned [csize];
 293       hd = new unsignedIChunk(data,  lo-csize, lo, lo, lo);
 294       hd->link_to_next(t);
 295       t = hd;
 296     }
 297   }
 298   *((t->unsignedIChunk::grow_low())) = elem;
 299   set_cache(t);
 300   return --lo;
 301 }
 302 
 303 
 304 int unsignedXPlex::del_low ()
     /* [<][>][^][v][top][bottom][index][help] */
 305 {
 306   if (empty()) empty_error();
 307   unsignedIChunk* t = hd;
 308   t->unsignedIChunk::shrink_low();
 309   if (t->unsignedIChunk::empty() && !one_chunk())
 310   {
 311     hd = t->next();
 312     del_chunk(t);
 313     t = hd;
 314   }
 315   set_cache(t);
 316   return ++lo;
 317 }
 318 
 319 void unsignedXPlex::reverse()
     /* [<][>][^][v][top][bottom][index][help] */
 320 {
 321   unsigned tmp;
 322   int l = lo;
 323   int h = fnc - 1;
 324   unsignedIChunk* loch = hd;
 325   unsignedIChunk* hich = tl();
 326   while (l < h)
 327   {
 328     unsigned* lptr = loch->pointer_to(l);
 329     unsigned* hptr = hich->pointer_to(h);
 330     tmp = *lptr;
 331     *lptr = *hptr;
 332     *hptr = tmp;
 333     if (++l >= loch->fence_index()) loch = loch->next();
 334     if (--h < hich->low_index()) hich = hich->prev();
 335   }
 336 }
 337 
 338 void unsignedXPlex::fill(const unsigned  x)
     /* [<][>][^][v][top][bottom][index][help] */
 339 {
 340   for (int i = lo; i < fnc; ++i) (*this)[i] = x;
 341 }
 342 
 343 void unsignedXPlex::fill(const unsigned  x, int l, int hi)
     /* [<][>][^][v][top][bottom][index][help] */
 344 {
 345   for (int i = l; i <= hi; ++i) (*this)[i] = x;
 346 }
 347 
 348 
 349 void unsignedXPlex::clear()
     /* [<][>][^][v][top][bottom][index][help] */
 350 {
 351   if (fnc != lo)
 352   {
 353     unsignedIChunk* t = tl();
 354     while (t != hd)
 355     {
 356       unsignedIChunk* prv = t->prev();
 357       del_chunk(t);
 358       t = prv;
 359     }
 360     t->unsignedIChunk::clear(lo);
 361     set_cache(t);
 362     fnc = lo;
 363   }
 364 }
 365 
 366 
 367 int unsignedXPlex::OK () const
     /* [<][>][^][v][top][bottom][index][help] */
 368 {
 369   int v = hd != 0 && ch != 0;     // at least one chunk
 370 
 371   v &= fnc == tl()->fence_index();// last chunk fence == plex fence
 372   v &= lo == ((hd))->unsignedIChunk::low_index();    // first lo == plex lo
 373 
 374 // loop for others:
 375   int found_ch = 0;                   // to make sure ch is in list;
 376   const unsignedIChunk* t = (hd);
 377   for (;;)
 378   {
 379     if (t == ch) ++found_ch;
 380     v &= t->unsignedIChunk::OK();              // each chunk is OK
 381     if (t == tl())
 382       break;
 383     else                              // and has indices contiguous to succ
 384     {
 385       v &= t->top_index() == t->next()->base_index();
 386       if (t != hd)                  // internal chunks full
 387       {
 388         v &= !t->empty();
 389         v &= !t->can_grow_low();
 390         v &= !t->can_grow_high();
 391       }
 392       t = t->next();
 393     }
 394   }
 395   v &= found_ch == 1;
 396   if (!v) error("invariant failure");
 397   return v;
 398 }

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