home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / gxxinc.lzh / GXXINC / XBITSET.H < prev    next >
C/C++ Source or Header  |  1991-07-07  |  9KB  |  386 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. #ifdef __GNUG__
  26. #pragma once
  27. #pragma interface
  28. #endif
  29.  
  30. #define _BitSet_h 1
  31.  
  32. #include <stream.h>
  33. #include <values.h>
  34.  
  35. #define BITSETBITS  BITS(short)
  36.  
  37. struct BitSetRep
  38. {
  39.   unsigned short  len;          // number of shorts in s
  40.   unsigned short  sz;           // allocated slots
  41.   unsigned short  virt;         // virtual 0 or 1
  42.   unsigned short  s[1];         // bits start here
  43. };
  44.  
  45. extern BitSetRep*   BitSetalloc(BitSetRep*, const unsigned short*, 
  46.                                 int, int, int);
  47. extern BitSetRep*   BitSetcopy(BitSetRep*, const BitSetRep*);
  48. extern BitSetRep*   BitSetresize(BitSetRep*, int);
  49. extern BitSetRep*   BitSetop(const BitSetRep*, const BitSetRep*, 
  50.                              BitSetRep*, char);
  51. extern BitSetRep*   BitSetcmpl(const BitSetRep*, BitSetRep*);
  52.  
  53.  
  54. extern BitSetRep    _nilBitSetRep;
  55.  
  56. class BitSet;
  57.  
  58. class BitSetBit
  59. {
  60. protected:
  61.   BitSet*            src;
  62.   unsigned long      pos;
  63.  
  64.  public:
  65.                      BitSetBit(BitSet* v, int p);
  66.                      BitSetBit(const BitSetBit& b);
  67.                     ~BitSetBit();
  68.                      operator int();
  69.   int                operator = (int b);
  70.   int                operator == (int b);
  71.   int                operator != (int b);
  72. };
  73.  
  74. class BitSet
  75. {
  76. protected:
  77.   BitSetRep*          rep;
  78.  
  79.   
  80. public:
  81.  
  82. // constructors
  83.                      BitSet();
  84.                      BitSet(const BitSet&);
  85.  
  86.                     ~BitSet();
  87.  
  88.   void               operator =  (const BitSet& y);
  89.  
  90. // equality & subset tests
  91.  
  92.   friend int         operator == (const BitSet& x, const BitSet& y);
  93.   friend int         operator != (const BitSet& x, const BitSet& y);
  94.   friend int         operator <  (const BitSet& x, const BitSet& y);
  95.   friend int         operator <= (const BitSet& x, const BitSet& y);
  96.   friend int         operator >  (const BitSet& x, const BitSet& y);
  97.   friend int         operator >= (const BitSet& x, const BitSet& y);
  98.  
  99.  
  100. // operations on self
  101.  
  102.   void               operator |= (const BitSet& y);
  103.   void               operator &= (const BitSet& y);
  104.   void               operator -= (const BitSet& y);
  105.   void               operator ^= (const BitSet& y);
  106.  
  107.   void               complement();
  108.  
  109. // individual bit manipulation
  110.  
  111.   void               set(int pos);
  112.   void               set(int from, int to);
  113.   void               set(); // set all
  114.  
  115.   void               clear(int pos);
  116.   void               clear(int from, int to);
  117.   void               clear(); // clear all
  118.  
  119.   void               invert(int pos);
  120.   void               invert(int from, int to);
  121.  
  122.   int                test(int pos) const;
  123.   int                test(int from, int to) const;
  124.  
  125.   BitSetBit          operator [] (int i);
  126.   
  127. // iterators
  128.  
  129.   int                first(int b = 1) const;
  130.   int                last(int b = 1) const;
  131.  
  132.   int                next(int pos, int b = 1) const;
  133.   int                previous(int pos, int b = 1) const;
  134.  
  135. // status
  136.  
  137.   int                empty() const;
  138.   int                virtual_bit() const;
  139.   int                count(int b = 1) const;
  140.   
  141. // convertors & IO
  142.  
  143.   friend BitSet      atoBitSet(const char* s, 
  144.                                char f='0', char t='1', char star='*');
  145.   friend const char* BitSettoa(const BitSet& x, 
  146.                                char f='0', char t='1', char star='*');
  147.  
  148.   friend BitSet      shorttoBitSet(unsigned short w);
  149.   friend BitSet      longtoBitSet(unsigned long w);
  150.  
  151.   friend ostream&    operator << (ostream& s, const BitSet& x);
  152.  
  153. // procedural versions of operators
  154.  
  155.   friend void        and(const BitSet& x, const BitSet& y, BitSet& r);
  156.   friend void        or(const BitSet& x, const BitSet& y, BitSet& r);
  157.   friend void        xor(const BitSet& x, const BitSet& y, BitSet& r);
  158.   friend void        diff(const BitSet& x, const BitSet& y, BitSet& r);
  159.   friend void        complement(const BitSet& x, BitSet& r);
  160.  
  161. // misc
  162.  
  163.   volatile void      error(const char* msg) const;
  164.   int                OK() const;
  165. };
  166.  
  167.  
  168. typedef BitSet BitSetTmp;
  169.  
  170.  
  171.   BitSet      operator |  (const BitSet& x, const BitSet& y);
  172.   BitSet      operator &  (const BitSet& x, const BitSet& y);
  173.   BitSet      operator -  (const BitSet& x, const BitSet& y);
  174.   BitSet      operator ^  (const BitSet& x, const BitSet& y);
  175.  
  176.   BitSet      operator ~  (const BitSet& x);
  177.  
  178. // These are inlined regardless of optimization
  179.  
  180. inline int BitSet_index(int l)
  181. {
  182.   return (unsigned)(l) / BITSETBITS;
  183. }
  184.  
  185. inline int BitSet_pos(int l)
  186. {
  187.   return l & (BITSETBITS - 1);
  188. }
  189.  
  190. #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
  191.  
  192.  
  193. inline BitSet::BitSet() : rep(&_nilBitSetRep) {}
  194.  
  195. inline BitSet::BitSet(const BitSet& x) :rep(BitSetcopy(0, x.rep)) {}
  196.  
  197. inline BitSet::~BitSet() { if (rep != &_nilBitSetRep) delete rep; }
  198.  
  199. inline void BitSet::operator =  (const BitSet& y)
  200.   rep = BitSetcopy(rep, y.rep);
  201. }
  202.  
  203. inline int operator != (const BitSet& x, const BitSet& y) { return !(x == y); }
  204.  
  205. inline int operator >  (const BitSet& x, const BitSet& y) { return y < x; }
  206.  
  207. inline int operator >= (const BitSet& x, const BitSet& y) { return y <= x; }
  208.  
  209. inline void and(const BitSet& x, const BitSet& y, BitSet& r)
  210. {
  211.   r.rep =  BitSetop(x.rep, y.rep, r.rep, '&');
  212. }
  213.  
  214. inline void or(const BitSet& x, const BitSet& y, BitSet& r)
  215. {
  216.   r.rep =  BitSetop(x.rep, y.rep, r.rep, '|');
  217. }
  218.  
  219. inline void xor(const BitSet& x, const BitSet& y, BitSet& r)
  220. {
  221.   r.rep =  BitSetop(x.rep, y.rep, r.rep, '^');
  222. }
  223.  
  224. inline void diff(const BitSet& x, const BitSet& y, BitSet& r)
  225. {
  226.   r.rep =  BitSetop(x.rep, y.rep, r.rep, '-');
  227. }
  228.  
  229. inline void complement(const BitSet& x, BitSet& r)
  230. {
  231.   r.rep = BitSetcmpl(x.rep, r.rep);
  232. }
  233.  
  234. #if defined(__GNUG__) && !defined(NO_NRV)
  235.  
  236. inline BitSet operator & (const BitSet& x, const BitSet& y) return r
  237. {
  238.   and(x, y, r);
  239. }
  240.  
  241. inline BitSet operator | (const BitSet& x, const BitSet& y) return r
  242. {
  243.   or(x, y, r);
  244. }
  245.  
  246. inline BitSet operator ^ (const BitSet& x, const BitSet& y) return r
  247. {
  248.   xor(x, y, r);
  249. }
  250.  
  251. inline BitSet operator - (const BitSet& x, const BitSet& y) return r
  252. {
  253.   diff(x, y, r);
  254. }
  255.  
  256. inline BitSet operator ~ (const BitSet& x) return r
  257. {
  258.   ::complement(x, r);
  259. }
  260.  
  261. #else /* NO_NRV */
  262.  
  263. inline BitSet operator & (const BitSet& x, const BitSet& y) 
  264. {
  265.   BitSet r; and(x, y, r); return r;
  266. }
  267.  
  268. inline BitSet operator | (const BitSet& x, const BitSet& y) 
  269. {
  270.   BitSet r; or(x, y, r); return r;
  271. }
  272.  
  273. inline BitSet operator ^ (const BitSet& x, const BitSet& y) 
  274. {
  275.   BitSet r; xor(x, y, r); return r;
  276. }
  277.  
  278. inline BitSet operator - (const BitSet& x, const BitSet& y) 
  279. {
  280.   BitSet r; diff(x, y, r); return r;
  281. }
  282.  
  283. inline BitSet operator ~ (const BitSet& x) 
  284. {
  285.   BitSet r; ::complement(x, r); return r;
  286. }
  287.  
  288. #endif
  289.  
  290. inline void BitSet::operator &= (const BitSet& y)
  291. {
  292.   and(*this, y, *this);
  293. }
  294.  
  295. inline void BitSet::operator |= (const BitSet& y)
  296. {
  297.   or(*this, y, *this);
  298. }
  299.  
  300. inline void BitSet::operator ^= (const BitSet& y)
  301. {
  302.   xor(*this, y, *this);
  303. }
  304.  
  305. inline void BitSet::operator -= (const BitSet& y)
  306. {
  307.   diff(*this, y, *this);
  308. }
  309.  
  310.  
  311. inline void BitSet::complement()
  312. {
  313.   ::complement(*this, *this);
  314. }
  315.  
  316. inline int BitSet::virtual_bit() const
  317. {
  318.   return rep->virt;
  319. }
  320.  
  321. inline int BitSet::first(int b) const
  322. {
  323.   return next(-1, b);
  324. }
  325.  
  326. inline int BitSet::test(int p) const
  327. {
  328.   if (p < 0) error("Illegal bit index");
  329.   int index = BitSet_index(p);
  330.   return (index >= rep->len)? rep->virt : 
  331.          ((rep->s[index] & (1 << BitSet_pos(p))) != 0);
  332. }
  333.  
  334.  
  335. inline void BitSet::clear()
  336. {
  337.   if (rep->len > 0) bzero(rep->s, rep->sz * sizeof(short));
  338.   rep->len = rep->virt = 0;
  339. }
  340.  
  341. inline void BitSet::set()
  342. {
  343.   rep = BitSetalloc(rep, 0, 0, 1, 0);
  344. }
  345.  
  346. inline BitSetBit::BitSetBit(const BitSetBit& b) :src(b.src), pos(b.pos) {}
  347.  
  348. inline BitSetBit::BitSetBit(BitSet* v, int p)
  349. {
  350.   src = v;  pos = p;
  351. }
  352.  
  353. inline BitSetBit::~BitSetBit() {}
  354.  
  355. inline BitSetBit::operator int()
  356. {
  357.   return src->test(pos);
  358. }
  359.  
  360. inline int BitSetBit::operator = (int b)
  361. {
  362.   if (b) src->set(pos); else src->clear(pos); return b;
  363. }
  364.  
  365. inline int BitSetBit::operator == (int b)
  366. {
  367.   return src->test(pos) == b;
  368. }
  369.  
  370. inline int BitSetBit::operator != (int b)
  371. {
  372.   return src->test(pos) != b;
  373. }
  374.  
  375. inline BitSetBit BitSet::operator [] (int i)
  376. {
  377.   if (i < 0) error("illegal bit index");
  378.   return BitSetBit(this, i);
  379. }
  380.  
  381.  
  382.  
  383. #endif
  384. #endif
  385.