// This may look like C code, but it is really -*- C++ -*-

#ifndef _CHARSET_H
#define _CHARSET_H
#ifdef __GNUC__
#pragma interface
#endif

#include <limits.h>
#include <iostream.h>

typedef unsigned long _CharSetWord;
#define _BITS_PER_CS_WORD (CHAR_BIT*sizeof(_CharSetWord))
#define _CHARSETWORDS ((UCHAR_MAX+_BITS_PER_CS_WORD)/_BITS_PER_CS_WORD)

class CharSet {
    inline _CharSetWord& char_to_word(int ch)
	{ return words[((unsigned)ch)/_BITS_PER_CS_WORD]; }
    inline _CharSetWord char_to_word(int ch) const
	{ return words[((unsigned)ch)/_BITS_PER_CS_WORD]; }
    inline int bit_in_word(int ch) const
	{return (unsigned)ch % _BITS_PER_CS_WORD;}
  public: // FIXME
    _CharSetWord words[_CHARSETWORDS];
    int test(int ch) const { if (ch < 0 || ch > UCHAR_MAX) return 0;
			     return 1 & (char_to_word(ch) >> bit_in_word(ch));}

    void clear(); // Empty the charset.
    void clear(int i); // Remove i from the set.
    void set(int i); // Add I to the set.
    void add(char *p, int len); // Add (u_char)p[0] ... (u_char)p[len-1].
    CharSet() { clear(); }
    void put(streambuf *, int can_quote) const;
};

ostream& operator<<(ostream& s, const CharSet&);

#if 1 /* Q */
#include "types.h"

class Charset : public Root, public CharSet {
//    DECLARE_MEMBERS(Charset)
  public:
    Charset() : CharSet() { }
    virtual void printon(ostream &) const;
};
#endif
#endif
