Не уверен насчет моей логики битовой маски

У меня есть объекты, которые я хочу отображать посетителю только на основании разных критериев. Объект имеет битовую маску, и я определил следующие условия:

const FLAG_ALWAYS   = 0; // always show this item
const FLAG_LOGIN    = 1; // only display to logged in users
const FLAG_NOTLOGIN = 2; // only display to users not logged in
const FLAG_OTHER    = 4; // other criteria
const FLAG_NORTH    = 8; // GeoIP
const FLAG_SOUTH    = 16;

Комбинации флагов возможны, конечно, как 1+4+16 или же 2+4,

Элемент может отображаться в 3 условиях для входа в систему, например: вошли в систему, не вошли в систему, или оба. Поэтому мне нужно FLAG_NOTLOGIN,

Я смущен FLAG_ALWAYS... должно быть 0или он должен охватывать все другие флаги, такие как 4095?

Или я должен удалить FLAG_NOTLOGIN?

2 ответа

Решение

Ответ зависит от того, как вы сочетаете критерии. Есть два самых простых случая.

Любое совпадение, ИЛИ комбинация. любой установленный вами флаг будет добавлять совпадения, больше флажков - больше совпадений.

В этом случае сброс всех флагов (0x0000) никогда не будет совпадать. Это означает, что критерии не выполнены.

Все установленные флаги (0xFFFF) вызовут большинство совпадений. Если у вас есть дополнительные критерии (один из них установлен), критерии будут совпадать всегда.

Матч реализован так: 0!=(filter & criteria)где filter набор критериев для фильтрации и criteria установлен один и тот же флаг установлен на нескольких условиях.

Все совпадения и комбинации. любой установленный вами флаг отфильтровывает некоторые совпадения, больше флажков - меньше совпадений.

В этом случае все флаги сброса будут совпадать всегда.

Все установленные флаги будут вызывать наименьшее количество совпадений. Если у вас есть взаимоисключающие критерии (один набор, тогда другие сбрасываются), когда все не приведут к совпадению.

Например ваши флаги: FLAG_LOGIN, FLAG_NOLOGIN, Пользователь может быть либо логином, либо нет, поэтому оба критерия никогда не будут выполнены, и FLAG_LOGIN+FLAG_NOLOGIN никогда не совпадет, но 0 будет соответствовать в любом случае, так как ни один из критериев не установлен.

Сопоставление осуществляется по следующей формуле: 0==(all_flags & ~filter & ~criteria), Вот filter а также criteria такие же, как указано выше и all_flags набор всех используемых флагов, чтобы исключить неиспользуемые биты в сравнении. (примечание, выражение criteria == (filter & criteria) кажется более очевидным, но неправильным, потому что это не приведет к совпадению, если в критериях не установлены флаги).

Если ваш флаг 1 | 4 и объект имеет 1 | 8тогда первый случай будет совпадать (потому что 1 критерии соблюдены и одного достаточно) и второй случай не будет совпадать (4 критерий не соответствует, но вам нужны оба 1 а также 4).

FLAG_ALWAYS должна быть комбинацией всех других флагов и не должна быть нулевой. FLAG_NOTLOGIN не нужно удалять.

Другие вопросы по тегам