Value::compareType() -> Value::equalType()
This commit is contained in:
@@ -284,6 +284,53 @@ bool Value::idStartsWith(const std::string& prefix) const
|
||||
return ID.size()>=prefix.size() && prefix==ID.substr(0u, prefix.size());
|
||||
}
|
||||
|
||||
bool Value::_equal(const impl::FieldDesc* A, const impl::FieldDesc* B)
|
||||
{
|
||||
if(A==B) {
|
||||
return true;
|
||||
|
||||
} else if(!A ^ !B) {
|
||||
return false;
|
||||
|
||||
} else if(!A) { // !A && !B
|
||||
return true;
|
||||
|
||||
} else if(A->size()!=B->size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for(auto i : range(A->size())) {
|
||||
if(A[i].code!=B[i].code)
|
||||
return false;
|
||||
|
||||
if(A[i].code==TypeCode::StructA || A[i].code==TypeCode::UnionA) {
|
||||
if(!_equal(&A[i].members[0], &B[i].members[0]))
|
||||
return false;
|
||||
|
||||
} else if(A[i].code==TypeCode::Struct || A[i].code==TypeCode::Union) {
|
||||
auto it = A[i].mlookup.begin();
|
||||
auto end= A[i].mlookup.end();
|
||||
auto it2= B[i].mlookup.begin();
|
||||
|
||||
for(;it!=end; ++it, ++it2) {
|
||||
if(it->first!=it2->first) {
|
||||
return false; // different field name
|
||||
|
||||
} else if(it->second!=it2->second) {
|
||||
return false; // different field order
|
||||
|
||||
} else if(A[i].code==TypeCode::Union) {
|
||||
if(!_equal(&A[i].members[it->second], &B[i].members[it2->second]))
|
||||
return false;
|
||||
|
||||
} // else if A[i] is Struct, outer loop will reach members
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string &Value::nameOf(const Value& descendant) const
|
||||
{
|
||||
if(!store || !descendant.store)
|
||||
|
||||
+8
-4
@@ -528,10 +528,14 @@ public:
|
||||
//! Test prefix of Type ID string (Struct or Union only)
|
||||
bool idStartsWith(const std::string& prefix) const;
|
||||
|
||||
//! test for instance equality.
|
||||
inline bool compareInst(const Value& o) const { return store==o.store; }
|
||||
// int compareValue(const Value&) const;
|
||||
inline int compareType(const Value& o) const { return desc==o.desc; }
|
||||
private:
|
||||
static
|
||||
bool _equal(const impl::FieldDesc* A, const impl::FieldDesc* B);
|
||||
public:
|
||||
//! Test for instance equality. aka. this==this
|
||||
inline bool equalInst(const Value& o) const { return store==o.store; }
|
||||
//! Test for equality of type only (including field names)
|
||||
inline bool equalType(const Value& o) const { return _equal(desc, o.desc); }
|
||||
|
||||
/** Return our name for a descendant field.
|
||||
* @code
|
||||
|
||||
+8
-5
@@ -29,15 +29,18 @@ void testTraverse()
|
||||
|
||||
{
|
||||
auto top2 = top["value<"];
|
||||
testOk1(top.compareType(top2));
|
||||
testOk1(top.compareInst(top2));
|
||||
testOk1(top.equalType(top2));
|
||||
testOk1(top.equalInst(top2));
|
||||
}
|
||||
{
|
||||
auto sevr1 = top["alarm.severity"];
|
||||
auto sevr2 = top["value<alarm.status<severity"];
|
||||
testOk1(sevr1.compareType(sevr2));
|
||||
testOk1(sevr1.compareInst(sevr2));
|
||||
testOk1(sevr1.equalType(sevr2));
|
||||
testOk1(sevr1.equalInst(sevr2));
|
||||
}
|
||||
|
||||
testFalse(top.equalType(top["alarm"]));
|
||||
testFalse(top.equalType(top["value"]));
|
||||
}
|
||||
|
||||
void testAssign()
|
||||
@@ -261,7 +264,7 @@ void testAssignSimilar()
|
||||
|
||||
MAIN(testdata)
|
||||
{
|
||||
testPlan(78);
|
||||
testPlan(80);
|
||||
testSetup();
|
||||
testTraverse();
|
||||
testAssign();
|
||||
|
||||
Reference in New Issue
Block a user