## 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] */