#include <iostream>
#include <type_traits>
namespace bitfields
{
template <typename Bitfield>
constexpr Bitfield operator& (Bitfield x, Bitfield y) noexcept(true)
{
typedef typename std::underlying_type<Bitfield>::type type;
return Bitfield(type(x) & type(y));
}
template <typename Bitfield>
Bitfield& operator&= (Bitfield& x, Bitfield y) noexcept(true)
{
typedef typename std::underlying_type<Bitfield>::type type;
return x = x & y;
}
template <typename Bitfield>
constexpr Bitfield operator| (Bitfield x, Bitfield y) noexcept(true)
{
typedef typename std::underlying_type<Bitfield>::type type;
return Bitfield(type(x) | type(y));
}
template <typename Bitfield>
Bitfield& operator|= (Bitfield& x, Bitfield y) noexcept(true)
{
typedef typename std::underlying_type<Bitfield>::type type;
return x = x | y;
}
template <typename Bitfield>
constexpr Bitfield operator^ (Bitfield x, Bitfield y) noexcept(true)
{
typedef typename std::underlying_type<Bitfield>::type type;
return Bitfield(type(x) ^ type(y));
}
template <typename Bitfield>
Bitfield& operator^= (Bitfield& x, Bitfield y) noexcept(true)
{
typedef typename std::underlying_type<Bitfield>::type type;
return x = x ^ y;
}
template <typename Bitfield>
constexpr Bitfield operator~ (Bitfield x) noexcept(true)
{
typedef typename std::underlying_type<Bitfield>::type type;
return Bitfield(~type(x));
}
template <typename Bitfield>
constexpr bool operator! (Bitfield x) noexcept(true)
{
return !typename std::underlying_type<Bitfield>::type(x);
}
template <typename Bitfield>
constexpr bool test(Bitfield x) noexcept(true)
{
return !!x;
}
}
namespace bitfields
{
enum class bitfield: unsigned char
{
a = 0x01,
b = 0x02,
c = 0x04
};
}
typedef bitfields::bitfield bitfield;
int main()
{
bitfield v = bitfield::a | bitfield::b;
v &= bitfield::a;
switch (v) {
case bitfield::a | bitfield::b:
case bitfield::a & bitfield::b:
case bitfield::a ^ bitfield::c:
case ~bitfield::a:
default:
break;
};
if (test(v & bitfield::a)) {
std::cout << "a ";
}
if (test(v & bitfield::b)) {
std::cout << "b ";
}
if (test(v & bitfield::c)) {
std::cout << "c ";
}
std::cout << '\n';
}