Не уверен насчет моей логики битовой маски
У меня есть объекты, которые я хочу отображать посетителю только на основании разных критериев. Объект имеет битовую маску, и я определил следующие условия:
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 не нужно удалять.