0024947: Redesign OCCT legacy type system
authorabv <abv@opencascade.com>
Fri, 22 May 2015 03:40:28 +0000 (06:40 +0300)
committerabv <abv@opencascade.com>
Sat, 11 Jul 2015 08:05:31 +0000 (11:05 +0300)
Global static functions instantiating RTTI descriptors for class types (used though STANDARD_TYPE macro) are replaced by template static method Instance() of the class Standard_Type.
Implementation of RTTI is revised accordingly (global registry of type descriptors added to ensure single instance of each type descriptor shared by all dynamic libraries).
Obsolete methods of Standard_Type class (IsInstance(), Ancestors()) are removed; new method Parent() is added returning type descriptor of the parent class.
Class Standard_AncestorIterator is removed; this iteration can be easily done by recursive calls to Standard_Type::Parent().

Definition of macro STANDARD_TYPE() moved from Standard_Macro.hxx to Standard_DefineHandle.hxx.
Inclusion of Standard_Type.hxx and the class header is now necessary for use of method DownCast() and function STANDARD_TYPE() for the class.
In general, Standard_Type.hxx should be included now instead of Standard_DefineHandle.hxx in places where these macros are used.

Macro DEFINE_STANDARD_EXCEPTION changed to define all methods inline; macro IMPLEMENT_STANDARD_EXCEPTION becomes obsolete.
Macros IMPLEMENT_DOWNCAST, IMPLEMENT_STANDARD_* become deprecated, they are still defined (as empty) for compatibility.

Implementation of Handle classes became fully inline.
Method get() is added in Handle classes returning pointer to the contained object.

RTTI removed from NCollection_Handle class.

Standard_Persistent is made empty descendant of Standard_Transient, instead of implementing its own hierarchy with reference counting.

Unused enumerations Standard_InternalType, Standard_WayOfLife, Standard_KindOfType are removed.
Global function HashCode() accepting Handle(Standard_Transient) is removed; HashCode() for Standard_CString with length should be used instead.

DRAW command dtryload is added for testing dynamic load / unload of the specified library.
New test perf fclasses bug24947 uses this command to measure performance of multiple (1000 times) loading / unloading OCCT libs on example of TKSTEP.

38 files changed:
src/DDF/DDF_DataCommands.cxx
src/Draw/Draw_PloadCommands.cxx
src/IFSelect/IFSelect_BasicDumper.cxx
src/IntImp/IntImp_ComputeTangence.cxx
src/Message/Message_Algorithm.cxx
src/NCollection/NCollection_Handle.cxx
src/NCollection/NCollection_Handle.hxx
src/Precision/Precision.cxx
src/SelectMgr/SelectMgr_SelectableObject.cxx
src/Standard/FILES
src/Standard/Handle_Standard_Persistent.cxx
src/Standard/Handle_Standard_Persistent.hxx
src/Standard/Handle_Standard_Transient.hxx
src/Standard/Standard.cdl
src/Standard/Standard_AncestorIterator.cdl [deleted file]
src/Standard/Standard_AncestorIterator.cxx [deleted file]
src/Standard/Standard_CString.cxx
src/Standard/Standard_DefineException.hxx
src/Standard/Standard_DefineHandle.hxx
src/Standard/Standard_Failure.cdl
src/Standard/Standard_Failure.cxx
src/Standard/Standard_HashCode.cxx
src/Standard/Standard_Macro.hxx
src/Standard/Standard_Persistent.cxx
src/Standard/Standard_Persistent_proto.hxx
src/Standard/Standard_PrimitiveTypes.hxx
src/Standard/Standard_ShortReal.hxx
src/Standard/Standard_Transient.cdl
src/Standard/Standard_Transient.cxx
src/Standard/Standard_Transient.hxx
src/Standard/Standard_Transient_proto.hxx
src/Standard/Standard_Type.cdl [deleted file]
src/Standard/Standard_Type.cxx
src/Standard/Standard_Type.hxx [new file with mode: 0644]
src/Standard/Standard_Type.lxx [deleted file]
src/TDataStd/TDataStd_TreeNode.cxx
tests/perf/fclasses/bug24947 [new file with mode: 0644]
tests/perf/grids.list

index 65eb753..a1d00aa 100644 (file)
@@ -317,11 +317,7 @@ static Standard_Integer  DDF_CheckAttrs (Draw_Interpretor& di,Standard_Integer n
                }
                TDF_Tool::Entry(sAtt->Label(), entr1);
                //cout<<"\tAttribute dynamic type = "<<sAtt->DynamicType()<<",\tlocated on Label = "<<entr1<<endl;
-               di<<"\tAttribute dynamic type = ";
-               Standard_SStream aSStream;
-               sAtt->DynamicType()->Print(aSStream);
-               aSStream << ends;
-               di << aSStream;
+               di<<"\tAttribute dynamic type = " << sAtt->DynamicType()->Name();
                di<<",\tlocated on Label = "<<entr1.ToCString()<<"\n";
              }
          }
@@ -356,21 +352,14 @@ static Standard_Integer  DDF_CheckLabel (Draw_Interpretor& di,Standard_Integer n
     for (TDF_AttributeIterator itr(SOURCE); itr.More(); itr.Next()) {
       itr.Value()->References(ds1);
       //cout<<"\tSource Attribute dynamic type = "<<itr.Value()->DynamicType()<<endl;
-      di<<"\tSource Attribute dynamic type = ";
-      Standard_SStream aSStream1;
-      itr.Value()->DynamicType()->Print(aSStream1);
-      aSStream1 << ends;
-      di << aSStream1 << "\n";
+      di<<"\tSource Attribute dynamic type = " << itr.Value()->DynamicType()->Name() << "\n";
       const TDF_AttributeMap& attMap = ds1->Attributes(); //attMap
       for (TDF_MapIteratorOfAttributeMap attMItr(attMap);attMItr.More(); attMItr.Next()) {
        Handle(TDF_Attribute) sAtt = attMItr.Key();
        TCollection_AsciiString entry;
        TDF_Tool::Entry(sAtt->Label(), entry);
        //cout<<"\t\tReferences attribute dynamic type = "<<sAtt->DynamicType()<<",\tLabel = "<<entry<<endl;
-       di<<"\t\tReferences attribute dynamic type = ";
-       Standard_SStream aSStream2;
-       sAtt->DynamicType()->Print(aSStream2);
-       di << aSStream2;
+       di<<"\t\tReferences attribute dynamic type = " << sAtt->DynamicType()->Name();
        di<<",\tLabel = "<<entry.ToCString()<<"\n";
       }
       ds1->Clear();
index 06a1c00..98f7ac2 100644 (file)
@@ -18,6 +18,7 @@
 #include <OSD_Directory.hxx>
 #include <OSD_File.hxx>
 #include <OSD_Environment.hxx>
+#include <OSD_SharedLibrary.hxx>
 #include <Resource_Manager.hxx>
 #include <Draw_Interpretor.hxx>
 #include <Draw_MapOfAsciiString.hxx>
@@ -252,6 +253,32 @@ static Standard_Integer Pload (Draw_Interpretor& di,
 }
 
 //=======================================================================
+//function : dtryload
+//purpose  : 
+//=======================================================================
+
+static Standard_Integer dtryload (Draw_Interpretor& di, Standard_Integer n, const char** argv)
+{
+  if (n != 2)
+  {
+    cout << "Error: specify path to library to be loaded" << endl;
+    return 1;
+  }
+
+  OSD_SharedLibrary aLib(argv[1]);
+  if (aLib.DlOpen(OSD_RTLD_NOW))
+  {
+    di << "Loading " << argv[1] << " successful";
+    aLib.DlClose();
+  }
+  else 
+  {
+    di << "Loading " << argv[1] << " failed: " << aLib.DlError();
+  }
+  return 0;
+}
+
+//=======================================================================
 //function : PloadCommands
 //purpose  : 
 //=======================================================================
@@ -266,4 +293,6 @@ void Draw::PloadCommands(Draw_Interpretor& theCommands)
   
   theCommands.Add("pload" , "pload [-PluginFilename] [[Key1] [Key2] ...]: Loads Draw plugins " ,
                  __FILE__, Pload, g);
+  theCommands.Add("dtryload" , "dtryload path : load and unload specified dynamic loaded library" ,
+                 __FILE__, dtryload, g);
 }
index 4e80679..68c0863 100644 (file)
@@ -73,13 +73,6 @@ IFSelect_BasicDumper::IFSelect_BasicDumper ()  {  }
     file.SendItem(sra->Upper());
     return Standard_True;
   }
-/*  if (type == STANDARD_TYPE(IFSelect_SelectTextType)) {
-    DeclareAndCast(IFSelect_SelectTextType,sty,item);
-    if (sty->IsExact()) file.SendText("exact");
-    else                file.SendText("contains");
-    file.SendText(sty->SignatureText().ToCString());
-    return Standard_True;
-  } */
   if (type == STANDARD_TYPE(IFSelect_SelectShared))          return Standard_True;
   if (type == STANDARD_TYPE(IFSelect_SelectSharing))         return Standard_True;
 
index 3c94fdb..5cf4a41 100644 (file)
@@ -12,6 +12,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <IntImp_ComputeTangence.hxx>
 #include <IntImp_ConstIsoparametric.hxx>
 
 static const IntImp_ConstIsoparametric staticChoixRef [4] = {
@@ -23,8 +24,6 @@ IntImp_VIsoparametricOnCaro2,
 
 Standard_EXPORT const IntImp_ConstIsoparametric *ChoixRef = staticChoixRef ;
 
-#include <IntImp_ComputeTangence.hxx>
-
 //=======================================================================
 //function : IntImp_ComputeTangence
 //purpose  : 
index 28f8c74..ac990e0 100644 (file)
@@ -21,7 +21,6 @@
 #include <Message_Msg.hxx>
 #include <Message_MsgFile.hxx>
 #include <Message_Messenger.hxx>
-#include <Standard_AncestorIterator.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
 #include <TColStd_HSequenceOfInteger.hxx>
@@ -187,8 +186,6 @@ void Message_Algorithm::SendStatusMessages (const Message_ExecStatus& theStatus,
     return;
   }
 
-  const TCollection_AsciiString aClassName (DynamicType()->Name());
-
   // Iterate on all set flags in the specified range
   for ( Standard_Integer i  = Message_ExecStatus::FirstStatus; 
                          i <= Message_ExecStatus::LastStatus; i++ )
@@ -221,24 +218,14 @@ void Message_Algorithm::SendStatusMessages (const Message_ExecStatus& theStatus,
     }
     aSuffix.AssignCat( Message_ExecStatus::LocalStatusIndex( stat ) );
 
-    // find message, iterating by base classes if necessary
-    TCollection_AsciiString aMsgName = aClassName + aSuffix;
-    Handle(Standard_Type) aType = DynamicType();
-    while (! Message_MsgFile::HasMsg(aMsgName) && !aType.IsNull())
+    // find message, prefixed by class type name, iterating by base classes if necessary
+    TCollection_AsciiString aMsgName;
+    for (Handle(Standard_Type) aType = DynamicType(); ! aType.IsNull(); aType = aType->Parent())
     {
-      Standard_AncestorIterator it(aType);
-      aType.Nullify();
-      for (; it.More(); it.Next())
-      {
-        aType = it.Value();
-        TCollection_AsciiString aClassName1 (aType->Name());
-        TCollection_AsciiString aMsgName1 = aClassName1 + aSuffix;
-        if (Message_MsgFile::HasMsg(aMsgName1))
-        {
-          aMsgName = aMsgName1;
-          break;
-        }
-      }
+      aMsgName = aType->Name();
+      aMsgName += aSuffix;
+      if (Message_MsgFile::HasMsg(aMsgName))
+        break;
     }
 
     // create a message
index fab78fe..3edeefa 100644 (file)
 // commercial license or contractual agreement.
 
 #include <NCollection_Handle.hxx>
-
-// NOTE: OCCT type information functions are defined explicitly
-// instead of using macros from Standard_DefineHandle.hxx,
-// since class NCollection_Handle is template and this is not supported 
-
-static Handle(Standard_Type) aTypeNCollection_Handle = 
-       STANDARD_TYPE(NCollection_Handle);
-
-const Handle(Standard_Type)& STANDARD_TYPE(NCollection_Handle)
-{
-  static Handle(Standard_Transient) _Ancestors[] = 
-    { STANDARD_TYPE(Standard_Transient), NULL, };
-  static Handle(Standard_Type) _aType = 
-    new Standard_Type("NCollection_Handle", 
-                      sizeof(NCollection_Handle<Standard_Transient>),
-                      1, (Standard_Address)_Ancestors, (Standard_Address)NULL);
-  return _aType;
-}
index d33bcfb..8bf7844 100644 (file)
@@ -17,9 +17,6 @@
 #define NCollection_Handle_HeaderFile
 
 #include <MMgt_TShared.hxx>
-
-//! Standard type function allowing to check that contained object is Handle
-Standard_EXPORT const Handle(Standard_Type)& STANDARD_TYPE(NCollection_Handle);
   
 //! Purpose: This template class is used to define Handle adaptor
 //! for allocated dynamically objects of arbitrary type.
@@ -28,20 +25,6 @@ Standard_EXPORT const Handle(Standard_Type)& STANDARD_TYPE(NCollection_Handle);
 //! the object when last referred Handle is destroyed (i.e. it is a 
 //! typical smart pointer), and that it can be handled as 
 //! Handle(Standard_Transient) in OCCT components.
-//!
-//! Use it as follows:
-//!
-//! NCollection_Handle<T> aPtr = new T (...);
-//!
-//! aPtr->Method(...);
-//!
-//! Handle(Standard_Transient) aBase = aPtr;
-//! if ( aBase->IsKind(STANDARD_TYPE(NCollection_Handle)) )
-//! {
-//!   NCollection_Handle<T> aPtr2 = NCollection_Handle<T>::DownCast (aBase);
-//!   if ( ! aPtr2.IsNull() )
-//!     aPtr2->Method2();
-//! }
 
 template <class T>
 class NCollection_Handle : public Handle(Standard_Transient)
@@ -61,10 +44,6 @@ class NCollection_Handle : public Handle(Standard_Transient)
     //! Destructor deletes the object
     ~Ptr () { if ( myPtr ) delete myPtr; myPtr = 0; }
 
-    //! Implementation of DynamicType() method
-    const Handle(Standard_Type)& DynamicType() const 
-      { return STANDARD_TYPE(NCollection_Handle); }
-
   protected:
 
     //! Copy constructor
@@ -108,10 +87,11 @@ class NCollection_Handle : public Handle(Standard_Transient)
   
   //! Downcast arbitrary Handle to the argument type if contained
   //! object is Handle for this type; returns null otherwise
-  static NCollection_Handle<T> DownCast (const Handle(Standard_Transient)& theOther) 
+  static NCollection_Handle<T> DownCast (const Handle(Standard_Transient)& theOther)
   {
-    return NCollection_Handle<T> (theOther.IsNull() ? 0 : dynamic_cast<Ptr*> (theOther.operator->()), 0);
+    return NCollection_Handle<T>(dynamic_cast<Ptr*>(theOther.get()), 0);
   }
+
 };
 
 #endif
index 32c028d..dfd2632 100644 (file)
@@ -14,7 +14,5 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#define _Precision_SourceFile
-
 #include <Precision.ixx>
 
index e59069c..f1515d6 100644 (file)
@@ -30,6 +30,7 @@
 #include <Prs3d_PlaneAspect.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
+#include <PrsMgr_PresentableObjectPointer.hxx>
 
 #include <TopLoc_Location.hxx>
 #include <gp_Pnt.hxx>
@@ -108,6 +109,9 @@ void SelectMgr_SelectableObject::RecomputePrimitives()
 //==================================================
 void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer theMode)
 {
+  Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
+  Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
+
   for (Standard_Integer aSelIdx =1; aSelIdx <= myselections.Length(); aSelIdx++ )
   {
     if (myselections.Value (aSelIdx)->Mode() == theMode)
@@ -116,9 +120,9 @@ void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer the
       ComputeSelection (myselections (aSelIdx), theMode);
       myselections (aSelIdx)->UpdateStatus (SelectMgr_TOU_Partial);
       myselections (aSelIdx)->UpdateBVHStatus (SelectMgr_TBU_Renew);
-      if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && theMode == 0)
+      if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
       {
-        SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), theMode);
+        SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
       }
       return;
     }
@@ -127,9 +131,9 @@ void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer the
   Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
   ComputeSelection (aNewSel, theMode);
 
-  if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && theMode == 0)
+  if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
   {
-    SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), theMode);
+    SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
   }
 
   aNewSel->UpdateStatus (SelectMgr_TOU_Partial);
@@ -207,9 +211,14 @@ void SelectMgr_SelectableObject
     myselections.Last()->UpdateBVHStatus (SelectMgr_TBU_Renew);
   }
 
-  if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && aMode == 0)
+  if (aMode == 0)
   {
-    SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), aMode);
+    Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
+    Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
+    if (! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
+    {
+      SetAssemblyOwner (aSelParent->GetAssemblyOwner(), aMode);
+    }
   }
 }
 
index 61185c3..ad50300 100755 (executable)
@@ -43,8 +43,11 @@ Standard_ShortReal.hxx
 Standard_Stream.hxx
 Standard_Time.hxx
 Standard_Transient.hxx
+Standard_Transient.cxx
 Standard_Transient_proto.hxx
 Standard_TypeDef.hxx
+Standard_Type.hxx
+Standard_Type.cxx
 Standard_math.cxx
 Standard_math.hxx
 Standard_values.h
index 44c48bd..e1c10af 100644 (file)
 
 #include <Standard_Persistent.hxx>
 
-
-
-Handle(Standard_Persistent)& Handle(Standard_Persistent)::operator=
-       (const Handle(Standard_Persistent)& aHandle)
-     {
-      Assign(aHandle.Access());
-      return *this;
-     }
-
-
-
-Handle(Standard_Persistent)& Handle(Standard_Persistent)::operator=
-(const Standard_Persistent* anItem)
-     {
-      Assign((const Standard_Persistent *)anItem);
-      return *this;
-     }
-
index 9ad299f..20dc6f5 100644 (file)
 #ifndef _Handle_Standard_Persistent_HeaderFile
 #define _Handle_Standard_Persistent_HeaderFile
 
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_TypeDef.hxx>
+#include <Standard_DefineHandle.hxx>
 #include <Standard_Persistent_proto.hxx>
 
-#ifdef _WIN32
-// Disable the warning "conversion from 'unsigned int' to Standard_Persistent *"
-#pragma warning (push)
-#pragma warning (disable:4312)
-#endif
-
-class Standard_Persistent;
-class Handle_Standard_Type;
-class Handle_Standard_Persistent;
-
-Standard_EXPORT Standard_Integer HashCode(const Handle(Standard_Persistent)& ,
-                                          const Standard_Integer);
-
-class Handle(Standard_Persistent)
- {
-   private:
-
-    Standard_Persistent *entity;
-
-    Standard_EXPORT void RaiseNullObject(const Standard_CString S) const;
-
-    void BeginScope() const
-      {
-       if (entity != 0) entity->count++;
-      }    
-
-    void EndScope()
-      {
-       if (entity != 0) 
-         {
-          entity->count--;
-          if (entity->count == 0) {
-           entity->Delete();
-           entity = 0 ;
-         }
-       }
-      }
-
-
-   public:
-
-    DEFINE_STANDARD_ALLOC
-
-    Handle(Standard_Persistent)()
-      {
-       entity = 0 ;
-      }
-
-    Handle(Standard_Persistent)(const Handle(Standard_Persistent)& aTid) 
-      {
-       entity = aTid.entity;
-       BeginScope();
-      } 
-
-    Handle(Standard_Persistent)(const Standard_Persistent *anItem)
-      {
-       if (!anItem)
-           entity = 0 ;
-       else {
-        entity = (Standard_Persistent *)anItem;
-        BeginScope();
-       }
-      }
-
-     Standard_EXPORT void Dump(Standard_OStream& out) const;
-
-    Standard_EXPORT ~Handle(Standard_Persistent)();
-
-    bool operator==(const Handle(Standard_Persistent)& right) const
-      {
-       return entity == right.entity;
-      }
-
-    bool operator==(const Standard_Persistent *right) const
-      {
-       return entity == right;
-      }
-
-    friend bool operator==(const Standard_Persistent *left, const Handle(Standard_Persistent)& right)
-      {
-       return left == right.entity;
-      }
-
-    bool operator!=(const Handle(Standard_Persistent)& right) const
-      {
-       return entity != right.entity;
-      }
+DEFINE_STANDARD_HANDLE(Standard_Persistent, Standard_Transient)
 
-    bool operator!=(const Standard_Persistent *right) const
-      {
-       return entity != right;
-      }
-
-    friend bool operator!=(const Standard_Persistent *left, const Handle(Standard_Persistent)& right)
-      {
-       return left != right.entity;
-      }
-
-    void Nullify()
-      {
-       EndScope();
-       entity =  0 ;
-      }
-
-    Standard_Boolean IsNull() const
-      {
-       return entity == 0 ;
-      } 
-
-    Standard_Persistent* Access() const
-      {
-       return entity;
-      } 
-
-   protected:
-
-    Standard_Persistent* ControlAccess() const
-      {
-       return entity;
-      } 
-
-    void Assign(const Standard_Persistent *anItem)
-      {
-       EndScope();
-       if (!anItem)
-           entity = 0 ;
-       else {
-        entity = (Standard_Persistent *)anItem;
-        BeginScope();
-       }
-      }
-
-
-  public:
-
-   operator Standard_Persistent*()
-     {
-       return Access();
-     }
-
-
-   Standard_EXPORT Handle(Standard_Persistent)& operator=(const Handle(Standard_Persistent)& aHandle);
-   Standard_EXPORT Handle(Standard_Persistent)& operator=(const Standard_Persistent* anItem);
-
-   Standard_Persistent* operator->() 
-     {
-      return ControlAccess();
-     }
-
-   Standard_Persistent* operator->() const
-     {
-      return ControlAccess();
-     }
-
-   Standard_Persistent& operator*()
-     {
-      return *(ControlAccess());
-     }
-
-   const Standard_Persistent& operator*() const
-     {
-      return *(ControlAccess());
-     }
-
-   Standard_EXPORT static const Handle(Standard_Persistent) DownCast(const Handle(Standard_Persistent)& AnObject);
-};
-
-class Standard_Type;
-
-#ifdef _WIN32
-#pragma warning (pop)
-#endif
+Standard_EXPORT Standard_Integer HashCode(const Handle(Standard_Persistent)&, const Standard_Integer);
 
 #endif
index 0809fd6..1ca48bc 100644 (file)
@@ -127,6 +127,12 @@ public:
     return entity;
   }
 
+  //! STL-style member accessor
+  Standard_Transient* get() const
+  {
+    return entity;
+  }
+
   //! Dereferencing operator
   Standard_Transient& operator*()
   {
index f3f468a..af8a7df 100644 (file)
@@ -28,24 +28,6 @@ package Standard
 
 
 is
-    enumeration InternalType is
-               Void,          -- TYPUND     0x00000000  /* Undefined    */
-               Char,          -- TYPIT1     0x00010001  /* Byte         */
-               ExtChar,       -- TYPIT2     0x00020001  /* Integer*2    */
-               LongInt,       -- TYPIT4     0x00040001  /* Integer*4    */
-               Bool,          -- TYPLO4     0x00040002  /* Logical*4    */
-               Float,         -- TYPRE4     0x00040004  /* Real*4       */
-               LongDouble,    -- TYPRE8     0x00080004  /* Real*8       */
-               String,        -- TYPCHR     0x00000010  /* Character    */
-               EString,       -- TYPCHREXT  0x00000011  /* Character    */
-               EntryAddress,  -- TYPENT     0x00040020  /* Function address */
-               DataAddress,   -- TYPDAD     0x00040080  /* Data address */
-               EngineHandle,  -- TYPHDLE    0x00004000  /* Handle       */
-               Long64,        -- TYPIT8     0x00080001  /* Integer*8    */
-               Array;         -- TYPARR     0x00008000  /* Tableau      */
-
-    enumeration WayOfLife is IsNothing, IsAddress, IsTransient, IsPersistent, IsNotLoaded;
-    enumeration KindOfType is IsUnKnown, IsClass, IsEnumeration, IsPrimitive, IsImported, IsPackage;
     enumeration HandlerStatus is HandlerVoid, HandlerJumped, HandlerProcessed;
 
     imported IStream;
@@ -71,8 +53,6 @@ is
     deferred class ErrorHandlerCallback;
     class ErrorHandler;
     
-    class AncestorIterator;
-    
     primitive Boolean;
     primitive Character;
     primitive ExtCharacter;
@@ -87,8 +67,8 @@ is
 
     deferred class Persistent ;
 
-    deferred class Transient ;
-           class Type; -- inherits Transient
+    imported deferred class Transient ;
+           imported transient class Type; -- inherits Transient
            class Failure; --  inherits Transient
                exception AbortiveTransaction inherits Failure;
                exception DomainError inherits Failure;
diff --git a/src/Standard/Standard_AncestorIterator.cdl b/src/Standard/Standard_AncestorIterator.cdl
deleted file mode 100644 (file)
index 6ace930..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
--- Created on: 1992-08-24
--- Created by: Ramin BARRETO
--- Copyright (c) 1992-1999 Matra Datavision
--- Copyright (c) 1999-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.
-
-class AncestorIterator from Standard
-    ---Purpose:
-    -- The class <AncestorIterator> is a iterator which provides 
-    -- information about inheritance. 
-    -- An AncestorIterator object is used to scan sequentially the 
-    -- hierarchy of a type object from its direct super-type to the root.
-    --
-    -- Warning:
-    --   The near parents are first.
-    --   
-uses 
-    Boolean from Standard
-   ,Integer from Standard
-   ,Type from Standard
-
-raises 
-    NoMoreObject from Standard
-   
-is
-
-    ------------------------------------------------------------------------
-    ---Category: The Constructur of AncestorIterator.
-    ------------------------------------------------------------------------
-    Create(anOther: AncestorIterator )  returns AncestorIterator;
-    ---Purpose:
-    --   The copy constructor for a AncestorIterator . 
-    --   
-    ---Level: Advanced    
-       
-    Create(aType: Type) returns AncestorIterator;
-    ---Purpose: 
-    --   Creates an iterator on the type <aType>.
-    --   Set the iterator at the beginning of the ancestors; 
-    --   this means near parents are first.
-    ---Level: Advanced  
-   
-    ------------------------------------------------------------------------
-    ---Category: Assignation.
-    ------------------------------------------------------------------------
-    Assign(me: in out; anOther: AncestorIterator); 
-    ---Purpose:
-    --   Assigns an  AncestorIterator from another AncestorIterator.
-    --
-    ---C++: alias operator =        
-    ---Level: Advanced        
-          
-    ------------------------------------------------------------------------
-    ---Category: The methods for iterating.
-    ------------------------------------------------------------------------
-
-    More(me) returns Boolean;
-    ---Purpose: 
-    -- Returns True if there are other ancestors.
-    --
-    -- Example:
-    --
-    -- Handle(Standard_Type) type;
-    -- Standard_AncestorIterator super(TYPE(Geom_Circle));
-    -- while(super.More()) { type = super.Value();
-    --      super.Next();
-    -- }  
-
-    Next(me: in out) 
-    ---Purpose: 
-    -- Moves the position of the iterator to the next super-type. 
-    -- If the current position corresponds to a root class, it becomes undefined.
-    --
-    -- Exceptions:
-    -- Standard_NoMoreObject if the position of the iterator is undefined
-    raises NoMoreObject; -- If there are no more ancestors.
-    ---Level: Advanced  
-          
-    ------------------------------------------------------------------------
-    ---Category: The information of each ancestor.
-    ------------------------------------------------------------------------
-
-    Iterator(me) returns AncestorIterator
-    ---Purpose: 
-    --   Returns an <AncestorIterator> corresponding to the current position 
-    --   of the iterator.
-    raises NoMoreObject; -- If there are no more Ancestors.
-    ---Level: Advanced  
-
-    Value(me) returns Type 
-    ---Purpose:
-    -- Returns the type corresponding to the current position of 
-    -- the iterator.
-    --
-    -- Example:
-    --
-    -- Standard_AncestorIterator super(TYPE(Geom_Circle));
-    -- assert (super.Value() == TYPE(Geom_Conic));
-    --
-    -- Exceptions:
-    -- Standard_NoSuchObject if the position of the iterator is undefined.
-    raises NoMoreObject; -- If there are no more ancestors.
-   
-fields
-
-    myType  : Type;
-    myNbIter: Integer;
-   
-end AncestorIterator from Standard;
diff --git a/src/Standard/Standard_AncestorIterator.cxx b/src/Standard/Standard_AncestorIterator.cxx
deleted file mode 100644 (file)
index 697349b..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-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 <Standard_AncestorIterator.ixx>
-#include <Standard_NoMoreObject.hxx>
-
-//============================================================================
-Standard_AncestorIterator::Standard_AncestorIterator
-  (const Standard_AncestorIterator& anOther)
-{
-  myType   = anOther.myType;
-  myNbIter = anOther.myNbIter;
-}
-
-//============================================================================
-Standard_AncestorIterator::Standard_AncestorIterator
-  (const Handle(Standard_Type)& aType)
-{
-  myType = aType;
-  myNbIter = 0;
-}
-
-//============================================================================
-void Standard_AncestorIterator::Assign
-  (const Standard_AncestorIterator& anOther)
-{
-  myType   = anOther.myType;
-  myNbIter = anOther.myNbIter;
-}
-
-//============================================================================
-Standard_Boolean Standard_AncestorIterator::More() const
-{
-  return (myNbIter < myType->NumberOfAncestor());
-}
-
-//============================================================================
-void Standard_AncestorIterator::Next() 
-{
-  Standard_NoMoreObject_Raise_if(myNbIter == myType->NumberOfAncestor(),
-                                "Standard_AncestorIterator::Next()");
-  myNbIter++;
-}
-
-//============================================================================
-Standard_AncestorIterator Standard_AncestorIterator::Iterator() const
-{
-  Handle(Standard_Type) aType, *allAncestors;
-
-  Standard_NoMoreObject_Raise_if(myNbIter == myType->NumberOfAncestor(),
-                                "Standard_AncestorIterator::Next()");
-  
-  allAncestors = (Handle(Standard_Type) *) myType->Ancestors();
-  aType = allAncestors[myNbIter];
-
-  return Standard_AncestorIterator(aType); 
-}
-
-//============================================================================
-Handle(Standard_Type) Standard_AncestorIterator::Value() const
-{
-  Handle(Standard_Type) aType, *allAncestors;
-
-  Standard_NoMoreObject_Raise_if(myNbIter == myType->NumberOfAncestor(),
-                                "Standard_AncestorIterator::Next()");
-  
-  allAncestors = (Handle(Standard_Type) *) myType->Ancestors();
-  aType = allAncestors[myNbIter];
-
-  return aType; 
-}
-
index b55009b..bc8b5c6 100755 (executable)
@@ -18,7 +18,7 @@
 //          resizing of a Map or copying an item from a Map to another Map.
 //        - three methods of HashCoding of strings converted to uppercase.
 
-#define _Standard_CString_SourceFile
+#include <Standard_Type.hxx>
 
 #include <Standard_CLocaleSentry.hxx>
 #include <Standard_CString.hxx>
index aa34568..61e99c8 100644 (file)
@@ -14,8 +14,7 @@
 #ifndef _Standard_DefineException_HeaderFile
 #define _Standard_DefineException_HeaderFile
 
-#include <Standard_Macro.hxx>
-#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
 
 //! Defines an exception class \a C1 that inherits an exception class \a C2.
 /*! \a C2 must be Standard_Failure or its ancestor.
 
     When using DEFINE_STANDARD_EXCEPTION in your code make sure you also insert a macro
     DEFINE_STANDARD_HANDLE(C1,C2) before it.
-
-    \sa IMPLEMENT_STANDARD_EXCEPTION.
 */
+
 #define DEFINE_STANDARD_EXCEPTION(C1,C2) \
  \
 class C1 : public C2 { \
-  Standard_EXPORT virtual void Throw() const; \
+  void Throw () const { throw *this; } \
 public: \
   C1() : C2() {} \
-  C1(const Standard_CString AString) : C2(AString) {} \
-  Standard_EXPORT static void Raise(const Standard_CString aMessage = ""); \
-  Standard_EXPORT static void Raise(Standard_SStream& aReason); \
-  Standard_EXPORT static Handle(C1) NewInstance(const Standard_CString aMessage = ""); \
- \
-  DEFINE_STANDARD_RTTI(C1) \
+  C1(const Standard_CString theMessage) : C2(theMessage) {} \
+  static void Raise(const Standard_CString theMessage = "") { \
+    Handle(C1) _E = new C1; \
+    _E->Reraise(theMessage); \
+  } \
+  static void Raise(Standard_SStream& theMessage) { \
+    Handle(C1) _E = new C1; \
+    _E->Reraise (theMessage); \
+  } \
+  static Handle(C1) NewInstance(const Standard_CString theMessage = "") { return new C1(theMessage); } \
+  DEFINE_STANDARD_RTTI(C1,C2) \
 };
 
-
-//! Implements an exception class \a C1 declared with DEFINE_STANDARD_EXCEPTION macro.
-/*! If you are using IMPLEMENT_STANDARD_EXCEPTION in your code make sure you also call
-    IMPLEMENT_STANDARD_HANDLE(C1,C2) and IMPLEMENT_STANDARD_RTTIEXT(C1,C2).
-*/
-#define IMPLEMENT_STANDARD_EXCEPTION(C1) \
- \
-void C1::Raise(Standard_SStream& aReason) \
-{ \
-  Handle(C1) _E = new C1; \
-  _E->Reraise (aReason); \
-} \
- \
-void C1::Raise(const Standard_CString AString) \
-{ \
-  Handle(C1) _E = new C1; \
-  _E->Reraise(AString); \
-} \
- \
-Handle(C1) C1::NewInstance(const Standard_CString aMessage) \
-{ \
-  return new C1(aMessage); \
-} \
-void C1::Throw () const \
-{ \
-  throw *this; \
-}
+//! Obsolete macro, kept for compatibility with old code
+#define IMPLEMENT_STANDARD_EXCEPTION(C1) 
 
 #endif
index e7c518e..37d53e9 100644 (file)
 
 #include <Standard_Macro.hxx>
 
+//! @file
+//! This file provides low-level helper macros for definition of OCCT handles and types.
+//! It is not to be included in the user code  directly; include Standard_Type.hxx instead.
+
 class Standard_Transient;
 class Standard_Persistent;
-class Handle_Standard_Type;
+class Standard_Type;
 
-// COMMON
-//
-#define IMPLEMENT_DOWNCAST(C1,BC) \
-Handle(C1) Handle(C1)::DownCast(const Handle(BC)& AnObject)  \
-{ \
-  Handle(C1) _anOtherObject; \
- \
-  if (!AnObject.IsNull()) { \
-    if (AnObject->IsKind(STANDARD_TYPE(C1))) { \
-      _anOtherObject = Handle(C1)((Handle(C1)&)AnObject); \
-    } \
-  } \
- \
-  return _anOtherObject ; \
+// Forward declarations of auxiliary template class for type descriptor instantiation
+// and down casting function; defined in Standard_Type.hxx
+namespace opencascade {
+  template <typename T> class type_instance;
+  template <class H1, class H2>  H1 down_cast (const H2& theObject);
 }
 
+//! Helper macro to get instance of a type descriptor for a class in a legacy way.
+#define STANDARD_TYPE(theType) Standard_Type::Instance<theType>()
+
+//! Helper macro to be included in definition of the classes inheriting
+//! Standard_Transient to enable use of OCCT RTTI and smart pointers (handles).
+#define DEFINE_STANDARD_RTTI(Class,Base) \
+public: \
+  typedef Base base_type; \
+  static const char* get_type_name () { return #Class; } \
+  virtual const Handle(Standard_Type)& DynamicType() const { return STANDARD_TYPE(Class); }
+
+//! Define OCCT Handle for a class C1 inheriting C2, 
+//! with BC being a root of the hierarchy
 #define DEFINE_STANDARD_HANDLECLASS(C1,C2,BC) \
 class C1; \
-Standard_EXPORT const Handle(Standard_Type)& STANDARD_TYPE(C1); \
- \
 class Handle(C1) : public Handle(C2) { \
 public: \
   typedef C1 element_type;\
   \
-  Handle(C1)():Handle(C2)() {} \
-  \
+  Handle(C1)() {} \
   Handle(C1)(const Handle(C1)& aHandle) : Handle(C2)(aHandle) {} \
-  \
   Handle(C1)(const C1* anItem) : Handle(C2)((C2 *)anItem) {} \
   \
   Handle(C1)& operator=(const Handle(C1)& aHandle) \
@@ -56,81 +60,41 @@ public: \
     Assign(aHandle.Access()); \
     return *this; \
   } \
-  \
   Handle(C1)& operator=(const C1* anItem) \
   { \
-    Assign((BC *)anItem); \
+    Assign((BC*)anItem); \
     return *this; \
   } \
   \
-  C1& operator*() const \
-  { \
-    return *(C1 *)ControlAccess(); \
-  } \
+  C1& operator*() const { return *(C1 *)ControlAccess(); } \
+  C1* operator->() const { return (C1 *)ControlAccess(); } \
+  C1* get() const { return (C1 *)ControlAccess(); } \
   \
-  C1* operator->() const \
+  template <class HBC> \
+  static Handle(C1) DownCast(const HBC& theObject) \
   { \
-    return (C1 *)ControlAccess(); \
+    return opencascade::down_cast <Handle(C1), HBC> (theObject); \
   } \
-  \
-  Standard_EXPORT static Handle(C1) DownCast(const Handle(BC)& AnObject); \
 };
 
 // TRANSIENT
 //
 #define DEFINE_STANDARD_HANDLE(C1,C2) DEFINE_STANDARD_HANDLECLASS(C1,C2,Standard_Transient)
 
-#define IMPLEMENT_STANDARD_HANDLE(C1,C2) IMPLEMENT_DOWNCAST(C1,Standard_Transient)
-
 // PERSISTENT
 //
 #define DEFINE_STANDARD_PHANDLE(C1,C2) DEFINE_STANDARD_HANDLECLASS(C1,C2,Standard_Persistent)
 
-#define IMPLEMENT_STANDARD_PHANDLE(C1,C2) IMPLEMENT_DOWNCAST(C1,Standard_Persistent)
-
-// TYPE MANAGEMENT
-//
-#define DEFINE_STANDARD_RTTI(C1) \
-Standard_EXPORT virtual const Handle(Standard_Type)& DynamicType() const;
-
-#define IMPLEMENT_STANDARD_RTTI(C1) \
-const Handle(Standard_Type)& C1::DynamicType() const \
-{ \
-  return STANDARD_TYPE(C1); \
-}
-
-#define IMPLEMENT_STANDARD_TYPE(C1) \
-static Handle(Standard_Type) aType##C1 = STANDARD_TYPE(C1); \
- \
-const Handle(Standard_Type)& STANDARD_TYPE(C1) \
-{
-
-#define IMPLEMENT_STANDARD_SUPERTYPE(Cn) /* Left to ensure source compatibility with Open CASCADE 6.3 and earlier */
-
-#define IMPLEMENT_STANDARD_SUPERTYPE_ARRAY() \
-static Handle(Standard_Transient) _Ancestors[]= {
-
-#define IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(Cn) \
-  STANDARD_TYPE(Cn),
-
-#define IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_END() \
-  NULL \
-};
-
-#define IMPLEMENT_STANDARD_TYPE_END(C1) \
-static Handle(Standard_Type) _aType = new Standard_Type(#C1,sizeof(C1),1, \
-                                                        (Standard_Address)_Ancestors, \
-                                                        (Standard_Address)NULL); \
-  return _aType; \
-}
-
-#define IMPLEMENT_STANDARD_RTTIEXT(C1,C2) \
-IMPLEMENT_STANDARD_RTTI(C1) \
-IMPLEMENT_STANDARD_TYPE(C1) \
-IMPLEMENT_STANDARD_SUPERTYPE(C2) \
-IMPLEMENT_STANDARD_SUPERTYPE_ARRAY() \
-IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(C2) \
-IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_END() \
-IMPLEMENT_STANDARD_TYPE_END(C1)
+// Obsolete macros kept for compatibility
+#define IMPLEMENT_DOWNCAST(C1,BC)
+#define IMPLEMENT_STANDARD_HANDLE(C1,C2)
+#define IMPLEMENT_STANDARD_PHANDLE(C1,C2)
+#define IMPLEMENT_STANDARD_RTTI(C1)
+#define IMPLEMENT_STANDARD_TYPE(C1)
+#define IMPLEMENT_STANDARD_SUPERTYPE(Cn)
+#define IMPLEMENT_STANDARD_SUPERTYPE_ARRAY()
+#define IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_END()
+#define IMPLEMENT_STANDARD_TYPE_END(C1)
+#define IMPLEMENT_STANDARD_RTTIEXT(C1,C2)
 
 #endif
index 6890cb4..0a1563d 100644 (file)
@@ -94,7 +94,7 @@ is
        --          dangerous since some of methods require that object
        --          was allocated dynamically.
        
-    Jump (me);
+    Jump (me: mutable);
        ---Purpose: Used to throw CASCADE exception from C signal handler.
         --          On platforms that do not allow throwing C++ exceptions 
         --          from this handler (e.g. Linux), uses longjump to get to 
index 622dbe1..f164d53 100644 (file)
@@ -152,7 +152,7 @@ void Standard_Failure::Reraise ()
 #endif
 }
 
-void Standard_Failure::Jump() const 
+void Standard_Failure::Jump()
 {
 #if defined (NO_CXX_EXCEPTION) || defined (OCC_CONVERT_SIGNALS)
   Standard_ErrorHandler::Error (this);
index 4923a46..5e94dec 100644 (file)
 #include <Standard_RangeError.hxx>
 
 //============================================================================
-Standard_EXPORT Standard_Integer HashCode(const Standard_Address me,const Standard_Integer Upper,const Handle(Standard_Type)& aType)
-{
-  char             *mecharPtr;
-  Standard_Integer *meintPtr = (Standard_Integer *) me;
-  Standard_Integer aHashCode, aRest, i, aSize = aType->Size();
-  
-  Standard_RangeError_Raise_if (Upper < 1,
-      "Try to apply HashCode method with negative or null argument.");
-
-  aRest = aSize % sizeof(Standard_Integer);
-
-  aHashCode = 0;
-
-  if (aSize == 0) 
-    aHashCode = (Standard_Integer) ptrdiff_t(me);
-
-
-  for (i = 0;  (unsigned int ) i < aSize / sizeof(Standard_Integer); i++)
-  {
-    aHashCode = aHashCode ^ *meintPtr;
-    meintPtr++;
-  }
-  
-  mecharPtr = (char *) meintPtr;
-
-  for (i = 0; i < aRest; i++) 
-  {
-    aHashCode = aHashCode ^ *mecharPtr;
-    mecharPtr++;
-  }
-
-
-  return HashCode( aHashCode , Upper) ;
-}
-
-//============================================================================
 Standard_EXPORT Standard_Integer HashCode (const Handle(Standard_Transient)& me,
                                            const Standard_Integer Upper )
 {
index 869f935..dd3ede3 100644 (file)
@@ -21,7 +21,6 @@
 
 // Standard OCC macros: Handle(), STANDARD_TYPE()
 # define   Handle(ClassName)      Handle_##ClassName
-# define   STANDARD_TYPE(aType)   aType##_Type_()
 
 #if defined(__cplusplus) && (__cplusplus >= 201100L)
   // part of C++11 standard
index 7a3c000..e1c10af 100644 (file)
 
 #include <Standard_Persistent.hxx>
 
-#include <Standard_Failure.hxx>
-#include <Standard_NullObject.hxx>
-#include <Standard_RangeError.hxx>
-#include <Standard_ImmutableObject.hxx>
-#include <Standard_TypeMismatch.hxx>
-#include <Standard_NotImplemented.hxx>
-#include <Standard_Type.hxx>
-
-// The Initialization of the Standard_Persistent variables
-const Handle(Standard_Type)& Standard_Persistent_Type_() 
-{
-  static const Handle(Standard_Type) _Ancestors[]={NULL};
-  static Handle(Standard_Type) _aType 
-    = new Standard_Type("Standard_Persistent",
-                       sizeof(Standard_Persistent),
-                       0,
-     (Standard_Address) _Ancestors,
-                       NULL);
-
-  return _aType;
-}
-
-//
-// The Standard_Persistent Methods
-//
-
-// The Method This 
-//
-Handle(Standard_Persistent) Standard_Persistent::This() const
-{
-  Handle(Standard_Persistent) aHand(this);
-
-  return aHand;
-}
-
-// Empty Destructor
-//
-Standard_Persistent::~Standard_Persistent()
-{
-}
-
-// Operator= with a Standard_Persistent
-//
-Standard_Persistent& Standard_Persistent::operator=(const Standard_Persistent& )
-{ 
-  return *this;
-}
-
-//
-//
-Standard_Boolean Standard_Persistent::IsInstance(const Handle(Standard_Type)
-                                               &AType) const
-{
-  return (Standard_Boolean) (AType ==  DynamicType());
-}
-
-//
-//
-const Handle(Standard_Type)& Standard_Persistent::DynamicType () const
-{  
-  return  STANDARD_TYPE(Standard_Persistent);
-}
-
-//
-//
-Standard_Boolean Standard_Persistent::IsKind (const Handle(Standard_Type)& aType) const
-{
-  return DynamicType()->SubType ( aType );
-//  return  (aType == STANDARD_TYPE(Standard_Persistent));
-}
-
-void Standard_Persistent::Delete() const
- { 
-   delete((Standard_Persistent *)this); 
- }
-
-const Handle(Standard_Persistent) Handle(Standard_Persistent)::DownCast(const Handle(Standard_Persistent)& AnObject) 
-{
-  Handle(Standard_Persistent) _anOtherObject;
-  
-  if (!AnObject.IsNull()) 
-    if (AnObject->IsKind(STANDARD_TYPE(Standard_Persistent))) 
-      {
-       _anOtherObject = Handle(Standard_Persistent)((Handle(Standard_Persistent)&)AnObject);
-      }
-  
-  return _anOtherObject ;
-}
-
-Handle(Standard_Persistent)::~Handle(Standard_Persistent)()
-{
- EndScope();
-}
-
-void Handle(Standard_Persistent)::RaiseNullObject(const Standard_CString S) const
-{ 
-  Standard_NullObject::Raise(S);
-}
-
-void Handle(Standard_Persistent)::Dump(Standard_OStream& out) const
-{ 
-  out << ControlAccess();
-}
-
-
index a73b70f..499536e 100644 (file)
@@ -16,7 +16,7 @@
 #define _Standard_Persistent_proto_HeaderFile
 
 #include <Standard.hxx>
-#include <Standard_TypeDef.hxx>
+#include <Standard_Type.hxx>
 #include <Standard_OStream.hxx>
 
 class Standard_Type;
@@ -25,43 +25,25 @@ class Handle_Standard_Persistent;
 class Standard_Type;
 
 class Storage_stCONSTclCOM;
-Standard_EXPORT const Handle_Standard_Type& Standard_Persistent_Type_();
 
-class Standard_Persistent
+class Standard_Persistent : public Standard_Transient
 {
 friend class Handle(Standard_Persistent);
 friend class Storage_Schema;
 
 private:
-  Standard_Integer count;
   Standard_Integer _typenum;
   Standard_Integer _refnum;
 public:
   
-  DEFINE_STANDARD_ALLOC
+  Standard_Persistent& operator= (const Standard_Persistent&) { return *this; }
+  Standard_Persistent() : _typenum(0),_refnum(0) {}
+  Standard_Persistent(const Standard_Persistent&) : _typenum(0),_refnum(0) {}
+  Standard_Persistent(const Storage_stCONSTclCOM&) : _typenum(0),_refnum(0) {}
 
-  Standard_EXPORT virtual Handle_Standard_Persistent This() const;
-  Standard_EXPORT virtual void Delete() const;
-  Standard_EXPORT virtual ~Standard_Persistent();
-  
-  Standard_EXPORT Standard_Persistent& operator= (const Standard_Persistent&);
-                  Standard_Persistent() : count(0),_typenum(0),_refnum(0) {}
-                  Standard_Persistent(const Standard_Persistent&) : count(0),_typenum(0),_refnum(0) {}
-                  Standard_Persistent(const Storage_stCONSTclCOM&) : count(0),_typenum(0),_refnum(0) {}
-
-  Standard_EXPORT virtual const Handle_Standard_Type& DynamicType() const;
-  Standard_EXPORT         Standard_Boolean            IsKind(const Handle_Standard_Type&)const;
-  Standard_EXPORT         Standard_Boolean            IsInstance(const Handle_Standard_Type&)const;  
+  DEFINE_STANDARD_RTTI(Standard_Persistent,Standard_Transient)
 };
 
 #include <Handle_Standard_Persistent.hxx>
 
 #endif
-
-
-
-
-
-
-
-
index 342f661..9a5b19c 100644 (file)
 #include <stddef.h>
 #include <stdlib.h>
 
-class Standard_Type;
-class Handle_Standard_Type;
-
-class Handle_Standard_Transient;
-class Standard_Transient;
-
 #include <Standard_Macro.hxx>
 
 #include <Standard_Boolean.hxx>
@@ -35,18 +29,4 @@ class Standard_Transient;
 #include <Standard_ExtString.hxx>
 #include <Standard_Address.hxx>
 
-__Standard_API Standard_Integer HashCode(const Standard_Address, 
-                         const Standard_Integer,
-                         const Handle_Standard_Type&);
-
 #endif
-
-
-
-
-
-
-
-
-
-
index 1c4d9c5..7abf1da 100644 (file)
@@ -21,8 +21,6 @@
 #include <Standard_values.h>
 #include <Standard_TypeDef.hxx>
 
-class Handle_Standard_Type;
-
          //  *********************************** //
          //       Class methods                  //
          //                                      //
index a7f6aad..cf41d1d 100644 (file)
@@ -14,7 +14,7 @@
 -- Alternatively, this file may be used under the terms of Open CASCADE
 -- commercial license or contractual agreement.
 
-deferred class Transient from Standard 
+imported deferred class Transient from Standard 
 
     ---Purpose: Abstract class which forms the root of the entire 
     --          Transient class hierarchy.
@@ -81,6 +81,3 @@ is
         count : Integer from Standard;
        
 end Transient from Standard;
-
-
-
index 40687e5..a113a9c 100644 (file)
 // commercial license or contractual agreement.
 
 #include <Standard_Transient.hxx>
-
-// The Initialization of the Standard_Transient variables
-IMPLEMENT_STANDARD_TYPE(Standard_Transient)
-IMPLEMENT_STANDARD_SUPERTYPE_ARRAY()
-IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_END()
-IMPLEMENT_STANDARD_TYPE_END(Standard_Transient)
-
-IMPLEMENT_STANDARD_RTTI(Standard_Transient)
+#include <Standard_Type.hxx>
 
 //
 // The Standard_Transient Methods
 //
 
+// DynamicType
+//
+const Handle(Standard_Type)& Standard_Transient::DynamicType() const
+{
+  return STANDARD_TYPE(Standard_Transient);
+}
+
 // The Method This 
 //
 Handle(Standard_Transient) Standard_Transient::This() const
index 94a7b2c..fdbbd43 100644 (file)
@@ -18,6 +18,6 @@
 #include <Handle_Standard_Transient.hxx>
 #include <Standard_PrimitiveTypes.hxx>
 #include <Standard_Transient_proto.hxx>
-#include <Standard_Type.hxx>
+//#include <Standard_Type.hxx>
 
 #endif 
index fcd8a7b..f114bc4 100644 (file)
@@ -31,10 +31,18 @@ class Standard_Transient
     //---- uses the friend Standard_Transient class
     friend class Handle(Standard_Transient);
 
- public:
+public:
     
     DEFINE_STANDARD_ALLOC
 
+    //! Definition of base_type for RTTI (see Standard_Type)
+    typedef void base_type; 
+
+    //! Definition of the class name
+    static const char* get_type_name () { return "Standard_Transient"; }
+
+public:
+
     //! Empty constructor
     Standard_Transient() : count(0) {}
 
@@ -81,6 +89,4 @@ class Standard_Transient
    volatile Standard_Integer count;
 };
 
-Standard_EXPORT const Handle(Standard_Type)& STANDARD_TYPE(Standard_Transient);
-
 #endif 
diff --git a/src/Standard/Standard_Type.cdl b/src/Standard/Standard_Type.cdl
deleted file mode 100644 (file)
index 0b2ebcf..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
--- Created on: 1991-09-06
--- Created by: jean pierre TIRAULT
--- Copyright (c) 1991-1999 Matra Datavision
--- Copyright (c) 1999-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.
-
-class Type from Standard 
-
-   ---Purpose: 
-   --   The class <Type> provides services to find out information
-   --   about a type defined in CDL.
-   --
-   --   Note that multiple inheritance is not supported by the moment;
-   --   the array of ancestors accepted by constructors is assumed to
-   --   represent hierarchy of ancestors up to the root.
-   --   However, only first element is actually used by SubType method,
-   --   higher level ancestors are requested recursively.
-   --
-   --  Warning:
-   --   The information given by <Type> is about the type from which
-   --   it is created and not about the <Type> itself. 
-   --
-
-inherits
-   Transient from Standard
-
-uses 
-     Boolean from Standard,
-     Integer from Standard,
-     CString from Standard,
-     KindOfType from Standard,
-     AncestorIterator from Standard
-
-raises 
-   TypeMismatch from Standard,
-   NoSuchObject from Standard,
-   OutOfRange   from Standard
-
-is
-       
-   ---------------------------------------------------------------------
-   ---Category: The general information about a type.
-   ---------------------------------------------------------------------   
-
-   Name(me) returns CString;
-   ---Purpose: 
-   --   Returns the type name of <me>.
-   ---Level: Advanced
-
-   Size(me) returns Integer;
-   ---Purpose: 
-   --   Returns the size of <me> in bytes.
-   ---Level: Advanced
-  
-   ---------------------------------------------------------------------
-   ---Category: The Constructor of Type 
-   ---------------------------------------------------------------------
-   Create(aName           : CString;
-         aSize           : Integer) 
-   ---Purpose:
-   --   The constructor for a imported type.
-   ---Level: Advanced
-   returns Type;
-
-   Create(aName           : CString;
-         aSize           : Integer;
-         aNumberOfParent : Integer;
-         aAncestors      : Address) 
-   ---Purpose:
-   --   The constructor for a primitive.
-   ---Level: Advanced
-   returns Type;
-
-   Create(aName           : CString;
-         aSize           : Integer;
-         aNumberOfElement: Integer;
-         aNumberOfParent : Integer;
-         anAncestors     : Address;
-          aElements       : Address)
-   ---Purpose:
-   --   The constructor for an enumeration.
-   ---Level: Advanced
-   returns Type;
-
-   Create(aName           : CString;
-         aSize           : Integer;
-         aNumberOfParent : Integer;
-         anAncestors     : Address;
-          aFields         : Address) 
-   ---Purpose:
-   --   The constructor for a class.
-   ---Level: Advanced
-   returns Type;
-
-   ---------------------------------------------------------------------
-   ---Category: Comparison between types
-   ---------------------------------------------------------------------
-   SubType(me; aOther: Type) returns Boolean;
-   ---Purpose:
-   --   Returns "True", if <me> is the same as <aOther>,
-   --   or inherits from <aOther>.
-   --   Note that multiple inheritance is not supported.
-   ---Level: Advanced
-   
-   SubType(me; theName: CString) returns Boolean;
-   ---Purpose:
-   --   Returns "True", if <me> or one of its ancestors has the name 
-   --   equal to theName.
-   --   Note that multiple inheritance is not supported.
-   ---Level: Advanced
-   
-   ---------------------------------------------------------------------
-   ---Category: Information about nature of the type.  
-   ---------------------------------------------------------------------
-
-   IsImported(me) returns Boolean;
-   ---Purpose: 
-   --   Returns "True", if the type is imported.
-   ---Level: Advanced
-
-   IsPrimitive(me) returns Boolean;
-   ---Purpose: 
-   --   Returns "True", if the type is a primitive.
-   ---Level: Advanced
-
-   IsEnumeration(me) returns Boolean;
-   ---Purpose: 
-   --   Returns "True", if the type is an "Enumeration".
-   ---Level: Advanced
-
-   IsClass(me) returns Boolean;
-   ---Purpose: 
-   --   Returns "True", if the type is a "Class".
-   ---Level: Advanced
-
-   ---------------------------------------------------------------------
-   ---Category: The information about the ancestors of a type.
-   ---------------------------------------------------------------------
-
-   NumberOfParent(me) returns Integer;
-   ---Purpose: 
-   --   Returns the number of direct parents of the class.
-   --   
-   ---Level: Advanced
-
-   NumberOfAncestor(me) returns Integer;
-   ---Purpose: 
-   --   Returns the number of ancestors of the class.
-   --  
-   ---Level: Advanced
-
-   Ancestors(me) returns Address is private;
-   ---Purpose: 
-   --   Returns the address of the ancestors array. It can be used only by 
-   --   AncestorIterator.
-   ---Level: Advanced
-
-   Print (me; s: in out OStream);
-   ---Purpose: 
-   --   Prints on the stream <s> the name of Type.
-   --  Warning:
-   --   The operator "OStream& operator<< (Standard_OStream&,
-   --                                      Handle(Standard_Type)&)"
-   --   is implemented. (This operator uses the method Print)
-   --   
-   ---Level: Advanced          
-   ---C++: alias "Standard_EXPORT     void operator<<(Standard_OStream& s) const  {  Print(s); }  "
-   InLineDummy(me) is static private;
-   ---Purpose:
-   --    Just for inline.
-   --    
-   ---Level: Advanced   
-   ---C++: inline
-    
-fields
-
-   myName            : CString;
-   mySize             : Integer;   
-   myKind            : KindOfType;
-   myNumberOfParent   : Integer;
-   myNumberOfAncestor : Integer;
-   myAncestors       : Address;
-
-friends
-
-   class AncestorIterator from Standard
-
-end Type from Standard;
index ac7a972..6df4754 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Standard_Type.ixx>
-#include <Standard_Persistent.hxx>
 
-//============================================================================
-// The constructor for a imported Type 
-//============================================================================
-
-Standard_Type::Standard_Type(const Standard_CString aName, 
-                            const Standard_Integer aSize)
-{
-  myName = aName;
-  mySize = aSize;
-  myKind = Standard_IsImported;
+#include <Standard_Type.hxx>
+#include <Standard_Mutex.hxx>
+#include <Standard_Assert.hxx>
 
-  //==== Just for be clean with the class and the enumeration ================
-  myNumberOfParent   = 0; 
-  myNumberOfAncestor = 0;
+#include <NCollection_DataMap.hxx>
 
-  myAncestors = NULL;
-}
-
-//============================================================================
-// The constructor for a primitive Type 
 //============================================================================
 
-Standard_Type::Standard_Type(const Standard_CString aName, 
-                            const Standard_Integer aSize, 
-                            const Standard_Integer aNumberOfParent , 
-                            const Standard_Address aAncestors)
+Standard_Boolean Standard_Type::SubType (const Handle(Standard_Type)& theOther) const
 {
-  myName = aName;
-  mySize = aSize;
-  myKind = Standard_IsPrimitive;
-
-  myNumberOfParent   = aNumberOfParent;
-
-  //==== Calculate the number of ancestor ====================================
-  myNumberOfAncestor = 0;
-  myAncestors = aAncestors;
-  Handle(Standard_Type) *allAncestors = (Handle(Standard_Type) *)myAncestors;
-  for(Standard_Integer i=0; allAncestors && !allAncestors[i].IsNull(); i++) {
-    myNumberOfAncestor++;
-  }
+  return ! theOther.IsNull() && (theOther == this || (! myParent.IsNull() && myParent->SubType (theOther)));
 }
 
 //============================================================================
-// The constructor for an enumeration.
-//============================================================================
 
-Standard_Type::Standard_Type(const Standard_CString aName, 
-                            const Standard_Integer aSize, 
-                            const Standard_Integer , 
-                            const Standard_Integer aNumberOfParent, 
-                            const Standard_Address aAncestors, 
-                            const Standard_Address )
+Standard_Boolean Standard_Type::SubType (const Standard_CString theName) const
 {
-  myName = aName;
-  mySize = aSize;
-  myKind = Standard_IsEnumeration;
-
-  myNumberOfParent  = aNumberOfParent;
-
-  //==== Calculate the number of ancestor ====================================
-  myNumberOfAncestor = 0;
-  myAncestors = aAncestors;
-  Handle(Standard_Type) *allAncestors = (Handle(Standard_Type) *)myAncestors;
-  for(Standard_Integer i=0; allAncestors && !allAncestors[i].IsNull(); i++) {
-    myNumberOfAncestor++;
-  }
+  return theName != 0 && (IsSimilar (myName, theName) || (! myParent.IsNull() && myParent->SubType (theName)));
 }
 
-//============================================================================
-// The constructor for a class.
-//============================================================================
-
-Standard_Type::Standard_Type(const Standard_CString aName, 
-                            const Standard_Integer aSize, 
-                            const Standard_Integer aNumberOfParent , 
-                            const Standard_Address aAncestors , 
-                            const Standard_Address )
+// ------------------------------------------------------------------
+// Print (me; s: in out OStream) returns OStream;
+// ------------------------------------------------------------------
+void Standard_Type::Print (Standard_OStream& AStream) const
 {
-  myName = aName;
-  mySize = aSize;
-  myKind = Standard_IsClass;
-
-  myNumberOfParent    = aNumberOfParent;
-
-  //==== Calculate the number of ancestors ===================================
-  myNumberOfAncestor = 0;
-  myAncestors = aAncestors;
-  Handle(Standard_Type) *allAncestors = (Handle(Standard_Type) *)myAncestors;
-  for(Standard_Integer i=0; allAncestors && !allAncestors[i].IsNull(); i++) {
-    myNumberOfAncestor++;
-  }
+  AStream << hex << (Standard_Address)this << " : " << dec << myName ;
 }
 
 //============================================================================
-Standard_CString  Standard_Type::Name() const 
-{
-  return myName;
-}
-
+// Registry of types
 //============================================================================
-Standard_Integer  Standard_Type::Size()const 
-{
-  return mySize;
-}
 
-//============================================================================
-Standard_Boolean  Standard_Type::IsImported()const 
-{
-  return myKind == Standard_IsImported;
-}
+namespace {
+  // Value-based hasher for plain C string (char*)
+  struct CStringHasher 
+  {
+    static Standard_Integer HashCode (const Standard_CString& theKey, const Standard_Integer Upper)
+    {
+      return ::HashCode (theKey, Upper);
+    }
+    static bool IsEqual (const Standard_CString& theKey1, const Standard_CString& theKey2)
+    {
+      return ! strcmp (theKey1, theKey2);
+    }
+  };
 
-//============================================================================
-Standard_Boolean  Standard_Type::IsPrimitive()const 
-{
-  return myKind == Standard_IsPrimitive;
-}
+  // Map of string to type
+  typedef NCollection_DataMap<Standard_CString, Standard_Type*, CStringHasher> registry_type;
 
-//============================================================================
-Standard_Boolean  Standard_Type::IsEnumeration()const 
-{
-  return myKind == Standard_IsEnumeration;
+  // Registry is made static in the function to ensure that it gets
+  // initialized by the time of first access
+  registry_type& GetRegistry() 
+  {
+    static registry_type theRegistry;
+    return theRegistry;
+  }
 }
 
-//============================================================================
-Standard_Boolean  Standard_Type::IsClass()const 
+const Standard_Type* Standard_Type::Register (const char* theSystemName, const char* theName,
+                                              Standard_Size theSize, const Handle(Standard_Type)& theParent)
 {
-  return myKind == Standard_IsClass;
-}
+  // Access to registry is protected by mutex; it should not happen often because
+  // instances are cached by Standard_Type::Instance() (one per binary module)
+  static Standard_Mutex theMutex;
+  Standard_Mutex::Sentry aSentry (theMutex);
 
-//============================================================================
-Standard_Integer  Standard_Type::NumberOfParent()const 
-{
-  return myNumberOfParent;
-}
+  // return existing descriptor if already in the registry
+  registry_type& aRegistry = GetRegistry();
+  Standard_Type* aType = 0;
+  if (aRegistry.Find (theSystemName, aType))
+    return aType;
 
-//============================================================================
-Standard_Integer  Standard_Type::NumberOfAncestor()const 
-{
-  return myNumberOfAncestor;
-}
+  // else create a new descriptor
+  aType = new Standard_Type (theSystemName, theName, theSize, theParent);
 
-//============================================================================
-Standard_Address  Standard_Type::Ancestors()const 
-{
-  return myAncestors;
-}
+  // then add it to registry and return (the reference to the handle stored in the registry)
+  aRegistry.Bind (theSystemName, aType);
 
-//============================================================================
-Standard_Boolean  Standard_Type::SubType(const Handle(Standard_Type)& anOther)const 
-{
-  // Among ancestors of the type of this, there is the type of anOther
-  return anOther == this || 
-         ( myNumberOfAncestor &&
-           (*(Handle(Standard_Type)*)myAncestors)->SubType(anOther) );
-}
+//  cout << "Registering " << theSystemName << ": " << aRegistry.Extent() << endl;
 
-//============================================================================
-Standard_Boolean  Standard_Type::SubType(const Standard_CString theName)const 
-{
-  // Among ancestors of the type of this, there is the type of anOther
-  if ( ! theName )
-    return Standard_False;
-  if ( IsSimilar(myName, theName) )
-    return Standard_True;
-  if (myNumberOfAncestor) 
-    return (*(Handle(Standard_Type) *)myAncestors)->SubType(theName);
-  return Standard_False;
+  return aType;
 }
 
-// ------------------------------------------------------------------
-// Print (me; s: in out OStream) returns OStream;
-// ------------------------------------------------------------------
-void Standard_Type::Print (Standard_OStream& AStream) const
+Standard_Type::~Standard_Type ()
 {
-//  AStream <<  myName ;
-  AStream << hex << (Standard_Address ) myName << " : " << dec << myName ;
-}
+  // remove descriptor from the registry
+  registry_type& aRegistry = GetRegistry();
+  Standard_ASSERT(aRegistry.UnBind (mySystemName), "Standard_Type::~Standard_Type() cannot find itself in registry",);
 
-Standard_OStream& operator << (Standard_OStream& AStream
-                             ,const Handle(Standard_Type)& AType) 
-{
-  AType->Print(AStream);
-  return AStream;
+//  cout << "Unregistering " << mySystemName << ": " << aRegistry.Extent() << endl;
 }
diff --git a/src/Standard/Standard_Type.hxx b/src/Standard/Standard_Type.hxx
new file mode 100644 (file)
index 0000000..2b5c0a1
--- /dev/null
@@ -0,0 +1,183 @@
+// Copyright (c) 1991-1999 Matra Datavision
+// Copyright (c) 1999-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.
+
+#ifndef _Standard_Type_HeaderFile
+#define _Standard_Type_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Transient.hxx>
+
+#include <typeinfo>
+
+// Define handle class
+DEFINE_STANDARD_HANDLE(Standard_Type, Standard_Transient)
+
+//! This class provides legacy interface (type descriptor) to run-time type
+//! information (RTTI) for OCCT classes inheriting from Standard_Transient.
+//!
+//! In addition to features provided by standard C++ RTTI (type_info), 
+//! Standard_Type allows passing descriptor as an object and using it for 
+//! analysis of the type:
+//! - get descriptor of a parent class
+//! - get user-defined name of the class
+//! - get size of the object
+//! 
+//! Use static template method Instance() to get descriptor for a given type.
+//! Objects supporting OCCT RTTI return their type descriptor by method DynamicType().
+//! 
+//! To be usable with OCCT type system, the class should provide:
+//! - typedef base_type to its base class in the hierarchy
+//! - method get_type_name() returning programmer-defined name of the class
+//!   (as a statically allocated constant C string or string literal)
+//!
+//! Note that user-defined name is used since typeid.name() is usually mangled in 
+//! compiler-dependent way.
+//! 
+//! Only single chain of inheritance is supported, with a root base class Standard_Transient.
+
+class Standard_Type : public Standard_Transient
+{
+public:
+
+  //! Returns the system type name of the class (typeinfo.name)
+  Standard_CString SystemName() const { return mySystemName; }
+  
+  //! Returns the given name of the class type (get_type_name)
+  Standard_CString Name() const { return myName; }
+  
+  //! Returns the size of the class instance in bytes
+  Standard_Size Size() const { return mySize; }
+
+  //! Returns descriptor of the base class in the hierarchy
+  const Handle(Standard_Type)& Parent () const { return myParent; }
+  
+  //! Returns True if this type is the same as theOther, or inherits from theOther.
+  //! Note that multiple inheritance is not supported.
+  Standard_EXPORT Standard_Boolean SubType (const Handle(Standard_Type)& theOther) const;
+
+  //! Returns True if this type is the same as theOther, or inherits from theOther.
+  //! Note that multiple inheritance is not supported.
+  Standard_EXPORT Standard_Boolean SubType (const Standard_CString theOther) const;
+
+  //! Prints type (address of descriptor + name) to a stream
+  Standard_EXPORT void Print (Standard_OStream& theStream) const;
+
+  //! Template function returning instance of the type descriptor for an argument class.
+  //!
+  //! For optimization, each type is registered only once (due to use of the static variable).
+  //!
+  //! See helper macro DEFINE_STANDARD_RTTI for defining these items in the class.
+  template <class T>
+  static const Handle(Standard_Type)& Instance()
+  {
+    return opencascade::type_instance<T>::get();
+  }
+
+  //! Register a type; returns either new or existing descriptor.
+  //!
+  //! @param theSystemName name of the class as returned by typeid(class).name()
+  //! @param theName name of the class to be stored in Name field
+  //! @param theSize size of the class instance
+  //! @param theParent base class in the Transient hierarchy
+  //!
+  //! Note that this function is intended for use by opencascade::type_instance only. 
+  Standard_EXPORT static 
+    const Standard_Type* Register (const char* theSystemName, const char* theName,
+                                   Standard_Size theSize, const Handle(Standard_Type)& theParent);
+
+  //! Destructor removes the type from the registry
+  Standard_EXPORT ~Standard_Type ();
+
+  // Define own RTTI
+  DEFINE_STANDARD_RTTI(Standard_Type, Standard_Transient)
+
+private:
+
+  //! Constructor is private
+  Standard_Type (const char* theSystemName, const char* theName,
+                 Standard_Size theSize, const Handle(Standard_Type)& theParent)
+  : mySystemName(theSystemName), myName(theName), mySize(theSize), myParent(theParent)
+  {
+  }
+
+private:
+  Standard_CString mySystemName;  //!< System name of the class (typeinfo.name)
+  Standard_CString myName;        //!< Given name of the class
+  Standard_Size mySize;           //!< Size of the class instance, in bytes
+  Handle(Standard_Type) myParent; //!< Type descriptor of parent class
+};
+
+namespace opencascade {
+
+  //! Template class providing instantiation of type descriptors as static
+  //! variables (one per binary module). Having type descriptors defined as 
+  //! static variables is essential to ensure that everything gets initialized
+  //! during library loading and thus no concurrency occurs when type system
+  //! is accessed from multiple threads.
+  template <typename T>
+  class type_instance
+  {
+    static Handle(Standard_Type) myInstance;
+  public:
+    static const Handle(Standard_Type)& get ();
+  };
+
+  //! Specialization of type descriptor instance for void; returns null handle
+  template <>
+  class type_instance<void>
+  {
+  public:
+    Standard_EXPORT static Handle(Standard_Type) get () { return 0; }
+  };
+
+  // Implementation of static function returning instance of the
+  // type descriptor
+  template <typename T>
+  const Handle(Standard_Type)& type_instance<T>::get ()
+  {
+    // static variable inside function ensures that descriptors
+    // are initialized in correct sequence
+    static Handle(Standard_Type) anInstance =
+      Standard_Type::Register (typeid(T).name(), T::get_type_name(), sizeof(T), 
+                               type_instance<typename T::base_type>::get());
+    return anInstance;
+  }
+
+  // Static class field is defined to ensure initialization of all type
+  // descriptors at load time of the library
+  template <typename T>
+  Handle(Standard_Type) type_instance<T>::myInstance (get());
+
+  //! Definition of dynamic cast function for handles
+  template <class H1, class H2>
+  H1 down_cast (const H2& theObject)
+  {
+    return ! theObject.IsNull() && theObject->IsKind (Standard_Type::Instance<typename H1::element_type>()) ? 
+                                   static_cast<typename H1::element_type*> (theObject.get()) : 0;
+/* alternative implementation using standard C++ RTTI is slower:
+    return dynamic_cast<typename H1::element_type*>(theObject.get());
+*/
+  }
+
+}
+
+//! Operator printing type descriptor to stream
+inline Standard_OStream& operator << (Standard_OStream& theStream, const Handle(Standard_Type)& theType) 
+{
+  theType->Print (theStream);
+  return theStream;
+}
+
+#endif // _Standard_Type_HeaderFile
diff --git a/src/Standard/Standard_Type.lxx b/src/Standard/Standard_Type.lxx
deleted file mode 100644 (file)
index e0fb147..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-// ------------------------------------------------------------------
-// Print (me; s: in out OStream) returns OStream;
-// ------------------------------------------------------------------
-//++++ void Standard_Type::Print (Standard_OStream& AStream) const
-//++++ {
-//++++   AStream << ": " << myMessage << endl;
-//++++ }
-inline void Standard_Type::InLineDummy() const
-{
-}
-
-Standard_EXPORT Standard_OStream& operator << (Standard_OStream& AStream
-                             ,const Handle(Standard_Type)& AType);
index e0db4b4..25a0916 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <TDataStd_TreeNode.ixx>
+#include <TDataStd_TreeNode.hxx>
 #include <TDF_Label.hxx>
+#include <TDF_DataSet.hxx>
+#include <TDF_DeltaOnAddition.hxx>
+#include <TDF_DeltaOnRemoval.hxx>
+#include <TDF_RelocationTable.hxx>
 #include <Standard_DomainError.hxx>
 
 //=======================================================================
diff --git a/tests/perf/fclasses/bug24947 b/tests/perf/fclasses/bug24947
new file mode 100644 (file)
index 0000000..d7288ce
--- /dev/null
@@ -0,0 +1,14 @@
+# Test performance of dynamic loading / unloading of large OCCT library
+
+set libname TKSTEP
+
+switch -nocase $env(os_type) {
+  windows {set libname    ${libname}.dll}
+  linux   {set libname lib${libname}.so}
+  macos   {set libname lib${libname}.dylib}
+}
+
+for {set i 0} {$i < 1000} {incr i} {
+  puts "Iteration $i" 
+  dtryload $libname
+}
index c7c4c77..5c3cf52 100644 (file)
@@ -1,3 +1,4 @@
 001 bop
 002 ncollection
 003 bspline
+004 fclasses