A modern C++ library for type-safe flag operations on enum types.
- Type-safe flag operations: Perform bitwise operations on enum types without losing type safety
- Modern C++ support: Leverages C++20 concepts and features when available
- Minimal overhead: Zero-cost abstractions with compile-time optimizations
- Comprehensive API: Complete set of flag manipulation functions and operators
To enable flag operations for an enum type, add a declaration:
enum class MyFlags {
None = 0,
Flag1 = 1 << 0,
Flag2 = 1 << 1,
Flag3 = 1 << 2
};
// Enable flag operations for MyFlags
enum_flags::enable_flag_ops flag_enable(MyFlags);#include "enum_flags.hpp"
enum class Permissions {
None = 0,
Read = 1 << 0,
Write = 1 << 1,
Execute = 1 << 2
};
enum_flags::enable_flag_ops flag_enable(Permissions);
int main() {
// Combine flags using bitwise OR
auto perms = Permissions::Read | Permissions::Write;
// Test if a flag is set
bool has_read = enum_flags::test(perms, Permissions::Read);
// Set a flag
perms = enum_flags::set_flag(perms, Permissions::Execute);
// Clear a flag
perms = enum_flags::clear_flag(perms, Permissions::Write);
// Toggle a flag
perms = enum_flags::toggle_flag(perms, Permissions::Read);
return 0;
}set_flag(value, flag, on = true)- Set or clear a flagclear_flag(value, flag)- Clear a flagtoggle_flag(value, flag)- Toggle a flagset_assign(value, flag, on = true)- Assignment version of set_flagclear_assign(value, flag)- Assignment version of clear_flagtoggle_assign(value, flag)- Assignment version of toggle_flag
any(value)- Check if any flags are setnone(value)- Check if no flags are settest(value, mask)- Check if any flags in mask are setall(value, mask)- Check if all flags in mask are setcount(value)- Count the number of set flags
When flag operations are enabled for an enum type, the following operators are automatically available:
operator|- Bitwise OR (combine flags)operator&- Bitwise AND (intersection)operator^- Bitwise XOR (difference)operator~- Bitwise NOT (complement)operator|=- Compound OR assignmentoperator&=- Compound AND assignmentoperator^=- Compound XOR assignment
- C++17 or later
- Optional C++20 support for enhanced features:
- Concepts for better type checking
std::popcountfor optimized flag counting
Simply copy enum_flags.hpp to your project and include it:
#include "enum_flags.hpp"This library follows several key principles:
- Type Safety: All operations maintain enum type safety and prevent accidental mixing of different enum types
- Zero Cost: Operations are optimized away at compile time when possible
- Explicit Opt-in: Flag operations must be explicitly enabled for each enum type
- Modern C++: Takes advantage of modern C++ features while maintaining backward compatibility
enum class FileMode {
None = 0,
Read = 1 << 0,
Write = 1 << 1,
Execute = 1 << 2,
Append = 1 << 3
};
enum_flags::enable_flag_ops flag_enable(FileMode);
void set_file_mode(FileMode& mode, FileMode flags) {
mode |= flags;
}
bool has_permission(FileMode mode, FileMode permission) {
return enum_flags::test(mode, permission);
}enum class WidgetState {
None = 0,
Enabled = 1 << 0,
Visible = 1 << 1,
Focused = 1 << 2,
Hovered = 1 << 3
};
enum_flags::enable_flag_ops flag_enable(WidgetState);
class Widget {
WidgetState state_ = WidgetState::None;
public:
void set_enabled(bool enabled) {
enum_flags::set_assign(state_, WidgetState::Enabled, enabled);
}
bool is_enabled() const {
return enum_flags::test(state_, WidgetState::Enabled);
}
void set_visible(bool visible) {
enum_flags::set_assign(state_, WidgetState::Visible, visible);
}
bool is_visible() const {
return enum_flags::test(state_, WidgetState::Visible);
}
};This project is licensed under the MIT License - see the LICENSE file for details.