/* Web Polygraph       http://www.web-polygraph.org/
 * (C) 2003-2006 The Measurement Factory
 * Licensed under the Apache License, Version 2.0 */

#ifndef POLYGRAPH__XSTD_BITMASK_H
#define POLYGRAPH__XSTD_BITMASK_H

#include "xstd/Size.h"

// fixed size bit mask
class BitMask {
	protected:
		typedef int Bin;

	protected:
		static int BinOff(int idx) { return idx / sizeof(Bin); }
		static int BitOff(int idx) { return idx % sizeof(Bin); }
		static int BitVal(int idx) { return 1 << BitOff(idx); }
		static int BinCount(int bitCount) { return BinOff(bitCount) + 1; }

	public:
		BitMask(int aCapacity = 0): theBins(0), theCapacity(0) { resize(aCapacity); }
		~BitMask() { delete[] theBins; }

		int capacity() const { return theCapacity; }
		Size size() const;

		bool isSet(int bit) const { return (bin(bit) & BitVal(bit)) != 0; }
		bool operator [](int bit) const { return isSet(bit); }

		void beSet(int bit) { bin(bit) |= BitVal(bit); }
		void beClear(int bit) { bin(bit) &= ~BitVal(bit); }

		// ignores old content
		void resize(int aCapacity);
		// preserves old content, assumes an [x,x+capacity-1] range was mapped
		void grow(int aCapacity, int x);

		void clear();

	protected:
		Bin &bin(int bit) { return theBins[BinOff(bit)]; }
		const Bin &bin(int bit) const { return theBins[BinOff(bit)]; }

	private:
		void takeOver(BitMask &from);

	protected:
		Bin *theBins;
		int theCapacity;  // in bits!
};

#endif


syntax highlighted by Code2HTML, v. 0.9.1