#include <iostream>
#include <algorithm>
#include <deque>
#include <stdarg.h>
template<typename T> class UFlag {

public:
	UFlag(){}
	UFlag(int n, ...){
		va_list args;
		va_start(args, n);
		for(int i = 0; i < n; ++i){
			T t = va_arg(args, T);
			list.push_back(t);
		}
		va_end(args);
	}

    explicit operator bool() const {
        return list.size();
    }

	inline UFlag<T>& operator |(T b){
	    list.push_back(b);
		return *this;
	}
	
	inline UFlag<T>& operator |(UFlag<T> b){
	    for(const T& t : b.list)
	        list.push_back(t);
		return *this;
	}
	
	inline UFlag<T>& operator &(T n){
	    UFlag<T> uf; uf | n;
	    return *this & uf;
	}
	
	inline UFlag<T>& operator &(UFlag<T> b){
		//if(list.size() == 0) return *(&b);
		if(b.list.size() == 0) return *this;
	    UFlag<T> *uf = new UFlag<T>();
	    for(T& t : b.list){
	        if(std::find(list.begin(), list.end(), t) != list.end()) uf->list.push_back(t);
	    }
	    return *uf;
	}
	
	void cout(){
	    std::cout << "cout: ";
	    for(const auto& i : list)
	        std::cout << i << ", ";
	    std::cout << std::endl;
	}

private:
	std::deque<T> list;
};


using namespace std;

int main()
{
    cout << "Starting" << endl;
   UFlag<int> uf;
   (uf | 10) | 5;
   uf.cout();
   
   UFlag<int> uf2;
   uf2 | 55 | 66;
   uf2.cout();
   
   
   uf | uf2;
   uf.cout();
   
   UFlag<int> uf3;
   uf3 | 0 | 7 | -5;
   uf3.cout();
   
   UFlag<int> uf4 = uf & uf3;
   uf4.cout();
   
   if(uf & uf3) std::cout << "Contains" << std::endl;
   uf3 | 66 | 10;
   if(uf & uf3) std::cout << "2: Contains" << std::endl;
   
   UFlag<int> uf5(3, 5, 6, 90);
   uf5.cout();
   
   UFlag<int> uf6;
   UFlag<int> uf7(3, 4, 5, 6);
   (uf6 & uf7).cout();
   (uf7 & uf6).cout();
   return 0;
}

