// Copyright (c) 2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Auxiliary macro to check and report status. // Note that if() is used to ensure that condition is // evaluated before calls to stream output functions, to // prevent side effects from such calls in cases when condition // may contain references to freed objects in the stack. #define CHECK(di,ok,what) \ if (ok) di << "Checking " << what << ": OK\n";\ else di << "Checking " << what << ": Error\n" //======================================================================= //function : QAHandleOps //purpose : Test Handle operations (mostly compile-time checks) //======================================================================= // set of overloaded functions for checking resolution of arguments inline void f (const Handle(Geom_Curve)&) {} inline void func (const Handle(Geom_Curve)&) {} inline void func (const Handle(Geom_BSplineCurve)&) {} inline void func (const Handle(Geom_Surface)&) {} inline void func (const Handle(gp_Pnt)&) {} inline void func (const Handle(gp_XYZ)&) {} inline void func (const Handle(gp_Trsf)&) {} static Standard_Integer QAHandleOps (Draw_Interpretor& theDI, Standard_Integer /*theArgNb*/, const char** /*theArgVec*/) { // =============================================================== // Part 1: classes inheriting transient // =============================================================== Handle(Geom_Line) aLine = new Geom_Line (gp::Origin(), gp::DZ()); CHECK(theDI, ! aLine.IsNull(), "handle for non-null"); const Handle(Geom_Line)& cLine = aLine; // cast to self const ref const Handle(Geom_Curve)& cCurve = aLine; // cast to base const ref Geom_Line* pLine = aLine.get(); const Geom_Line* cpLine = aLine.get(); Geom_Line& rLine = *aLine; const Geom_Line& crLine = *cLine; Handle(Geom_Curve) aCurve = aLine; // copy from handle to derived type aCurve = cLine; // assignment to handle of derived type Handle(Geom_Line) dLine (cpLine); // copy from handle to derived type aLine = Handle(Geom_Line)::DownCast (cCurve); CHECK(theDI, ! aLine.IsNull(), "down cast"); // comparison operators CHECK(theDI, aLine == aLine, "equality of handle to itself"); CHECK(theDI, cLine == cLine, "equality of const handle to itself"); CHECK(theDI, aLine == cLine, "equality of const and non-const handle"); CHECK(theDI, aLine == cCurve, "equality of handle and base handle"); CHECK(theDI, aLine == pLine, "equality of handle and pointer"); CHECK(theDI, pLine == aLine, "equality of pointer and handle"); CHECK(theDI, aLine == cpLine, "equality of handle and const pointer"); CHECK(theDI, cpLine == aLine, "equality of const pointer and handle"); CHECK(theDI, &rLine == aLine, "equality of reference and handle"); CHECK(theDI, &crLine == aLine, "equality of reference and handle"); CHECK(theDI, aLine, "cast to bool"); Handle(Geom_Line) aLin2; CHECK(theDI, aLine != aLin2, "inequality of handle to the same type handle"); CHECK(theDI, aLin2 != cLine, "inequality of const and non-const handle"); CHECK(theDI, aLin2 != cCurve, "inequality of handle and base handle"); CHECK(theDI, aLin2 != pLine, "inequality of handle and pointer"); CHECK(theDI, pLine != aLin2, "inequality of pointer and handle"); CHECK(theDI, aLin2 != cpLine, "inequality of handle and const pointer"); CHECK(theDI, cpLine != aLin2, "inequality of const pointer and handle"); Handle(Geom_Curve) aCur2; CHECK(theDI, aLine != aCur2, "inequality of handles of different types"); CHECK(theDI, aCur2 != cLine, "inequality of const and non-const handle"); CHECK(theDI, aCur2 != cCurve, "inequality of handle and base handle"); CHECK(theDI, aCur2 != pLine, "inequality of handle and pointer"); CHECK(theDI, pLine != aCur2, "inequality of pointer and handle"); CHECK(theDI, aCur2 != cpLine, "inequality of handle and const pointer"); CHECK(theDI, cpLine != aCur2, "inequality of const pointer and handle"); // passing handle as reference to base class f (aLine); // passing handle to overloaded function accepting handle to another type // will fail on VC below 12 and GCC below 4.3 due to ambiguity of overloads #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) || (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3) func (aLine); func (cLine); #endif const Handle(Geom_Curve)& aCurve2 = aLine; // cast to base const ref CHECK (theDI, !aCurve2.IsNull (), "cast to base class const reference"); Handle(Geom_Line) qLine = cpLine; // constructor from const pointer -- could be made explicit... // check that compiler keeps temporary object referenced by local variable const Handle(Geom_Line)& aTmpRef (Handle(Geom_Line)::DownCast (aCurve2)); // note that here and in similar checks below we use comparison of pointers instead // of checking handle for Null, since such check may fail if temporary object is // destroyed prematurely and its location is used for other object. CHECK(theDI, aTmpRef.get() == aCurve2.get(), "local reference of to temporary handle object"); // check undesired but logical situation: // compiler does not keep temporary object referenced by local variable of base type; // here compiler does not recognize that it should keep the temporary object because handle // classes do not inherit each other and they use hard cast for references to simulate inheritance const Handle(Geom_Curve)& aTmpRefBase (Handle(Geom_Line)::DownCast (aCurve2)); CHECK(theDI, aTmpRefBase.get() != aCurve2.get(), "local reference to temporary handle object (base type)"); // check operations with Handle_* classes Handle(Geom_Line) hLine = aLine; CHECK(theDI, ! hLine.IsNull(), "hhandle for non-null"); const Handle_Geom_Line& chLine = aLine; // cast to self const ref const Handle_Geom_Curve& chCurve = aLine; // cast to base const ref const Handle_Geom_Line& hhLine = hLine; // cast to self const ref const Handle_Geom_Curve& hhCurve = hLine; // cast to base const ref Handle_Geom_Curve hCurve = aLine; // copy from handle to derived type Handle_Geom_Line phLine (aLine.get()); // construct from pointer hLine = Handle_Geom_Line::DownCast (cCurve); // inheritance of downcast CHECK(theDI, ! hLine.IsNull(), "down cast"); // comparison operators CHECK(theDI, hLine == hLine, "equality of hhandle to itself"); CHECK(theDI, hLine == aLine, "equality of hhandle to handle"); CHECK(theDI, hhLine == hLine, "equality of hhandle to const"); CHECK(theDI, chLine == hLine, "equality of hhandle to const"); CHECK(theDI, hhCurve == hLine, "equality of hhandle to const"); CHECK(theDI, chCurve == hLine, "equality of hhandle to const"); CHECK(theDI, hLine, "cast to bool"); // passing hhandle as reference to base class f (hLine); // passing handle to overloaded function accepting handle to another type // will fail on VC below 12 and GCC below 4.3 due to ambiguity of overloads #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) || (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3) func (hLine); func (chLine); #endif Handle_Geom_Line qhLine = cpLine; // constructor from const pointer -- could be made explicit... // check that compiler keeps temporary object referenced by local variable const Handle_Geom_Line& hTmpRef (Handle(Geom_Line)::DownCast (aCurve2)); CHECK(theDI, hTmpRef.get() == aCurve2.get(), "local reference to temporary object (Handle_)"); // check lifetime of temporary object referenced by local variable (base type) const Handle_Geom_Curve& hTmpRefBase (Handle(Geom_Line)::DownCast (aCurve2)); // here we have different behavior for MSVC 2013+ where Handle_ is a class // (compiler creates temporary object of approprtiate type and keeps it living // until the reference is valid) and other compilers where Handle_ is // typedef to handle<> (compiler does not know that the reference that is being // assigned is pointing to temporary object, due to involved type cast operation) #if (defined(_MSC_VER) && _MSC_VER >= 1800) CHECK(theDI, hTmpRefBase.get() == aCurve2.get(), "local reference to temporary handle object (Handle_ to base type)"); #else CHECK(theDI, hTmpRefBase.get() != aCurve2.get(), "local reference to temporary handle object (Handle_ to base type)"); #endif Handle(Geom_Surface) aSurf; (void)aSurf; #if 0 // each test in this section must cause compiler error gunc (cLine); // passing const handle as non-const reference to base type pLine = cLine.get(); // getting non-const pointer to contained object from const handle Handle(Geom_Line) xLine = cCurve; // copy from handle to base type Handle(Geom_BSplineCurve) aBSpl (new Geom_Line (gp::Origin(), gp::DX())); // construction from pointer to incompatible type CHECK(theDI, aLine == aSurf, "equality of handles of incompatible types"); CHECK(theDI, aSurf == cLine, "equality of const and non-const handle"); CHECK(theDI, aSurf == cCurve, "equality of handle and base handle"); CHECK(theDI, aSurf == pLine, "equality of handle and pointer"); CHECK(theDI, pLine == aSurf, "equality of pointer and handle"); CHECK(theDI, aSurf == cpLine, "equality of handle and const pointer"); CHECK(theDI, cpLine != aSurf, "equality of const pointer and handle"); CHECK(theDI, aLine != aSurf, "inequality of handles of incompatible types"); CHECK(theDI, aSurf != cLine, "inequality of const and non-const handle"); CHECK(theDI, aSurf != cCurve, "inequality of handle and base handle"); CHECK(theDI, aSurf != pLine, "inequality of handle and pointer"); CHECK(theDI, pLine != aSurf, "inequality of pointer and handle"); CHECK(theDI, aSurf != cpLine, "inequality of handle and const pointer"); CHECK(theDI, cpLine != aSurf, "inequality of const pointer and handle"); #endif // =============================================================== // Part 2: classes not inheriting transient // =============================================================== /* Handle(gp_Pnt) aPnt = new gp_Pnt (gp::Origin()); CHECK(theDI, ! aPnt.IsNull(), "handle for non-null"); const Handle(gp_Pnt)& cPnt = aPnt; // cast to self const ref // const Handle(gp_XYZ)& cXYZ = aPnt; // cast to base const ref gp_Pnt* pPnt = aPnt.get(); const gp_Pnt* cpPnt = aPnt.get(); gp_Pnt& rPnt = *aPnt; const gp_Pnt& crPnt = *cPnt; // Handle(gp_XYZ) aXYZ = aPnt; // copy from handle to derived type // aXYZ = cPnt; // assignment to handle of derived type // aPnt = Handle(gp_Pnt)::DownCast (cXYZ); // CHECK(theDI, ! aPnt.IsNull(), "down cast"); // comparison operators CHECK(theDI, aPnt == aPnt, "equality of handle to itself"); CHECK(theDI, cPnt == cPnt, "equality of const handle to itself"); CHECK(theDI, aPnt == cPnt, "equality of const and non-const handle"); // CHECK(theDI, aPnt == cXYZ, "equality of handle and base handle"); CHECK(theDI, aPnt == pPnt, "equality of handle and pointer"); CHECK(theDI, pPnt == aPnt, "equality of pointer and handle"); CHECK(theDI, aPnt == cpPnt, "equality of handle and const pointer"); CHECK(theDI, cpPnt == aPnt, "equality of const pointer and handle"); CHECK(theDI, &rPnt == aPnt, "equality of reference and handle"); CHECK(theDI, &crPnt == aPnt, "equality of reference and handle"); Handle(gp_Pnt) aPnt2; CHECK(theDI, aPnt != aPnt2, "inequality of handle to the same type handle"); CHECK(theDI, aPnt2 != cPnt, "inequality of const and non-const handle"); // CHECK(theDI, aPnt2 != cXYZ, "inequality of handle and base handle"); CHECK(theDI, aPnt2 != pPnt, "inequality of handle and pointer"); CHECK(theDI, pPnt != aPnt2, "inequality of pointer and handle"); CHECK(theDI, aPnt2 != cpPnt, "inequality of handle and const pointer"); CHECK(theDI, cpPnt != aPnt2, "inequality of const pointer and handle"); Handle(gp_XYZ) aXYZ2; CHECK(theDI, aLine != aPnt2, "inequality of handles of different types"); CHECK(theDI, aXYZ2 != cPnt, "inequality of const and non-const handle"); // CHECK(theDI, aXYZ2 != cXYZ, "inequality of handle and base handle"); // CHECK(theDI, aXYZ2 != pPnt, "inequality of handle and pointer"); // CHECK(theDI, pPnt != aXYZ2, "inequality of pointer and handle"); // CHECK(theDI, aXYZ2 != cpPnt, "inequality of handle and const pointer"); // CHECK(theDI, cpPnt != aXYZ2, "inequality of const pointer and handle"); // passing handle as reference to base class func (aPnt); func (cPnt); */ return 0; } //======================================================================= //function : QAHandleBool //purpose : Test Handle -> bool conversion //======================================================================= static Standard_Integer QAHandleBool (Draw_Interpretor& theDI, Standard_Integer /*theArgNb*/, const char** /*theArgVec*/) { Handle(NCollection_BaseAllocator) aPtr = new NCollection_IncAllocator(); Handle(NCollection_IncAllocator) anInc = Handle(NCollection_IncAllocator)::DownCast (aPtr); CHECK (theDI, ! anInc.IsNull(), "cast to NCollection_IncAllocator"); Handle(NCollection_BaseAllocator) anAlloc = aPtr; CHECK (theDI, ! anAlloc.IsNull(), "cast to NCollection_BaseAllocator"); Handle(NCollection_HeapAllocator) aHAlloc = Handle(NCollection_HeapAllocator)::DownCast (aPtr); CHECK (theDI, aHAlloc.IsNull(), "cast to NCollection_HeapAllocator"); return 0; } // Auxiliary class to define new virtual methods class Transient_Root : public Standard_Transient { public: virtual const char* Name() const { return "Transient_Root"; } virtual Standard_Transient* CreateParent() const { return new Standard_Transient; } virtual Standard_Transient* Clone() const { return new Transient_Root; } DEFINE_STANDARD_RTTI_INLINE(Transient_Root,Standard_Transient) }; DEFINE_STANDARD_HANDLE(Transient_Root, Standard_Transient) // Auxiliary macros to create hierarchy of 50 classes #define QA_DEFINECLASS(theClass, theParent) \ class theClass : public theParent \ { \ public:\ virtual const char* Name() const Standard_OVERRIDE { return #theClass; } \ virtual Standard_Transient* CreateParent() const Standard_OVERRIDE { return new theParent(); } \ virtual Standard_Transient* Clone() const Standard_OVERRIDE { return new theClass(); } \ DEFINE_STANDARD_RTTI_INLINE(theClass,theParent) \ };\ DEFINE_STANDARD_HANDLE (theClass, theParent) #define QA_NAME(theNum) qaclass ## theNum ## _ ## 50 #define QA_HANDLE_NAME(theNum) Handle(qaclass ## theNum ## _ ## 50) #define QA_DEFINECLASS10(theParent, theTens) \ QA_DEFINECLASS(QA_NAME(theTens ## 0), theParent) \ QA_DEFINECLASS(QA_NAME(theTens ## 1), QA_NAME(theTens ## 0)) \ QA_DEFINECLASS(QA_NAME(theTens ## 2), QA_NAME(theTens ## 1)) \ QA_DEFINECLASS(QA_NAME(theTens ## 3), QA_NAME(theTens ## 2)) \ QA_DEFINECLASS(QA_NAME(theTens ## 4), QA_NAME(theTens ## 3)) \ QA_DEFINECLASS(QA_NAME(theTens ## 5), QA_NAME(theTens ## 4)) \ QA_DEFINECLASS(QA_NAME(theTens ## 6), QA_NAME(theTens ## 5)) \ QA_DEFINECLASS(QA_NAME(theTens ## 7), QA_NAME(theTens ## 6)) \ QA_DEFINECLASS(QA_NAME(theTens ## 8), QA_NAME(theTens ## 7)) \ QA_DEFINECLASS(QA_NAME(theTens ## 9), QA_NAME(theTens ## 8)) QA_DEFINECLASS10(Transient_Root, 0) QA_DEFINECLASS10(qaclass09_50, 1) QA_DEFINECLASS10(qaclass19_50, 2) QA_DEFINECLASS10(qaclass29_50, 3) QA_DEFINECLASS10(qaclass39_50, 4) QA_DEFINECLASS (qaclass50_50, qaclass49_50) namespace { class qaclass50_50ANON : public qaclass49_50 { }; } namespace QaNamespace { class qaclass50_50 : public qaclass49_50 { public: qaclass50_50() {} }; } namespace { //! Timer sentry. Prints elapsed time information at destruction time. class QATimer : public OSD_Timer { public: enum TimeFormat { Seconds, Milliseconds, Microseconds, Nanoseconds, s = Seconds, ms = Milliseconds, ns = Nanoseconds, }; public: //! Main constructor - automatically starts the timer. QATimer (Draw_Interpretor& theDI, Standard_CString theTitle, const TimeFormat theFormat, const Standard_Integer theNbIters = 1, const Standard_Boolean theToPrintFormat = Standard_False) : myDI(&theDI), myTitle (theTitle), myFormat (theFormat), myNbIters (theNbIters), myToPrintFormat (theToPrintFormat) { Start(); } //! Destructor - stops the timer and prints statistics. ~QATimer() { Stop(); if (myTitle != NULL) { (*myDI) << myTitle; } switch (myFormat) { case Seconds: (*myDI) << ElapsedTime() / Standard_Real(myNbIters); if (myToPrintFormat) { (*myDI) << " s"; } break; case Milliseconds: (*myDI) << (ElapsedTime() / Standard_Real(myNbIters)) * 1000.0; if (myToPrintFormat) { (*myDI) << " ms"; } break; case Microseconds: (*myDI) << (ElapsedTime() / Standard_Real(myNbIters)) * 1000000.0; if (myToPrintFormat) { (*myDI) << " microseconds"; } break; case Nanoseconds: (*myDI) << (ElapsedTime() / Standard_Real(myNbIters)) * 1000000000.0; if (myToPrintFormat) { (*myDI) << " ns"; } break; } } private: Draw_Interpretor* myDI; Standard_CString myTitle; //!< timer description TimeFormat myFormat; //!< time format Standard_Integer myNbIters; //!< iterations number Standard_Boolean myToPrintFormat; //!< add time format }; } // anonymous namespace //======================================================================= //function : QAHandleInc //purpose : Estimate the smart-pointer counter incrementing time //======================================================================= static Standard_Integer QAHandleInc (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) { if (theArgNb > 2) { std::cout << "Error: wrong syntax! See usage:\n"; theDI.PrintHelp (theArgVec[0]); return 1; } const Standard_Integer aNbIters = (theArgNb > 1) ? Draw::Atoi (theArgVec[1]) : 10000000; if (aNbIters < 1) { std::cout << "Error: number of iterations should be positive!\n"; return 1; } Handle(Standard_Transient) aHandle = new Standard_Transient(); std::shared_ptr aSharePtr (new Standard_Transient()); theDI << "Time of creating and destroying " << aNbIters << " smart pointers to the same object, per item, ns:"; { { QATimer aTimer (theDI, "\nOCCT Handle: ", QATimer::ns, aNbIters); { std::vector aHandles (aNbIters); for (Standard_Integer anIter = 0; anIter < aNbIters; ++anIter) { aHandles[anIter] = aHandle; } } } { QATimer aTimer (theDI, "\nC++ shared_ptr: ", QATimer::ns, aNbIters); { std::vector< std::shared_ptr > aSharePointers (aNbIters); for (Standard_Integer anIter = 0; anIter < aNbIters; ++anIter) { aSharePointers[anIter] = aSharePtr; } } } } return 0; } //======================================================================= //function : QAHandleKind //purpose : //======================================================================= static Standard_Integer QAHandleKind (Draw_Interpretor& /*theDI*/, Standard_Integer /*theArgNb*/, const char** /*theArgVec*/) { Handle(Standard_Type) aType00 = STANDARD_TYPE(qaclass00_50); Handle(Standard_Type) aType10 = STANDARD_TYPE(qaclass10_50); Handle(Standard_Type) aType20 = STANDARD_TYPE(qaclass20_50); Handle(Standard_Type) aType30 = STANDARD_TYPE(qaclass30_50); Handle(Standard_Type) aType40 = STANDARD_TYPE(qaclass40_50); Handle(Standard_Type) aType50 = STANDARD_TYPE(qaclass50_50); Handle(qaclass00_50) aHandle = new qaclass40_50(); #define QA_CHECK(theDesc, theExpr, theValue) \ {\ const bool isTrue = !!(theExpr); \ std::cout << theDesc << (isTrue ? " TRUE " : " FALSE ") << (isTrue == theValue ? " is OK\n" : " is Error\n"); \ } std::cout << "Check instance of " << aHandle->DynamicType()->Name() << "\n"; for (Handle(Standard_Type) aType = aHandle->DynamicType(); ! aType.IsNull(); aType = aType->Parent()) { std::cout << " - " << aType->Name() << "\n"; } QA_CHECK ("Name == qaclass40_50 : ", TCollection_AsciiString("qaclass40_50") == aHandle->DynamicType()->Name(), true); QA_CHECK ("IsKind (aType00) : ", aHandle->IsKind (aType00), true); QA_CHECK ("IsKind (aType10) : ", aHandle->IsKind (aType10), true); QA_CHECK ("IsKind (aType20) : ", aHandle->IsKind (aType20), true); QA_CHECK ("IsKind (aType30) : ", aHandle->IsKind (aType30), true); QA_CHECK ("IsKind (aType40) : ", aHandle->IsKind (aType40), true); QA_CHECK ("IsKind (aType50) : ", aHandle->IsKind (aType50), false); QA_CHECK ("IsKind (\"qaclass00_50\"): ", aHandle->IsKind ("qaclass00_50"), true); QA_CHECK ("IsKind (\"qaclass10_50\"): ", aHandle->IsKind ("qaclass10_50"), true); QA_CHECK ("IsKind (\"qaclass20_50\"): ", aHandle->IsKind ("qaclass20_50"), true); QA_CHECK ("IsKind (\"qaclass30_50\"): ", aHandle->IsKind ("qaclass30_50"), true); QA_CHECK ("IsKind (\"qaclass40_50\"): ", aHandle->IsKind ("qaclass40_50"), true); QA_CHECK ("IsKind (\"qaclass50_50\"): ", aHandle->IsKind ("qaclass50_50"), false); QA_CHECK ("IsInstance (aType00) : ", aHandle->IsInstance (aType00), false); QA_CHECK ("IsInstance (aType10) : ", aHandle->IsInstance (aType10), false); QA_CHECK ("IsInstance (aType20) : ", aHandle->IsInstance (aType20), false); QA_CHECK ("IsInstance (aType30) : ", aHandle->IsInstance (aType30), false); QA_CHECK ("IsInstance (aType40) : ", aHandle->IsInstance (aType40), true); QA_CHECK ("IsInstance (aType50) : ", aHandle->IsInstance (aType50), false); #ifdef HAVE_CPP11 std::cout << "\nC++11:\n"; std::type_index aCppType = typeid(*aHandle.operator->()); std::cout << "typeid().name() = '" << typeid(*aHandle.operator->()).name() << "'\n"; #ifdef _MSC_VER std::cout << "typeid().raw_name()= '" << typeid(*aHandle.operator->()).raw_name() << "'\n"; #endif std::cout << "[ANON]typeid().name() = '" << typeid(qaclass50_50ANON).name() << "'\n"; #ifdef _MSC_VER std::cout << "[ANON]typeid().raw_name()= '" << typeid(qaclass50_50ANON).raw_name() << "'\n"; #endif std::cout << "[NS]typeid().name() = '" << typeid(QaNamespace::qaclass50_50).name() << "'\n"; #ifdef _MSC_VER std::cout << "[NS]typeid().raw_name()= '" << typeid(QaNamespace::qaclass50_50).raw_name() << "'\n"; #endif QA_CHECK ("is typeid (aType00) : ", typeid(*aHandle.operator->()) == typeid(qaclass00_50), false); QA_CHECK ("is typeid (aType10) : ", typeid(*aHandle.operator->()) == typeid(qaclass10_50), false); QA_CHECK ("is typeid (aType20) : ", typeid(*aHandle.operator->()) == typeid(qaclass20_50), false); QA_CHECK ("is typeid (aType30) : ", typeid(*aHandle.operator->()) == typeid(qaclass30_50), false); QA_CHECK ("is typeid (aType40) : ", typeid(*aHandle.operator->()) == typeid(qaclass40_50), true); QA_CHECK ("is typeid (aType50) : ", typeid(*aHandle.operator->()) == typeid(qaclass50_50), false); QA_CHECK ("is type_index (aType00) : ", aCppType == typeid(qaclass00_50), false); QA_CHECK ("is type_index (aType40) : ", aCppType == typeid(qaclass40_50), true); QA_CHECK ("IsClass(Standard_Transient): ", std::is_class::value == !!STANDARD_TYPE(Standard_Transient)->IsClass(), true); //QA_CHECK ("IsEnum (Message_Status) : ", std::is_enum::value == !!STANDARD_TYPE(Message_Status)->IsEnumeration(), true); #endif return 0; } void QANCollection::CommandsHandle (Draw_Interpretor& theCommands) { const char* THE_GROUP = "QANCollection"; theCommands.Add ("QAHandleBool", "Test handle boolean operator", __FILE__, QAHandleBool, THE_GROUP); theCommands.Add ("QAHandleInc", "QAHandleInc nbIter=1000000" "\n\t\t: Test handle increment performance", __FILE__, QAHandleInc, THE_GROUP); theCommands.Add ("QAHandleKind", "Test handle IsKind", __FILE__, QAHandleKind, THE_GROUP); theCommands.Add ("QAHandleOps", "Test handle operations", __FILE__, QAHandleOps, THE_GROUP); return; }