home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / g__lib / bitset.h < prev    next >
C/C++ Source or Header  |  1993-07-23  |  9KB  |  419 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.  
  6. This file is part of GNU CC.
  7.  
  8. GNU CC is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY.  No author or distributor
  10. accepts responsibility to anyone for the consequences of using it
  11. or for whether it serves any particular purpose or works at all,
  12. unless he says so in writing.  Refer to the GNU CC General Public
  13. License for full details.
  14.  
  15. Everyone is granted permission to copy, modify and redistribute
  16. GNU CC, but only under the conditions described in the
  17. GNU CC General Public License.   A copy of this license is
  18. supposed to have been given to you along with GNU CC so you
  19. can know your rights and responsibilities.  It should be in a
  20. file named COPYING.  Among other things, the copyright notice
  21. and this notice must be preserved on all copies.  
  22. */
  23.  
  24. #ifndef _BitSet_h
  25. #pragma once
  26.  
  27. #define _BitSet_h 1
  28.  
  29. #include <stream.h>
  30. #include <values.h>
  31.  
  32. #define BITSETBITS  BITS(short)
  33.  
  34. struct BitSetRep
  35. {
  36.   unsigned short  len;          // number of shorts in s
  37.   unsigned short  sz;           // allocated slots
  38.   unsigned short  virt;         // virtual 0 or 1
  39.   unsigned short  s[1];         // bits start here
  40.  
  41.   friend BitSetRep*   BitSetalloc(BitSetRep*, unsigned short*, int, int, int);
  42.   friend BitSetRep*   BitSetcopy(BitSetRep*, BitSetRep*);
  43.   friend BitSetRep*   BitSetresize(BitSetRep*, int);
  44.   friend BitSetRep*   BitSetop(BitSetRep*, BitSetRep*, BitSetRep*, char);
  45.   friend BitSetRep*   BitSetcmpl(BitSetRep*, BitSetRep*);
  46.  
  47. };
  48.  
  49. extern BitSetRep    _nilBitSetRep;
  50. class BitSet;
  51. class BitSetTmp;
  52.  
  53. class BitSetBit
  54. {
  55. protected:
  56.   BitSet*            src;
  57.   unsigned long      pos;
  58.  
  59.  public:
  60.                      BitSetBit(BitSet* v, int p);
  61.                      BitSetBit(BitSetBit& b);
  62.                      ~BitSetBit();
  63.   int                operator int();
  64.   int                operator = (int b);
  65.   int                operator == (int b);
  66.   int                operator != (int b);
  67. };
  68.  
  69. class BitSet
  70. {
  71.   friend class       BitSetTmp;
  72.  
  73. protected:
  74.   BitSetRep*          rep;
  75.  
  76.  
  77. public:
  78.  
  79. // constructors
  80.                      BitSet();
  81.                      BitSet(BitSet&);
  82.  
  83.                      ~BitSet();
  84.  
  85.   void               operator =  (BitSet& y);
  86.   void               operator =  (BitSetTmp& y);
  87.  
  88. // equality & subset tests
  89.  
  90.   friend int         operator == (BitSet& x, BitSet& y);
  91.   friend int         operator != (BitSet& x, BitSet& y);
  92.   friend int         operator <  (BitSet& x, BitSet& y);
  93.   friend int         operator <= (BitSet& x, BitSet& y);
  94.   friend int         operator >  (BitSet& x, BitSet& y);
  95.   friend int         operator >= (BitSet& x, BitSet& y);
  96.  
  97. // set operators
  98.  
  99.   BitSetTmp          operator |  (BitSet& y);
  100.   BitSetTmp          operator |  (BitSetTmp& y);
  101.   void               operator |= (BitSet& y);
  102.   BitSetTmp          operator &  (BitSet& y);
  103.   BitSetTmp          operator &  (BitSetTmp& y);
  104.   void               operator &= (BitSet& y);
  105.   BitSetTmp          operator -  (BitSet& y);
  106.   BitSetTmp          operator -  (BitSetTmp& y);
  107.   void               operator -= (BitSet& y);
  108.   BitSetTmp          operator ^  (BitSet& y);
  109.   BitSetTmp          operator ^  (BitSetTmp& y);
  110.   void               operator ^= (BitSet& y);
  111.  
  112.   BitSetTmp          operator ~  ();
  113.   void               complement();
  114.  
  115. // individual bit manipulation
  116.  
  117.   void               set(int pos);
  118.   void               set(int from, int to);
  119.   void               set(); // set all
  120.  
  121.   void               clear(int pos);
  122.   void               clear(int from, int to);
  123.   void               clear(); // clear all
  124.  
  125.   void               invert(int pos);
  126.   void               invert(int from, int to);
  127.  
  128.   int                test(int pos);
  129.   int                test(int from, int to);
  130.  
  131.   BitSetBit          operator [] (int i);
  132.   
  133. // iterators
  134.  
  135.   int                first(int b = 1);
  136.   int                last(int b = 1);
  137.  
  138.   int                next(int pos, int b = 1);
  139.   int                previous(int pos, int b = 1);
  140.  
  141. // status
  142.  
  143.   int                empty();
  144.   int                virtual_bit();
  145.   int                count(int b = 1);
  146.   
  147. // convertors & IO
  148.  
  149.   friend BitSetTmp   atoBitSet(const char* s, 
  150.                                char f='0', char t='1', char star='*');
  151.   friend const char* BitSettoa(BitSet& x, 
  152.                                char f='0', char t='1', char star='*');
  153.  
  154.   friend BitSetTmp   shorttoBitSet(unsigned short w);
  155.   friend BitSetTmp   longtoBitSet(unsigned long w);
  156.  
  157.   friend ostream&    operator << (ostream& s, BitSet& x);
  158.  
  159. // misc
  160.  
  161.   void               error(char* msg);
  162.   int                OK();
  163. };
  164.  
  165. class BitSetTmp: public BitSet
  166. {
  167.   friend class       BitSet;
  168. public:
  169.                      BitSetTmp(BitSetRep*);
  170.                      BitSetTmp(BitSet& x);
  171.                      BitSetTmp(BitSetTmp& x);
  172.                      ~BitSetTmp();
  173.  
  174.   BitSetTmp          operator |  (BitSet& y);
  175.   BitSetTmp          operator &  (BitSet& y);
  176.   BitSetTmp          operator -  (BitSet& y);
  177.   BitSetTmp          operator ^  (BitSet& y);
  178.  
  179.   BitSetTmp          operator ~  ();
  180. };
  181.  
  182. //#ifdef __OPTIMIZE__
  183.  
  184. inline int BitSet_index(int l)
  185. {
  186.   return (unsigned)(l) / BITSETBITS;
  187. }
  188.  
  189. inline int BitSet_pos(int l)
  190. {
  191.   return l & (BITSETBITS - 1);
  192. }
  193.  
  194. inline BitSet::BitSet()
  195.   rep = &_nilBitSetRep;
  196. }
  197.  
  198. inline BitSet::BitSet(BitSet& x)
  199.   rep = BitSetcopy(0, x.rep);
  200. }
  201.  
  202. inline BitSetTmp::BitSetTmp(BitSetRep* x) 
  203. {
  204.   rep = x;
  205. }
  206.  
  207. inline BitSetTmp::BitSetTmp(BitSet& x)
  208. {
  209.   rep = x.rep; x.rep = &_nilBitSetRep;
  210. }
  211.  
  212. inline BitSetTmp::BitSetTmp(BitSetTmp& x)
  213. {
  214.   rep = x.rep; x.rep = &_nilBitSetRep;
  215. }
  216.  
  217. inline BitSet::~BitSet()
  218.   if (rep != &_nilBitSetRep) delete rep;
  219. }
  220.  
  221. inline BitSetTmp::~BitSetTmp() {}
  222.  
  223. inline void BitSet::operator =  (BitSet& y)
  224.   rep = BitSetcopy(rep, y.rep);
  225. }
  226.  
  227. inline void BitSet::operator =  (BitSetTmp& y)
  228.   if (rep != &_nilBitSetRep) delete rep;
  229.   rep = y.rep; y.rep = &_nilBitSetRep;
  230. }
  231.  
  232. inline int operator != (BitSet& x, BitSet& y)
  233. {
  234.   return !(x == y);
  235. }
  236.  
  237. inline int operator>(BitSet& x, BitSet& y)
  238. {
  239.   return y < x;
  240. }
  241.  
  242. inline int operator>=(BitSet& x, BitSet& y)
  243. {
  244.   return y <= x;
  245. }
  246.  
  247. inline BitSetTmp BitSet::operator & (BitSet& y)
  248. {
  249.   return  BitSetop(rep, y.rep, 0, '&');
  250. }
  251.  
  252. inline BitSetTmp BitSet::operator & (BitSetTmp& y)
  253. {
  254.   y.rep = BitSetop(rep, y.rep, y.rep, '&'); return y;
  255. }
  256.  
  257. inline BitSetTmp BitSetTmp::operator & (BitSet& y)
  258. {
  259.   rep = BitSetop(rep, y.rep, rep, '&'); return *this;
  260. }
  261.  
  262. inline void BitSet::operator &= (BitSet& y)
  263. {
  264.   rep = BitSetop(rep, y.rep, rep, '&'); 
  265. }
  266.  
  267. inline BitSetTmp BitSet::operator | (BitSet& y)
  268. {
  269.   return  BitSetop(rep, y.rep, 0, '|');
  270. }
  271.  
  272. inline BitSetTmp BitSet::operator | (BitSetTmp& y)
  273. {
  274.   y.rep = BitSetop(rep, y.rep, y.rep, '|'); return y;
  275. }
  276.  
  277. inline BitSetTmp BitSetTmp::operator | (BitSet& y)
  278. {
  279.   rep = BitSetop(rep, y.rep, rep, '|'); return *this;
  280. }
  281.  
  282. inline void BitSet::operator |= (BitSet& y)
  283. {
  284.   rep = BitSetop(rep, y.rep, rep, '|'); 
  285. }
  286.  
  287. inline BitSetTmp BitSet::operator ^ (BitSet& y)
  288. {
  289.   return  BitSetop(rep, y.rep, 0, '^');
  290. }
  291.  
  292. inline BitSetTmp BitSet::operator ^ (BitSetTmp& y)
  293. {
  294.   y.rep = BitSetop(rep, y.rep, y.rep, '^'); return y;
  295. }
  296.  
  297. inline BitSetTmp BitSetTmp::operator ^ (BitSet& y)
  298. {
  299.   rep = BitSetop(rep, y.rep, rep, '^'); return *this;
  300. }
  301.  
  302. inline void BitSet::operator ^= (BitSet& y)
  303. {
  304.   rep = BitSetop(rep, y.rep, rep, '^'); 
  305. }
  306.  
  307. inline BitSetTmp BitSet::operator - (BitSet& y)
  308. {
  309.   return  BitSetop(rep, y.rep, 0, '-');
  310. }
  311.  
  312. inline BitSetTmp BitSet::operator - (BitSetTmp& y)
  313. {
  314.   y.rep = BitSetop(rep, y.rep, y.rep, '-'); return y;
  315. }
  316.  
  317. inline BitSetTmp BitSetTmp::operator - (BitSet& y)
  318. {
  319.   rep = BitSetop(rep, y.rep, rep, '-'); return *this;
  320. }
  321.  
  322. inline void BitSet::operator -= (BitSet& y)
  323. {
  324.   rep = BitSetop(rep, y.rep, rep, '-'); 
  325. }
  326.  
  327. inline BitSetTmp BitSet::operator ~ ()
  328. {
  329.   return BitSetcmpl(rep, 0);
  330. }
  331.  
  332. inline BitSetTmp BitSetTmp::operator ~ ()
  333. {
  334.   rep = BitSetcmpl(rep, rep); return *this;
  335. }
  336.  
  337. inline void BitSet::complement()
  338. {
  339.   rep = BitSetcmpl(rep, rep);
  340. }
  341.  
  342. inline int BitSet::virtual_bit()
  343. {
  344.   return rep->virt;
  345. }
  346.  
  347. inline int BitSet::first(int b = 1)
  348. {
  349.   return next(-1, b);
  350. }
  351.  
  352. inline int BitSet::test(int p)
  353. {
  354.   if (p < 0) error("Illegal bit index");
  355.   int index = BitSet_index(p);
  356.   return (index >= rep->len)? rep->virt : 
  357.          ((rep->s[index] & (1 << BitSet_pos(p))) != 0);
  358. }
  359.  
  360.  
  361. inline void BitSet::clear()
  362. {
  363.   if (rep->len > 0) bzero(rep->s, rep->sz * sizeof(short));
  364.   rep->len = rep->virt = 0;
  365. }
  366.  
  367. inline void BitSet::set()
  368. {
  369.   rep = BitSetalloc(rep, 0, 0, 1, 0);
  370. }
  371.  
  372. inline BitSetBit::BitSetBit(BitSetBit& b)
  373. {
  374.   src = b.src;  pos = b.pos;
  375. }
  376.  
  377. inline BitSetBit::BitSetBit(BitSet* v, int p)
  378. {
  379.   src = v;  pos = p;
  380. }
  381.  
  382. inline BitSetBit::~BitSetBit() {}
  383.  
  384. inline int BitSetBit::operator int()
  385. {
  386.   return src->test(pos);
  387. }
  388.  
  389. inline int BitSetBit::operator = (int b)
  390. {
  391.   if (b) src->set(pos); else src->clear(pos); return b;
  392. }
  393.  
  394. inline int BitSetBit::operator == (int b)
  395. {
  396.   return src->test(pos) == b;
  397. }
  398.  
  399. inline int BitSetBit::operator != (int b)
  400. {
  401.   return src->test(pos) != b;
  402. }
  403.  
  404. inline BitSetBit BitSet::operator [] (int i)
  405. {
  406.   if (i < 0) error("illegal bit index");
  407.   return BitSetBit(this, i);
  408. }
  409.  
  410.  
  411. //#endif
  412.  
  413. #endif
  414.