#ifndef CANDBASE_TPL #define CANDBASE_TPL // Templates for CandBase objects. // You must #include this file in CandThing.cxx files after any CVSID() // definition. Separated from CandBase.h by NJT 02/04 // Test methods called from IsEquivalent methods of CandBase derived // classes. Implementations incorporated in CandBase.tpl file to // enable concrete Candidates to instantiate templated method calls. // For Candidate Validation suite by Paul Echevarria, October 2003. #include "MessageService/MsgService.h" //...................................................................... template Bool_t CandBase::TestArrayEquality(const char* mbrName, int arrLen, const mType& thisMbr, const mType& rhsMbr) const { // Tests the equality of a member array Bool_t isEquivalent = true; for (int i=0; i < arrLen; i++) { if (!(thisMbr[i] == rhsMbr[i])) { isEquivalent = false; } } if (isEquivalent) { MSG("VCand", Msg::kDebug) << mbrName << " \t[ok]\n"; } else { MSG("VCand", Msg::kDebug) << mbrName << " \t[not ok]\n"; return false; } return true; } //...................................................................... template Bool_t CandBase::TestCandHandleDup(const char* chName, const chType* thisCH, const chType* rCndCH ) const { // Tests if the CandHandle pointer was DupHandle() if (!thisCH && !rCndCH) { MSG("VCand", Msg::kDebug) << chName << " \t[ok]\n"; return true; } else { if (thisCH == rCndCH) { MSG("VCand", Msg::kDebug) << chName << " \t[is a shallow copy]\n"; return false; } else { if ( *thisCH == *rCndCH) { MSG("VCand", Msg::kDebug) << chName << " \t[ok]\n"; } else { MSG("VCand", Msg::kDebug) << chName << " \t[not ok]\n"; return false; } } } return true; } //...................................................................... template void CandBase::TestDisplayCandBanner(_char* mName) const { // Displays a debugging banner MSG("VCand", Msg::kDebug) << "\n____________" << mName << "::IsEquivalent " << "______________________________\n"; } //...................................................................... template Bool_t CandBase::TestEquality(const char* mbrName, const mType& thisMbr, const mType& rhsMbr) const { // Tests the equality of a simple member if (thisMbr == rhsMbr){ MSG("VCand", Msg::kDebug) << mbrName << " \t[ok]\n"; } else { MSG("VCand", Msg::kDebug) << mbrName << " \t[not ok]\n"; return false; } return true; } //...................................................................... template Bool_t CandBase::TestEquivalence(const char* mName, const mType& thisMbr, const mType& rhsMbr) const { // Tests the equivalence of two objects // (uses the IsEquivalent method) if (&thisMbr == &rhsMbr) { MSG("VCand", Msg::kDebug) << mName << " \t[is a shallow copy]\n"; return false; } else { if (thisMbr.IsEquivalent(&rhsMbr)) { MSG("VCand", Msg::kDebug) << mName << " \t[ok]\n"; } else { MSG("VCand", Msg::kDebug) << mName << " \t[not ok]\n"; return false; } } return true; } //...................................................................... template Bool_t CandBase::TestGenericElemPtrTObjArrayPtrEquality( const char* arrName, const TObjArray* thisTOA, const TObjArray* rCndTOA) const { // Tests the equality of the elements of a TObjArray* member // uses == operator to compare the TObject* elements of the TObjArray return TestGenericElemPtrTObjArrayPtrEquivalence(arrName, thisTOA, rCndTOA, false); } //...................................................................... template Bool_t CandBase::TestGenericElemPtrTObjArrayPtrEquivalence( const char* arrName, const TObjArray* thisTOA, const TObjArray* rCndTOA, Bool_t testEquivalence) const { // Tests the equivalence of the elements of a TObjArray* member // Uses the IsEquivalent() to compare the elements of the TObjArray // for the testEquivalence test // Note: Uses IsEqual() instead of the == operator, for equality test. if (thisTOA == rCndTOA) { MSG("VCand", Msg::kDebug) << arrName << " \t[is a shallow copy]\n"; return false; } else { Bool_t isEquivalent = true; Bool_t isShallow = false; Bool_t dcastFailed = false; if (thisTOA->GetEntries() != thisTOA->GetEntries()) { isEquivalent = false; } else { TIterator* thisIter = thisTOA->MakeIterator(); TIterator* rCndIter = rCndTOA->MakeIterator(); TObject *thisObj, *rCndObj; while ((thisObj = thisIter->Next()) && (rCndObj = rCndIter->Next())) { if (thisObj == rCndObj) { isShallow = true; } else { elemType *thisCB = dynamic_cast(thisObj); elemType *rCndCB = dynamic_cast(rCndObj); if (thisCB == NULL || rCndCB == NULL) { isEquivalent = false; dcastFailed = true; break; } if (testEquivalence) { // use object's IsEquivalent() method if (!thisCB || !rCndCB || !(thisCB->IsEquivalent(rCndCB))) { isEquivalent = false; } } else { // use the object's IsEqual() method if ( !(thisObj->IsEqual(rCndObj)) ) { isEquivalent = false; } } } } } if (isEquivalent) { if (isShallow) { MSG("VCand", Msg::kDebug) << arrName << " \t[shallow copy of TObjArray elements]\n"; } else { MSG("VCand", Msg::kDebug) << arrName << " \t[ok]\n"; } } else { if (dcastFailed) { MSG("VCand", Msg::kDebug) << arrName << " \t[dynamic cast of elements failed--not ok]\n"; } else { MSG("VCand", Msg::kDebug) << arrName << " \t[not ok]\n"; } return false; } } return true; } //...................................................................... template void CandBase::TestNothing(_char* mName) const { // Shows that testing wasn't just looked over MSG("VCand", Msg::kDebug) << mName << " class: Nothing to test.\n"; } //...................................................................... template Bool_t CandBase::TestPtrEquivalence(const char* mName, const mType* thisMbr, const mType* rhsMbr) const { // Tests the equivalence of two object pointers // (uses the IsEquivalent method) if (thisMbr == rhsMbr) { MSG("VCand", Msg::kDebug) << mName << " \t[is a shallow copy]\n"; return false; } else { if (thisMbr->IsEquivalent(rhsMbr)) { MSG("VCand", Msg::kDebug) << mName << " \t[ok]\n"; } else { MSG("VCand", Msg::kDebug) << mName << " \t[not ok]\n"; return false; } } return true; } //...................................................................... template Bool_t CandBase::TestTObjArrayCandHandleDup(const char* arrName, const toaType& thisTOA, const toaType& rCndTOA) const { // Tests if the CandHandles in the TObjArray were DupHandle()d // toaType is always a TObjArray, but it's templatized so the Bool_t isEquivalent = true; Bool_t hasShallowCopies = false; if (thisTOA.GetEntries() != rCndTOA.GetEntries() ){ isEquivalent = false; } else { TIterator* thisIter = thisTOA.MakeIterator(); TIterator* rCndIter = rCndTOA.MakeIterator(); // loop over the CandHandle elements TObject *thisTObj, *rCndTObj; while ( ((thisTObj=thisIter->Next()) != NULL) && ((rCndTObj=rCndIter->Next()) != NULL) ) { if (thisTObj == rCndTObj) { hasShallowCopies = true; isEquivalent = false; } else { const CandHandle* thisCH = dynamic_cast(thisTObj); const CandHandle* rCndCH = dynamic_cast(rCndTObj); if(!(*thisCH == *rCndCH)) { isEquivalent = false; } } } } if (hasShallowCopies) { MSG("VCand", Msg::kDebug) << arrName << " \t[has shallow copies]\n"; } else if (isEquivalent) { MSG("VCand", Msg::kDebug) << arrName << " \t[ok]\n"; } else { MSG("VCand", Msg::kDebug) << arrName << " \t[not ok]\n"; return false; } return true; } //...................................................................... template Bool_t CandBase::TestTObjArrayEquality(const char* arrName, const toaType& thisTOA, const toaType& rCndTOA) const { // Tests the equality of a TObjArray member // array elements are compared by checking if they point to same object // (TObject* == TObject*)? return TestTObjArrayPtrEquality(arrName, &thisTOA, &rCndTOA); } //...................................................................... template Bool_t CandBase::TestTObjArrayPtrEquality(const char* arrName, const toaType* thisTOA, const toaType* rCndTOA ) const { // Tests the equality of the elements of a TObjArray* member // uses == operator to compare the TObject* elements of the TObjArray return TestTObjArrayPtrEquivalence(arrName, thisTOA, rCndTOA, false); } //...................................................................... template Bool_t CandBase::TestTObjArrayPtrEquivalence(const char* arrName, const toaType* thisTOA, const toaType* rCndTOA, Bool_t testEquivalence) const { // Tests the equivalence of the elements of a TObjArray* member // Uses the IsEquivalent() to compare the elements of the TObjArray // for the testEquivalence test if (thisTOA == rCndTOA) { MSG("VCand", Msg::kDebug) << arrName << " \t[is a shallow copy]\n"; return false; } else { Bool_t isEquivalent = true; if (thisTOA->GetEntries() != thisTOA->GetEntries()) { isEquivalent = false; } else { TIterator* thisIter = thisTOA->MakeIterator(); TIterator* rCndIter = rCndTOA->MakeIterator(); TObject *thisObj, *rCndObj; while ( (thisObj = thisIter->Next()) && (rCndObj = rCndIter->Next()) ) { if (testEquivalence) { // use the object's IsEquivalent() method CandBase *thisCB = dynamic_cast(thisObj); CandBase *rCndCB = dynamic_cast(rCndObj); if (!thisCB || !rCndCB || !(thisCB->IsEquivalent(rCndCB)) ) { isEquivalent = false; } } else { // use the == operator if ( !(thisObj == rCndObj) ) { isEquivalent = false; } } } } if (isEquivalent) { MSG("VCand", Msg::kDebug) << arrName << " \t[ok]\n"; } else { MSG("VCand", Msg::kDebug) << arrName << " \t[not ok]\n"; return false; } } return true; } #endif // CANDBASE_TPL