Convert::equals: move to operator==(PVField&,PVField&)

This commit is contained in:
Michael Davidsaver
2013-04-22 16:12:03 -04:00
parent f72c5dba84
commit c1b6d26b8e
3 changed files with 146 additions and 357 deletions

View File

@@ -15,13 +15,6 @@
namespace epics { namespace pvData {
// PVXXX object comparison
bool operator==(PVField& left, PVField& right)
{
return getConvert()->equals(left,right);
}
// Introspection object comparision
/** Field equality conditions:
@@ -101,8 +94,142 @@ bool operator==(const StructureArray& a, const StructureArray& b)
return *(a.getStructure().get())==*(b.getStructure().get());
}
namespace nconvert {
// PVXXX object comparison
} // namespace nconvert
namespace {
// fully typed comparisons
template<typename T>
bool compareScalar(PVScalarValue<T>* left, PVScalarValue<T>* right)
{
return left->get()==right->get();
}
template<typename T>
bool compareArray(PVValueArray<T>* left, PVValueArray<T>* right)
{
return std::equal(left->get(), left->get()+left->getLength(), right->get());
}
// partially typed comparisons
bool compareField(PVScalar* left, PVScalar* right)
{
ScalarType lht = left->getScalar()->getScalarType();
if(lht != right->getScalar()->getScalarType())
return false;
switch(lht) {
#define OP(ENUM, TYPE) case ENUM: return compareScalar(static_cast<PVScalarValue<TYPE>*>(left), static_cast<PVScalarValue<TYPE>*>(right))
OP(pvBoolean, uint8);
OP(pvUByte, uint8);
OP(pvByte, int8);
OP(pvUShort, uint16);
OP(pvShort, int16);
OP(pvUInt, uint32);
OP(pvInt, int32);
OP(pvULong, uint64);
OP(pvLong, int64);
OP(pvFloat, float);
OP(pvDouble, double);
#undef OP
case pvString: {
PVString *a=static_cast<PVString*>(left), *b=static_cast<PVString*>(right);
return a->get()==b->get();
}
}
throw std::logic_error("PVScalar with invalid scalar type!");
}
bool compareField(PVScalarArray* left, PVScalarArray* right)
{
ScalarType lht = left->getScalarArray()->getElementType();
if(lht != right->getScalarArray()->getElementType())
return false;
if(left->getLength()!=right->getLength())
return false;
switch(lht) {
#define OP(ENUM, TYPE) case ENUM: return compareArray(static_cast<PVValueArray<TYPE>*>(left), static_cast<PVValueArray<TYPE>*>(right))
OP(pvBoolean, uint8);
OP(pvUByte, uint8);
OP(pvByte, int8);
OP(pvUShort, uint16);
OP(pvShort, int16);
OP(pvUInt, uint32);
OP(pvInt, int32);
OP(pvULong, uint64);
OP(pvLong, int64);
OP(pvFloat, float);
OP(pvDouble, double);
OP(pvString, String);
#undef OP
}
throw std::logic_error("PVScalarArray with invalid element type!");
}
bool compareField(PVStructure* left, PVStructure* right)
{
if(left->getStructure()!=right->getStructure())
return false;
const PVFieldPtrArray& lf = left->getPVFields();
const PVFieldPtrArray& rf = right->getPVFields();
for(size_t i=0, nfld=left->getNumberFields(); i<nfld; i++) {
if(*lf[i]!=*rf[i])
return false;
}
return true;
}
bool compareField(PVStructureArray* left, PVStructureArray* right)
{
if(left->getLength()!=right->getLength())
return false;
StructureConstPtr ls = left->getStructureArray()->getStructure();
if(*ls!=*right->getStructureArray()->getStructure())
return false;
const PVStructureArray::pointer ld=left->get(), rd=right->get();
for(size_t i=0, ilen=left->getLength(); i<ilen; i++)
{
const PVFieldPtrArray& lf = ld[i]->getPVFields();
const PVFieldPtrArray& rf = rd[i]->getPVFields();
for(size_t k=0, klen=ls->getNumberFields(); k<klen; k++)
{
if(*lf[i]!=*rf[i])
return false;
}
}
return true;
}
} // end namespace
// untyped comparison
bool operator==(PVField& left, PVField& right)
{
if(&left == &right)
return true;
Type lht = left.getField()->getType();
if(lht != right.getField()->getType())
return false;
switch(lht) {
case scalar: return compareField(static_cast<PVScalar*>(&left), static_cast<PVScalar*>(&right));
case scalarArray: return compareField(static_cast<PVScalarArray*>(&left), static_cast<PVScalarArray*>(&right));
case structure: return compareField(static_cast<PVStructure*>(&left), static_cast<PVStructure*>(&right));
case structureArray: return compareField(static_cast<PVStructureArray*>(&left), static_cast<PVStructureArray*>(&right));
}
throw std::logic_error("PVField with invalid type!");
}
}} // namespace epics::pvData

View File

@@ -330,7 +330,6 @@ void Convert::fromDouble(PVScalarPtr const &pv, double from)
}
static bool convertEquals(PVField *a,PVField *b);
static size_t convertFromByteArray(PVScalarArray * pv, size_t offset,
size_t len,const int8 from[], size_t fromOffset);
static size_t convertToByteArray(PVScalarArray *pv, size_t offset,
@@ -421,16 +420,6 @@ Convert::Convert()
Convert::~Convert(){}
bool Convert::equals(PVFieldPtr const &a,PVFieldPtr const &b)
{
return convertEquals(a.get(),b.get());
}
bool Convert::equals(PVField &a,PVField &b)
{
return convertEquals(&a,&b);
}
void Convert::getString(StringBuilder buf,PVFieldPtr const & pvField,int indentLevel)
{
convertToString(buf,pvField.get(),indentLevel);
@@ -1329,341 +1318,6 @@ void Convert::newLine(StringBuilder buffer, int indentLevel)
newLineImpl(buffer,indentLevel);
}
static bool scalarEquals(PVScalar *a,PVScalar *b)
{
ScalarType ascalarType = a->getScalar()->getScalarType();
ScalarType bscalarType = b->getScalar()->getScalarType();
if(ascalarType!=bscalarType) return false;
switch(ascalarType) {
case pvBoolean: {
PVBoolean *pa = static_cast<PVBoolean *>(a);
PVBoolean *pb = static_cast<PVBoolean *>(b);
bool avalue = pa->get();
bool bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvByte: {
PVByte *pa = static_cast<PVByte *>(a);
PVByte *pb = static_cast<PVByte *>(b);
int8 avalue = pa->get();
int8 bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvShort: {
PVShort *pa = static_cast<PVShort *>(a);
PVShort *pb = static_cast<PVShort *>(b);
int16 avalue = pa->get();
int16 bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvInt: {
PVInt *pa = static_cast<PVInt *>(a);
PVInt *pb = static_cast<PVInt *>(b);
int32 avalue = pa->get();
int32 bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvLong: {
PVLong *pa = static_cast<PVLong *>(a);
PVLong *pb = static_cast<PVLong *>(b);
int64 avalue = pa->get();
int64 bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvUByte: {
PVUByte *pa = static_cast<PVUByte *>(a);
PVUByte *pb = static_cast<PVUByte *>(b);
uint8 avalue = pa->get();
uint8 bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvUShort: {
PVUShort *pa = static_cast<PVUShort *>(a);
PVUShort *pb = static_cast<PVUShort *>(b);
uint16 avalue = pa->get();
uint16 bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvUInt: {
PVUInt *pa = static_cast<PVUInt *>(a);
PVUInt *pb = static_cast<PVUInt *>(b);
uint32 avalue = pa->get();
uint32 bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvULong: {
PVULong *pa = static_cast<PVULong *>(a);
PVULong *pb = static_cast<PVULong *>(b);
uint64 avalue = pa->get();
uint64 bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvFloat: {
PVFloat *pa = static_cast<PVFloat *>(a);
PVFloat *pb = static_cast<PVFloat *>(b);
float avalue = pa->get();
float bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvDouble: {
PVDouble *pa = static_cast<PVDouble *>(a);
PVDouble *pb = static_cast<PVDouble *>(b);
double avalue = pa->get();
double bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
case pvString: {
PVString *pa = static_cast<PVString *>(a);
PVString *pb = static_cast<PVString *>(b);
String avalue = pa->get();
String bvalue = pb->get();
return ((avalue==bvalue) ? true : false);
}
}
String message("should not get here");
throw std::logic_error(message);
}
static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
{
if(a==b) return true;
ScalarType aType = a->getScalarArray()->getElementType();
ScalarType bType = b->getScalarArray()->getElementType();
if(aType!=bType) return false;
if(a->getLength()!=b->getLength()) return false;
size_t length = a->getLength();
switch(aType) {
case pvBoolean: {
PVBooleanArray *aarray = static_cast<PVBooleanArray *>(a);
PVBooleanArray *barray = static_cast<PVBooleanArray *>(b);
BooleanArrayData adata;
BooleanArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
BooleanArray & avalue = adata.data;
BooleanArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvByte: {
PVByteArray *aarray = static_cast<PVByteArray *>(a);
PVByteArray *barray = static_cast<PVByteArray *>(b);
ByteArrayData adata;
ByteArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
ByteArray & avalue = adata.data;
ByteArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvShort: {
PVShortArray *aarray = static_cast<PVShortArray *>(a);
PVShortArray *barray = static_cast<PVShortArray *>(b);
ShortArrayData adata;
ShortArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
ShortArray & avalue = adata.data;
ShortArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvInt: {
PVIntArray *aarray = static_cast<PVIntArray *>(a);
PVIntArray *barray = static_cast<PVIntArray *>(b);
IntArrayData adata;
IntArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
IntArray & avalue = adata.data;
IntArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvLong: {
PVLongArray *aarray = static_cast<PVLongArray *>(a);
PVLongArray *barray = static_cast<PVLongArray *>(b);
LongArrayData adata;
LongArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
LongArray & avalue = adata.data;
LongArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvUByte: {
PVUByteArray *aarray = static_cast<PVUByteArray *>(a);
PVUByteArray *barray = static_cast<PVUByteArray *>(b);
UByteArrayData adata;
UByteArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
UByteArray & avalue = adata.data;
UByteArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvUShort: {
PVUShortArray *aarray = static_cast<PVUShortArray *>(a);
PVUShortArray *barray = static_cast<PVUShortArray *>(b);
UShortArrayData adata;
UShortArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
UShortArray & avalue = adata.data;
UShortArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvUInt: {
PVUIntArray *aarray = static_cast<PVUIntArray *>(a);
PVUIntArray *barray = static_cast<PVUIntArray *>(b);
UIntArrayData adata;
UIntArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
UIntArray & avalue = adata.data;
UIntArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvULong: {
PVULongArray *aarray = static_cast<PVULongArray *>(a);
PVULongArray *barray = static_cast<PVULongArray *>(b);
ULongArrayData adata;
ULongArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
ULongArray & avalue = adata.data;
ULongArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvFloat: {
PVFloatArray *aarray = static_cast<PVFloatArray *>(a);
PVFloatArray *barray = static_cast<PVFloatArray *>(b);
FloatArrayData adata;
FloatArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
FloatArray & avalue = adata.data;
FloatArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvDouble: {
PVDoubleArray *aarray = static_cast<PVDoubleArray *>(a);
PVDoubleArray *barray = static_cast<PVDoubleArray *>(b);
DoubleArrayData adata;
DoubleArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
DoubleArray & avalue = adata.data;
DoubleArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
case pvString: {
PVStringArray *aarray = static_cast<PVStringArray *>(a);
PVStringArray *barray = static_cast<PVStringArray *>(b);
StringArrayData adata;
StringArrayData bdata;
aarray->get(0,length,adata);
barray->get(0,length,bdata);
StringArray & avalue = adata.data;
StringArray & bvalue = bdata.data;
for(size_t i=0; i<length; i++) {
if(avalue[i]!=bvalue[i]) return false;
}
return true;
}
}
String message("should not get here");
throw std::logic_error(message);
}
static bool structureArrayEquals(PVStructureArray *a,PVStructureArray *b)
{
StructureConstPtr aStructure = a->getStructureArray()->getStructure();
StructureConstPtr bStructure = b->getStructureArray()->getStructure();
if(aStructure!=bStructure) return false;
if(a->getLength()!=b->getLength()) return false;
StructureArrayData aData = StructureArrayData();
StructureArrayData bData = StructureArrayData();
size_t length = a->getLength();
PVStructurePtrArray & aArray = aData.data;
PVStructurePtrArray & bArray = bData.data;
if(aArray==bArray) return true;
for(size_t i=0; i<length; i++) {
if(aArray[i]==0) {
if(bArray[i]==0) continue;
return false;
} else {
if(bArray[i]==0) return false;
}
if(*aArray[i]!=*bArray[i]) return false;
}
return true;
}
static bool structureEquals(PVStructure *a,PVStructure *b)
{
StructureConstPtr aStructure = a->getStructure();
StructureConstPtr bStructure = b->getStructure();
size_t length = aStructure->getNumberFields();
if(length!=bStructure->getNumberFields()) return false;
PVFieldPtrArray const & aFields = a->getPVFields();
PVFieldPtrArray const & bFields = b->getPVFields();
for(size_t i=0; i<length; i++) {
if(*aFields[i]!=*bFields[i]) return false;
}
return true;
}
bool convertEquals(PVField *a,PVField *b)
{
void * avoid = static_cast<void *>(a);
void * bvoid = static_cast<void *>(b);
if(avoid==bvoid) return true;
Type atype = a->getField()->getType();
Type btype = b->getField()->getType();
if(atype!=btype) return false;
if(atype==scalar) return scalarEquals(
static_cast<PVScalar *>(a),static_cast<PVScalar *>(b));
if(atype==scalarArray) return arrayEquals(
static_cast<PVScalarArray*>(a),static_cast<PVScalarArray *>(b));
if(atype==structureArray) return structureArrayEquals(
static_cast<PVStructureArray *>(a),static_cast<PVStructureArray *>(b));
if(atype==structure) return structureEquals(
static_cast<PVStructure *>(a),static_cast<PVStructure *>(b));
String message("should not get here");
throw std::logic_error(message);
}
template<typename PVT,typename T>
size_t convertFromScalarArray(PVScalarArray *pv,
size_t offset, size_t len,const T from[], size_t fromOffset)

View File

@@ -89,7 +89,11 @@ public:
* @param Second field
* @return (false, true) if the fields (are not, are) the same.
*/
bool equals(PVFieldPtr const &a,PVFieldPtr const &b);
bool equals(PVFieldPtr const &a,PVFieldPtr const &b)
{
return *a==*b;
}
/**
* Do fields have the same definition.
*
@@ -97,7 +101,11 @@ public:
* @param Second field
* @return (false, true) if the fields (are not, are) the same.
*/
bool equals(PVField &a,PVField &b);
bool equals(PVField &a,PVField &b)
{
return a==b;
}
/**
* Convert a PVField to a string.
* @param buf buffer for the result