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

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

FUNCTIONS

This source file includes following functions.
  1. seek
  2. add
  3. del
  4. 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 
   6 This file is part of the GNU C++ Library.  This library is free
   7 software; you can redistribute it and/or modify it under the terms of
   8 the GNU Library General Public License as published by the Free
   9 Software Foundation; either version 2 of the License, or (at your
  10 option) any later version.  This library is distributed in the hope
  11 that it will be useful, but WITHOUT ANY WARRANTY; without even the
  12 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13 PURPOSE.  See the GNU Library General Public License for more details.
  14 You should have received a copy of the GNU Library General Public
  15 License along with this library; if not, write to the Free Software
  16 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17 */
  18 
  19 #ifdef __GNUG__
  20 #pragma implementation
  21 #endif
  22 #include "config.h"
  23 #include "unsigned.OXPSet.h"
  24 
  25 
  26 Pix unsignedOXPSet::seek(unsigned  item)
     /* [<][>][^][v][top][bottom][index][help] */
  27 {
  28   int l = p.low();
  29   int h = p.high();
  30   while (l <= h)
  31   {
  32     int mid = (l + h) / 2;
  33     int cmp = unsignedCMP(item, p[mid]);
  34     if (cmp == 0)
  35       return p.index_to_Pix(mid);
  36     else if (cmp < 0)
  37       h = mid - 1;
  38     else
  39       l = mid + 1;
  40   }
  41   return 0;
  42 }
  43 
  44 Pix unsignedOXPSet::add(unsigned  item)
     /* [<][>][^][v][top][bottom][index][help] */
  45 {
  46   if (count == 0) 
  47   {
  48     ++count;
  49     return p.index_to_Pix(p.add_high(item));
  50   }
  51   int l = p.low();
  52   int h = p.high();
  53   while (l <= h)
  54   {
  55     int mid = (l + h) / 2;
  56     int cmp = unsignedCMP(item, p[mid]);
  57     if (cmp == 0)
  58       return p.index_to_Pix(mid);
  59     else if (cmp < 0)
  60         h = mid - 1;
  61     else
  62       l = mid + 1;
  63   }
  64   // add on whichever side is shortest
  65   ++count;
  66   if (l == p.fence())
  67     return p.index_to_Pix(p.add_high(item));
  68   else if (l == p.low())
  69     return p.index_to_Pix(p.add_low(item));
  70   else 
  71   {
  72     if (p.fence() - l < l - p.low())
  73     {
  74       h = p.add_high(p.high_element());
  75       for (int i = h - 1; i > l; --i) p[i] = p[i-1];
  76     }
  77     else
  78     {
  79       --l;
  80       h = p.add_low(p.low_element());
  81       for (int i = h + 1; i < l; ++i) p[i] = p[i+1];
  82     }
  83     p[l] = item;
  84     return p.index_to_Pix(l);
  85   }
  86 }
  87 
  88 void unsignedOXPSet::del(unsigned  item)
     /* [<][>][^][v][top][bottom][index][help] */
  89 {
  90   int l = p.low();
  91   int h = p.high();
  92   while (l <= h)
  93   {
  94     int mid = (l + h) / 2;
  95     int cmp = unsignedCMP(item, p[mid]);
  96     if (cmp == 0)
  97     {
  98       --count;
  99       if (p.high() - mid < mid - p.low())
 100       {
 101         for (int i = mid; i < p.high(); ++i) p[i] = p[i+1];
 102         p.del_high();
 103       }
 104       else
 105       {
 106         for (int i = mid; i > p.low(); --i) p[i] = p[i-1];
 107         p.del_low();
 108       }
 109       return;
 110     }
 111     else if (cmp < 0)
 112       h = mid - 1;
 113     else
 114       l = mid + 1;
 115   }
 116 }
 117 
 118 int unsignedOXPSet::operator <= (const unsignedOXPSet& b)
 119 {
 120   if (count > b.count) return 0;
 121   int i = p.low();
 122   int j = b.p.low();
 123   for (;;)
 124   {
 125     if (i >= p.fence())
 126       return 1;
 127     else if (j >= b.p.fence()) 
 128       return 0;
 129     int cmp = unsignedCMP(p[i], b.p[j]);
 130     if (cmp == 0)
 131     {
 132       ++i; ++j;
 133     }
 134     else if (cmp < 0)
 135       return 0;
 136     else
 137       ++j;
 138   }
 139 }
 140 
 141 int unsignedOXPSet::operator == (const unsignedOXPSet& b)
 142 {
 143   int n = count;
 144   if (n != b.count) return 0;
 145   if (n == 0) return 1;
 146   int i = p.low();
 147   int j = b.p.low();
 148   while (n-- > 0) if (!unsignedEQ(p[i++], b.p[j++])) return 0;
 149   return 1;
 150 }
 151 
 152 
 153 void unsignedOXPSet::operator |= (const unsignedOXPSet& b)
 154 {
 155   if (&b == this || b.count == 0)
 156     return;
 157   else if (b.count <= 2) // small b -- just add
 158     for (Pix i = b.first(); i; b.next(i)) add(b(i));
 159   else
 160   {
 161     // strategy: merge into top of p, simultaneously killing old bottom
 162     int oldfence = p.fence();
 163     int i = p.low();
 164     int j = b.p.low();
 165     for (;;)
 166     {
 167       if (i == oldfence)
 168       {
 169         while (j < b.p.fence()) p.add_high(b.p[j++]);
 170         break;
 171       }
 172       else if (j == b.p.fence())
 173       {
 174         while (i++ < oldfence) 
 175         {
 176           p.add_high(p.low_element());
 177           p.del_low();
 178         }
 179         break;
 180       }
 181       int cmp = unsignedCMP(p[i], b.p[j]);
 182       if (cmp <= 0)
 183       {
 184         ++i;
 185         if (cmp == 0)  ++j;
 186         p.add_high(p.low_element());
 187         p.del_low();
 188       }
 189       else
 190         p.add_high(b.p[j++]);
 191     }
 192     count = p.length();
 193   }
 194 }
 195 
 196 
 197 
 198 void unsignedOXPSet::operator -= (const unsignedOXPSet& b)
 199 {
 200   if (&b == this)
 201     clear();
 202   else if (count != 0 && b.count != 0)
 203   {
 204     int i = p.low();
 205     int k = i;
 206     int j = b.p.low();
 207     int oldfence = p.fence();
 208     for (;;)
 209     {
 210       if (i >= oldfence)
 211         break;
 212       else if (j >= b.p.fence())
 213       {
 214         if (k != i)
 215           while (i < oldfence) p[k++] = p[i++];
 216         else
 217           k = oldfence;
 218         break;
 219       }
 220       int cmp = unsignedCMP(p[i], b.p[j]);
 221       if (cmp == 0)
 222       {
 223         ++i; ++j;
 224       }
 225       else if (cmp < 0)
 226       {
 227         if (k != i) p[k] = p[i];
 228         ++i; ++k;
 229       }
 230       else
 231         j++;
 232     }
 233     while (k++ < oldfence)
 234     {
 235       --count;
 236       p.del_high();
 237     }
 238   }
 239 }
 240 
 241 void unsignedOXPSet::operator &= (const unsignedOXPSet& b)
 242 {
 243   if (b.count == 0)
 244     clear();
 245   else if (&b != this && count != 0)
 246   {
 247     int i = p.low();
 248     int k = i;
 249     int j = b.p.low();
 250     int oldfence = p.fence();
 251     for (;;)
 252     {
 253       if (i >= oldfence || j >= b.p.fence())
 254         break;
 255       int cmp = unsignedCMP(p[i], b.p[j]);
 256       if (cmp == 0)
 257       {
 258         if (k != i) p[k] = p[i];
 259         ++i; ++k; ++j;
 260       }
 261       else if (cmp < 0)
 262         ++i;
 263       else
 264         ++j;
 265     }
 266     while (k++ < oldfence)
 267     {
 268       --count;
 269       p.del_high();
 270     }
 271   }
 272 }
 273 
 274 int unsignedOXPSet::OK()
     /* [<][>][^][v][top][bottom][index][help] */
 275 {
 276   int v = p.OK();
 277   v &= count == p.length();
 278   for (int i = p.low(); i < p.high(); ++i) v &= unsignedCMP(p[i], p[i+1]) < 0;
 279   if (!v) error("invariant failure");
 280   return v;
 281 }

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