A million flags in bool[] is a megabyte; packed into bits it is 128 KB. std::vector<bool> does exactly this — and that is why its operator[] returns not bool& but a special proxy object. Now you write the same thing and find out how a[i] = true works when bit i has no address of its own.
BitSet packs bits into bytes — eight times less memory than bool[]. The catch: operator[] cannot return bool&, a single bit has no address. Implement a proxy object: reading converts it to bool, writing sets the bit. The goal is for a[i] = true to just work.
The proxy needs a pointer to the byte and a mask of the bit inside it. Assignment ORs or ANDs the byte; reading ANDs and compares.
Two members make it behave like a reference: operator=(bool) for writes and operator bool() for reads. For chaining, operator= returns Ref&.
Hit Submit (or ⌘/Ctrl + ↵) — test results will show up here.