summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llinitparam.cpp2
-rw-r--r--indra/llcommon/llinitparam.h64
-rw-r--r--indra/llcommon/llpredicate.cpp22
-rw-r--r--indra/llcommon/llpredicate.h199
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