#include <iostream>
using namespace std;

template<typename T>
struct bool_context {
	friend T operator&&(T const & lhs, bool rhs) {
		return lhs && T(rhs);
	}
	friend T operator&&(bool lhs, T const & rhs) {
		return T(lhs) && rhs;
	}
	friend T operator||(T const & lhs, bool rhs) {
		return lhs || T(rhs);
	}
	friend T operator||(bool lhs, T const & rhs) {
		return T(lhs) || rhs;
	}
};

struct my_bool : bool_context<my_bool> {
	bool value;
	my_bool(bool v) : value(v) {}
	explicit operator bool() { return value; };
	friend my_bool operator&&(my_bool const & lhs, my_bool const & rhs) {
		cout << "my_bool::operator&&" << endl;
		return lhs.value && rhs.value;
	}
	friend my_bool operator||(my_bool const & lhs, my_bool const & rhs) {
		cout << "my_bool::operator||" << endl;
		return lhs.value || rhs.value;
	}
};


int main(int, char**) {
	my_bool a = true;
	bool b = false;
	cout << "a && b => "; a && b;
	cout << "b && a => "; b && a;
	cout << "a && a => "; a && a;
	cout << "b && b => "; b && b; cout << endl;
	cout << "a || b => "; a || b;
	cout << "b || a => "; b || a;
	cout << "a || a => "; a || a;
	cout << "b || b => "; b || b; cout << endl;
	return 0;
}