#ifndef ENS32_H_
#define ENS32_H_
#include <iostream>
using namespace std;

struct Ens32
{
	int b;
	
	Ens32 (){b=0;}
	Ens32(int x){b=x;}
    operator int(){return b;}
	friend ostream & operator <<(ostream & f,Ens32 A){return A.put(f);}
	friend istream & operator >>(istream & f,Ens32 &A){return A.get(f);}
	void operator = (const Ens32 & A){b=A.b;}

	void Put1(int i){b |= (1L<<i);}     		// Ajoute i à l'ensemble b.
	void Put0(int i){b &= ~(1L<<i);}     		// Retire i de l'ensemble b.
	void PutX(int i){((b&(1L<<i))!=0)?(b &= ~(1L<<i)):(b |= (1L<<i));}     // inverse le bit i de l'ensemble b.
	void Put(int i, bool v){
		switch (v) {
		case 0 : b &= ~(1L<<i);break;
		case 1 : b |= (1L<<i);break;
		}
	}
	bool In(int i){return (b&(1L<<i))!=0;}     	// return vrai si i appartient à l'ensemble b.
	bool operator[](int i){return (b&(1L<<i))!=0;} 
	
	bool operator<=(Ens32 Y){return !(b&(~Y));}
	bool operator<(Ens32 Y){return !(b&(~Y)) && b!=Y;}
	bool operator>(Ens32 Y){return !(Y&(~b)) && Y!=b;}
	bool operator>=(Ens32 Y){return !(Y&(~b));}
	
	int Next(int r){							// Trouve le plus petit élément >=n appartenant à A.
    	if ((r>31) || ((b & (~0L << r))==0)) return -1; // pas d'élément suivant
    	int v=1L<<r;
    	while ((b&v)==0) {v<<=1;r++;}
    	return r;
	};            								
	void Rand(){b=rand();b<<=9;b+=rand();b<<=9;b+=rand();} 
	void Rand(int x, int y){
		int v=y-x+1;
		int u=rand();u<<=9;u+=rand();u<<=9;u+=rand();u%=v;
		if (u<0) u+=v;
		b=u+x;
	}
	ostream & put(ostream & f); // Affiche l'ensemble A. Ex : {0,1,2,9,15,31}
	istream & get(istream & f); // Lit l'ensemble A.

friend inline int Cmp (const void* a, const void *b){return (*(int*)a < *(int*)b )?-1:((*(int*)a == *(int*)b )?0:1);}

	static void Test(int);
	static void TestPut1();
	static void TestPut0();
	static void TestPutX();
	static void TestPut();
	static void TestComp();
	static void TestIn();
	static void TestNext();
	static void TestRand();
	static void Synopsis();
};

#endif
