C/C++ Ready | Программирование
14.3K subscribers
1.36K photos
87 videos
668 links
Авторский канал по разработке на C и C++.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!

Автор: @energy_c

РКН: https://clck.ru/3QREHc

Реклама на бирже: https://telega.in/c/cpp_ready
Download Telegram
Собираем типобезопасные флаги через enum class!

Иногда нужно хранить набор прав или режимов: чтение, запись, выполнение, логирование, debug-режимы. Часто для этого используют обычные int-флаги, но с ними легко случайно смешать разные значения.

Начнём с enum class:
enum class Permission : unsigned {
Read = 1 << 0,
Write = 1 << 1,
Exec = 1 << 2
};


Сам по себе enum class не умеет складываться через |, поэтому добавим оператор:
Permission operator|(Permission a, Permission b) {
return static_cast<Permission>(
static_cast<unsigned>(a) | static_cast<unsigned>(b)
);
}


Теперь можно собрать набор прав:
auto user = Permission::Read | Permission::Write;


Чтобы проверять наличие флага, сделаем маленькую функцию:
bool has(Permission value, Permission flag) {
return (
static_cast<unsigned>(value) &
static_cast<unsigned>(flag)
) != 0;
}


Использование получается читаемым:
if (has(user, Permission::Write)) {
std::cout << "Можно изменять данные\n";
}


Можно добавить и удаление флага:
Permission remove(Permission value, Permission flag) {
return static_cast<Permission>(
static_cast<unsigned>(value) & ~static_cast<unsigned>(flag)
);
}


Например, забрать право записи:
user = remove(user, Permission::Write);


Такой подход удобен для прав доступа, настроек движка, режимов логирования, feature flags и любых случаев, где несколько булевых значений логически относятся к одному набору.

📣 C++ Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍4🔥4