0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / Standard / Standard_Type.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Standard_Type.hxx>
17 #include <Standard_Mutex.hxx>
18 #include <Standard_Assert.hxx>
19
20 #include <unordered_map>
21
22 IMPLEMENT_STANDARD_RTTIEXT(Standard_Type,Standard_Transient)
23
24 //============================================================================
25
26 Standard_Type::Standard_Type (const std::type_info& theInfo,
27                               const char* theName,
28                               Standard_Size theSize,
29                               const Handle(Standard_Type)& theParent) :
30   myInfo(theInfo),
31   myName(theName),
32   mySize(theSize), 
33   myParent(theParent)
34 {
35 }
36
37 //============================================================================
38
39 Standard_Boolean Standard_Type::SubType (const Handle(Standard_Type)& theOther) const
40 {
41   return ! theOther.IsNull() && (theOther == this || (! myParent.IsNull() && myParent->SubType (theOther)));
42 }
43
44 //============================================================================
45
46 Standard_Boolean Standard_Type::SubType (const Standard_CString theName) const
47 {
48   return theName != 0 && (IsEqual (myName, theName) || (! myParent.IsNull() && myParent->SubType (theName)));
49 }
50
51 // ------------------------------------------------------------------
52 // Print (me; s: in out OStream) returns OStream;
53 // ------------------------------------------------------------------
54 void Standard_Type::Print (Standard_OStream& AStream) const
55 {
56   AStream << std::hex << (Standard_Address)this << " : " << std::dec << myName ;
57 }
58
59 //============================================================================
60 // Registry of types
61 //============================================================================
62
63 namespace {
64   // Map of string to type
65   typedef std::unordered_map<std::type_index, Standard_Type*> registry_type;
66
67   // Registry is made static in the function to ensure that it gets
68   // initialized by the time of first access
69   registry_type& GetRegistry() 
70   {
71     static registry_type theRegistry;
72     return theRegistry;
73   }
74
75   // To initialize theRegistry map as soon as possible to be destroyed the latest
76   Handle(Standard_Type) theType = STANDARD_TYPE(Standard_Transient);
77 }
78
79 Standard_Type* Standard_Type::Register (const std::type_info& theInfo, const char* theName,
80                                         Standard_Size theSize, const Handle(Standard_Type)& theParent)
81 {
82   // Access to registry is protected by mutex; it should not happen often because
83   // instances are cached by Standard_Type::Instance() (one per binary module)
84   static Standard_Mutex theMutex;
85   Standard_Mutex::Sentry aSentry (theMutex);
86
87   // return existing descriptor if already in the registry
88   registry_type& aRegistry = GetRegistry();
89   Standard_Type* aType = 0;
90   auto anIter = aRegistry.find(theInfo);
91   if (anIter != aRegistry.end())
92     return anIter->second;
93
94   // else create a new descriptor
95   aType = new Standard_Type (theInfo, theName, theSize, theParent);
96
97   // then add it to registry and return (the reference to the handle stored in the registry)
98   aRegistry.emplace(theInfo, aType);
99   return aType;
100 }
101
102 Standard_Type::~Standard_Type ()
103 {
104   // remove descriptor from the registry
105   registry_type& aRegistry = GetRegistry();
106   Standard_ASSERT(aRegistry.erase(myInfo) > 0, "Standard_Type::~Standard_Type() cannot find itself in registry",);
107 }