#ifndef GPK_SET_H
# define GPK_SET_H
# ifndef HASH_H
#  include <hash.h>
# endif

template <class X>
class gpk_set : private doublehash<X,unsigned>	{
	unsigned cardinality;
	public:
	gpk_set(int n, int (*fs)(C X&, int));
	virtual ~gpk_set();
	C hashitem<X, unsigned>* set_cardinal(C X& k);
	int count() C	{return cardinality;}
	int size() C {return doublehash<X,unsigned>::size();}
	BOOL rehash(int nn)	{return doublehash<X,unsigned>::rehash(nn);}
	BOOL unset(C X& k)	{return doublehash<X,unsigned>::unset(k);}
	BOOL check(C X& k) C	{ return doublehash<X,unsigned>::check(k);}
	C hashitem<X,unsigned> * getptr(C X& k) C	{return doublehash<X,unsigned>::getptr(k);}
	BOOL r_check(C unsigned& k) C	{return doublehash<X,unsigned>::r_check(k);}
	C X& r_get(C unsigned& k) C	{return doublehash<X,unsigned>::r_get(k);}
	C hashitem<X,unsigned> * r_getptr(C unsigned& k) C	{return doublehash<X,unsigned>::r_getptr(k);}
	BOOL r_unset(C unsigned& v)	{return doublehash<X,unsigned>::r_unset(v);}
	};

template<class X>
class set_iterator	{
	C gpk_set<X> *p;
	unsigned i;
	set_iterator();

	public:
	set_iterator(C gpk_set<X>& a) : p(&a) {reset();}
	operator int() C	{return (int)i;}
	void next()	{i++;}
	void previous()	{i--;}
	BOOL valid() C	{i>=0 && i<count();}
	void reset()	{i = 0;}
	void end()	{i = count()-1;}
	C X& key() C	{r_get(i);}
	C unsigned& value() C	{return (int)i;}
	C hashitem<X,unsigned> *item() C	{r_getptr(i);}
	};

#endif
