08 - bit

I can imagine only 2 kinds of types for which overloading bit operators makes sense:

  • bit mask types

  • types from an EDSL library

For bit mask types, overloads follow arithmetic overloads conventions, with the difference that compound versions are non-member (enumerations can not have member functions).

Below canonical implementation for a filesystem permissions bit mask enumeration (from user-defined types / enum flags):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
perms& operator&=(perms& lhs, perms rhs)
{
	return lhs = static_cast<perms>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
}

perms& operator|=(perms& lhs, perms rhs)
{
	return lhs = static_cast<perms>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
}

perms& operator^=(perms& lhs, perms rhs)
{
	return lhs = static_cast<perms>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs));
}

perms operator&(perms lhs, perms rhs) { return lhs &= rhs; }
perms operator|(perms lhs, perms rhs) { return lhs |= rhs; }
perms operator^(perms lhs, perms rhs) { return lhs ^= rhs; }

perms operator~(perms rhs)
{
	// note that this will also flip bits which do not represent any option
	return static_cast<perms>(~static_cast<unsigned>(rhs));
}