Skip to content

Instantly share code, notes, and snippets.

@derofim
Last active September 4, 2016 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derofim/0188769131c62c8aff5e1da5740b3574 to your computer and use it in GitHub Desktop.
Save derofim/0188769131c62c8aff5e1da5740b3574 to your computer and use it in GitHub Desktop.
C++11 bitfields
// Example program
#include <iostream>
#include <string>
template<typename Enum>
struct EnableBitMaskOperators
{
static const bool enable = false;
};
#define ENABLE_BITMASK_OPERATORS(x) \
template<> \
struct EnableBitMaskOperators<x> \
{ \
static const bool enable = true; \
};
template<typename Enum>
typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator &(Enum lhs, Enum rhs)
{
using underlying = typename std::underlying_type<Enum>::type;
return static_cast<Enum> (
static_cast<underlying>(lhs) &
static_cast<underlying>(rhs)
);
}
template<typename Enum>
typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator ^(Enum lhs, Enum rhs)
{
using underlying = typename std::underlying_type<Enum>::type;
return static_cast<Enum> (
static_cast<underlying>(lhs) ^
static_cast<underlying>(rhs)
);
}
template<typename Enum>
typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator ~(Enum rhs)
{
using underlying = typename std::underlying_type<Enum>::type;
return static_cast<Enum> (
~static_cast<underlying>(rhs)
);
}
template<typename Enum>
typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator |(Enum lhs, Enum rhs)
{
using underlying = typename std::underlying_type<Enum>::type;
return static_cast<Enum> (
static_cast<underlying>(lhs) |
static_cast<underlying>(rhs)
);
}
template<typename Enum>
typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type&
operator &=(Enum& lhs, Enum rhs)
{
using underlying = typename std::underlying_type<Enum>::type;
lhs = static_cast<Enum> (
static_cast<underlying>(lhs) &
static_cast<underlying>(rhs)
);
return lhs;
}
template<typename Enum>
typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type&
operator ^=(Enum& lhs, Enum rhs)
{
using underlying = typename std::underlying_type<Enum>::type;
lhs = static_cast<Enum> (
static_cast<underlying>(lhs) ^
static_cast<underlying>(rhs)
);
return lhs;
}
template<typename Enum>
typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum&>::type
operator |=(Enum& lhs, Enum rhs)
{
using underlying = typename std::underlying_type<Enum>::type;
lhs = static_cast<Enum> (
static_cast<underlying>(lhs) |
static_cast<underlying>(rhs)
);
return lhs;
}
enum class Permissions
{
Readable = 0x4,
Writable = 0x2,
Executable = 0x1
};
ENABLE_BITMASK_OPERATORS(Permissions)
int main()
{
Permissions p = Permissions::Readable | Permissions::Writable; // Set default permissions
p |= Permissions::Executable; // Add permission
p &= ~Permissions::Writable; // Remove permission
bool hasReadPermission = static_cast<bool>(p & Permissions::Readable);
bool hasWritePermission = static_cast<bool>(p & Permissions::Writable);
bool hasExecutePermission = static_cast<bool>(p & Permissions::Executable);
if (hasReadPermission) {
std::cout << "Has read permission" << "\n";
}
if (hasWritePermission) {
std::cout << "Has write permission" << "\n";
}
if (hasExecutePermission) {
std::cout << "Has execute permission" << "\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment