#include <iostream>
using namespace std;

struct Default_t{} Default;
struct Toggle_t{} Toggle;

struct FlagSet{
	uint m_set;
	uint m_reset;
	
	constexpr FlagSet operator|(const FlagSet other) const{
		return {
			~m_reset & other.m_set & ~other.m_reset |
			~m_set & other.m_set & other.m_reset |
			m_set & ~other.m_set,
			m_reset & ~other.m_reset |
			~m_set & ~other.m_set & other.m_reset|
			~m_reset & other.m_set & other.m_reset};
	}
	
	constexpr FlagSet& operator|=(const FlagSet other){
		*this = *this|other;
		return *this;
	}
};

struct Flag{
	const uint m_bit;
	
	constexpr FlagSet operator= (bool val) const{
		return {(uint)val<<m_bit,(!(uint)val)<<m_bit};
	}
	
	constexpr FlagSet operator= (Default_t) const{
		return {0u,0u};
	}
	
	constexpr FlagSet operator= (Toggle_t) const {
		return {1u<<m_bit,1u<<m_bit};
	}
	
	constexpr uint operator& (FlagSet i) const{
		return i.m_set & (1u<<m_bit);
	}
	
	constexpr operator FlagSet() const{
		return {1u<<m_bit,0u}; //= set
	}
	
	constexpr FlagSet operator|(const Flag other) const{
		return (FlagSet)*this|(FlagSet)other;
	}
	constexpr FlagSet operator|(const FlagSet other) const{
		return (FlagSet)*this|other;
	}
};

constexpr uint operator& (FlagSet i, Flag f){
	return f & i;
}


constexpr Flag Flag1{0};
constexpr Flag Flag2{1};
constexpr Flag Flag3{2};

constexpr auto NoFlag1 = (Flag1=false);


void foo(FlagSet f={0,0}){
	f |= Flag1|Flag2;
	cout << ((f & Flag1)?"1":"0");
	cout << ((f & Flag2)?"2":"0");
	cout << ((f & Flag3)?"3":"0");
	cout << endl;
}

int main() {
	
	foo();
	foo(Flag3);
	foo(Flag3|(Flag2=false));
	foo(Flag3|NoFlag1);
	foo((Flag1=Toggle)|(Flag2=Toggle)|(Flag3=Toggle));
	
	return 0;
}