diff options
-rw-r--r-- | indra/llcommon/llinitparam.cpp | 2 | ||||
-rw-r--r-- | indra/llcommon/llinitparam.h | 64 | ||||
-rw-r--r-- | indra/llcommon/llpredicate.cpp | 22 | ||||
-rw-r--r-- | indra/llcommon/llpredicate.h | 199 |
4 files changed, 166 insertions, 121 deletions
diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp index 69f97e87c4..c66659a696 100644 --- a/indra/llcommon/llinitparam.cpp +++ b/indra/llcommon/llinitparam.cpp @@ -190,7 +190,7 @@ namespace LLInitParam bool serialized = false; if (!isProvided()) { - if ((~predicate_rule_t(PROVIDED) && predicate_rule).isTriviallyFalse()) + if (predicate_rule_t(~ll_predicate(PROVIDED) && predicate_rule).isTriviallyFalse()) { return false; } diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 9530e562f6..b52ac809e0 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -545,7 +545,7 @@ namespace LLInitParam } bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name); - bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule = predicate_rule_t(), const BaseBlock* diff_block = NULL) const; + bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule = predicate_rule_t(ll_predicate(PROVIDED) && ll_predicate(NON_DEFAULT)), const BaseBlock* diff_block = NULL) const; bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const; virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } @@ -912,17 +912,17 @@ namespace LLInitParam const self_t* diff_typed_param = static_cast<const self_t*>(diff_param); LLPredicate::Value<ESerializePredicates> predicate; - if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue())) + predicate.set(NON_DEFAULT, !diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue())); + + if (typed_param.isValid()) { - predicate.add(NON_DEFAULT); + predicate.set(VALID, true); + predicate.set(PROVIDED, typed_param.anyProvided()); } - if (typed_param.isValid()) + else { - predicate.add(VALID); - if (typed_param.anyProvided()) - { - predicate.add(PROVIDED); - } + predicate.set(VALID, false); + predicate.set(PROVIDED, false); } if (!predicate_rule.check(predicate)) return false; @@ -1076,11 +1076,13 @@ namespace LLInitParam if (typed_param.isValid()) { - predicate.add(VALID); - if (typed_param.anyProvided()) - { - predicate.add(PROVIDED); - } + predicate.set(VALID, true); + predicate.set(PROVIDED, typed_param.anyProvided()); + } + else + { + predicate.set(VALID, false); + predicate.set(PROVIDED, false); } if (!predicate_rule.check(predicate)) return false; @@ -1270,19 +1272,18 @@ namespace LLInitParam LLPredicate::Value<ESerializePredicates> predicate; - if (typed_param.mMinCount > 0) - { - predicate.add(REQUIRED); - } + predicate.set(REQUIRED, typed_param.mMinCount > 0); if (typed_param.isValid()) { - predicate.add(VALID); - if (typed_param.anyProvided()) - { - predicate.add(PROVIDED); - } + predicate.set(VALID, true); + predicate.set(PROVIDED, typed_param.anyProvided()); } + else + { + predicate.set(VALID, false); + predicate.set(PROVIDED, false); + } if (!predicate_rule.check(predicate)) return false; @@ -1531,19 +1532,18 @@ namespace LLInitParam LLPredicate::Value<ESerializePredicates> predicate; - if (typed_param.mMinCount > 0) - { - predicate.add(REQUIRED); - } + predicate.set(REQUIRED, typed_param.mMinCount > 0); if (typed_param.isValid()) { - predicate.add(VALID); - if (typed_param.anyProvided()) - { - predicate.add(PROVIDED); - } + predicate.set(VALID, true); + predicate.set(PROVIDED, typed_param.anyProvided()); } + else + { + predicate.set(VALID, false); + predicate.set(PROVIDED, false); + } if (!predicate_rule.check(predicate)) return false; diff --git a/indra/llcommon/llpredicate.cpp b/indra/llcommon/llpredicate.cpp index e3410ef3f6..1278948e24 100644 --- a/indra/llcommon/llpredicate.cpp +++ b/indra/llcommon/llpredicate.cpp @@ -29,19 +29,13 @@ namespace LLPredicate { - EmptyRule make_rule() { return EmptyRule(); } - - S32 predicateFlagsFromValue(S32 value) + const U32 cPredicateFlagsFromEnum[5] = { - llassert(value < 5); - static const S32 predicates[5] = - { - 0xAAAAaaaa, // 10101010101010101010101010101010 - 0xCCCCcccc, // 11001100110011001100110011001100 - 0xF0F0F0F0, // 11110000111100001111000011110000 - 0xFF00FF00, // 11111111000000001111111100000000 - 0xFFFF0000 // 11111111111111110000000000000000 - }; - return predicates[value]; - } + 0xAAAAaaaa, // 10101010101010101010101010101010 + 0xCCCCcccc, // 11001100110011001100110011001100 + 0xF0F0F0F0, // 11110000111100001111000011110000 + 0xFF00FF00, // 11111111000000001111111100000000 + 0xFFFF0000 // 11111111111111110000000000000000 + }; } + diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h index 5fd1d30295..3f1bf1c8e6 100644 --- a/indra/llcommon/llpredicate.h +++ b/indra/llcommon/llpredicate.h @@ -33,129 +33,180 @@ namespace LLPredicate { template<typename ENUM> class Rule; - S32 predicateFlagsFromValue(S32 value); + extern const U32 cPredicateFlagsFromEnum[5]; template<typename ENUM> - struct Value + class Literal { friend Rule<ENUM>; + public: - Value(ENUM e) - : mPredicateCombinationFlags(0xFFFFffff) + typedef U32 predicate_flag_t; + static const S32 cMaxEnum = 5; + + Literal(ENUM e) + : mPredicateFlags(cPredicateFlagsFromEnum[e]) { - add(e); + llassert(0 <= e && e < cMaxEnum); } - Value() - : mPredicateCombinationFlags(0xFFFFffff) + Literal() + : mPredicateFlags(0xFFFFffff) {} - void add(ENUM predicate) + Literal operator~() { - llassert(predicate < 5); - S32 predicate_shift = 0x1 << (S32)predicate; - S32 flag_mask = predicateFlagsFromValue(predicate); - S32 flags_to_modify = mPredicateCombinationFlags & ~flag_mask; - // clear flags containing predicate to be removed - mPredicateCombinationFlags &= ~flag_mask; - // shift flags, in effect removing predicate - flags_to_modify <<= predicate_shift; - // put modified flags back - mPredicateCombinationFlags |= flags_to_modify; + Literal new_rule; + new_rule.mPredicateFlags = ~mPredicateFlags; + return new_rule; } - void remove(ENUM predicate) + Literal operator &&(const Literal& other) { - llassert(predicate < 5); - S32 predicate_shift = 0x1 << (S32)predicate; - S32 flag_mask = predicateFlagsFromValue(predicate); - S32 flags_to_modify = mPredicateCombinationFlags & flag_mask; - // clear flags containing predicate to be removed - mPredicateCombinationFlags &= ~flag_mask; - // shift flags, in effect removing predicate - flags_to_modify >>= predicate_shift; - // put modified flags back - mPredicateCombinationFlags |= flags_to_modify; + Literal new_rule; + new_rule.mPredicateFlags = mPredicateFlags & other.mPredicateFlags; + return new_rule; } - void unknown(ENUM predicate) + Literal operator ||(const Literal& other) { - add(predicate); - S32 flags_with_predicate = mPredicateCombinationFlags; - remove(predicate); - // unknown is result of adding and removing predicate at the same time! - mPredicateCombinationFlags |= flags_with_predicate; + Literal new_rule; + new_rule.mPredicateFlags = mPredicateFlags | other.mPredicateFlags; + return new_rule; } - bool has(ENUM predicate) + void set(ENUM e, bool value) { - S32 flag_mask = predicateFlagsFromValue(predicate); - return (mPredicateCombinationFlags & flag_mask) != 0; + llassert(0 <= e && e < cMaxEnum); + modifyPredicate(0x1 << (S32)e, cPredicateFlagsFromEnum[e], value); + } + + void set(const Literal& other, bool value) + { + U32 predicate_flags = other.mPredicateFlags; + while(predicate_flags) + { + U32 next_flags = clearLSB(predicate_flags); + lsb_flag = predicate_flags ^ next_flags; + U32 mask = 0; + for (S32 i = 0; i < cMaxEnum; i++) + { + if (cPredicateFlagsFromEnum[i] & lsb_flag) + { + mask |= cPredicateFlagsFromEnum[i]; + } + } + + modifyPredicate(lsb_flag, mask, value); + + predicate_flags = next_flags; + } + } + + void forget(ENUM e) + { + set(e, true); + U32 flags_with_predicate = mPredicateFlags; + set(e, false); + // ambiguous value is result of adding and removing predicate at the same time! + mPredicateFlags |= flags_with_predicate; + } + + void forget(const Literal& literal) + { + set(literal, true); + U32 flags_with_predicate = mPredicateFlags; + set(literal, false); + // ambiguous value is result of adding and removing predicate at the same time! + mPredicateFlags |= flags_with_predicate; } private: - S32 mPredicateCombinationFlags; + + predicate_flag_t clearLSB(predicate_flag_t value) + { + return value & (value - 1); + } + + void modifyPredicate(predicate_flag_t predicate_flag, predicate_flag_t mask, bool value) + { + llassert(clearLSB(predicate_flag) == 0); + predicate_flag_t flags_to_modify; + + if (value) + { + flags_to_modify = (mPredicateFlags & ~mask); + // clear flags not containing predicate to be added + mPredicateFlags &= mask; + // shift flags, in effect adding predicate + flags_to_modify *= predicate_flag; + } + else + { + flags_to_modify = mPredicateFlags & mask; + // clear flags containing predicate to be removed + mPredicateFlags &= ~mask; + // shift flags, in effect removing predicate + flags_to_modify /= predicate_flag; + } + // put modified flags back + mPredicateFlags |= flags_to_modify; + } + + predicate_flag_t mPredicateFlags; }; - struct EmptyRule {}; + template<typename ENUM> + struct Value + : public Literal<ENUM> + { + public: + Value(ENUM e) + : Literal(e) + {} + + Value() + {} + }; template<typename ENUM> class Rule + : public Literal<ENUM> { public: Rule(ENUM value) - : mPredicateRequirements(predicateFlagsFromValue(value)) + : Literal(value) {} - Rule() - : mPredicateRequirements(0x1) + Rule(const Literal other) + : Literal(other) {} - Rule operator~() - { - Rule new_rule; - new_rule.mPredicateRequirements = ~mPredicateRequirements; - return new_rule; - } - - Rule operator &&(const Rule& other) - { - Rule new_rule; - new_rule.mPredicateRequirements = mPredicateRequirements & other.mPredicateRequirements; - return new_rule; - } - - Rule operator ||(const Rule& other) - { - Rule new_rule; - new_rule.mPredicateRequirements = mPredicateRequirements | other.mPredicateRequirements; - return new_rule; - } + Rule() + {} bool check(const Value<ENUM>& value) const { - return ((value.mPredicateCombinationFlags | 0x1) & mPredicateRequirements) != 0; + return (value.mPredicateFlags & mPredicateFlags) != 0; } bool isTriviallyTrue() const { - return mPredicateRequirements & 0x1; + return mPredicateFlags == 0xFFFFffff; } bool isTriviallyFalse() const { - return mPredicateRequirements == 0; + return mPredicateFlags == 0; } - - private: - S32 mPredicateRequirements; }; +} - template<typename ENUM> - Rule<ENUM> make_rule(ENUM e) { return Rule<ENUM>(e);} +template<typename ENUM> +LLPredicate::Literal<ENUM> ll_predicate(ENUM e) +{ + return LLPredicate::Literal<ENUM>(e); +} - // return generic empty rule class to avoid requiring template argument to create an empty rule - EmptyRule make_rule(); -} #endif // LL_LLPREDICATE_H |