0026912: CLang 3.6.2 compiler warning [-Winconsistent-missing-override]
[occt.git] / src / Standard / Standard_Type.hxx
1 // Copyright (c) 1991-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 #ifndef _Standard_Type_HeaderFile
16 #define _Standard_Type_HeaderFile
17
18 #include <Standard.hxx>
19 #include <Standard_Handle.hxx>
20 #include <Standard_Transient.hxx>
21 #include <Standard_OStream.hxx>
22
23 #include <typeinfo>
24
25 //! Helper macro to get instance of a type descriptor for a class in a legacy way.
26 #define STANDARD_TYPE(theType) Standard_Type::Instance<theType>()
27
28 //! Helper macro to be included in definition of the classes inheriting
29 //! Standard_Transient to enable use of OCCT RTTI and smart pointers (handles).
30 #define DEFINE_STANDARD_RTTI(Class,Base) \
31 public: \
32   typedef Base base_type; \
33   static const char* get_type_name () { return #Class; } \
34   virtual const Handle(Standard_Type)& DynamicType() const Standard_OVERRIDE \
35   { return STANDARD_TYPE(Class); }
36
37 // forward declaration of type_instance class
38 namespace opencascade {
39   template <typename T>
40   class type_instance;
41 }
42
43 //! This class provides legacy interface (type descriptor) to run-time type
44 //! information (RTTI) for OCCT classes inheriting from Standard_Transient.
45 //!
46 //! In addition to features provided by standard C++ RTTI (type_info), 
47 //! Standard_Type allows passing descriptor as an object and using it for 
48 //! analysis of the type:
49 //! - get descriptor of a parent class
50 //! - get user-defined name of the class
51 //! - get size of the object
52 //! 
53 //! Use static template method Instance() to get descriptor for a given type.
54 //! Objects supporting OCCT RTTI return their type descriptor by method DynamicType().
55 //! 
56 //! To be usable with OCCT type system, the class should provide:
57 //! - typedef base_type to its base class in the hierarchy
58 //! - method get_type_name() returning programmer-defined name of the class
59 //!   (as a statically allocated constant C string or string literal)
60 //!
61 //! Note that user-defined name is used since typeid.name() is usually mangled in 
62 //! compiler-dependent way.
63 //! 
64 //! Only single chain of inheritance is supported, with a root base class Standard_Transient.
65
66 class Standard_Type : public Standard_Transient
67 {
68 public:
69
70   //! Returns the system type name of the class (typeinfo.name)
71   Standard_CString SystemName() const { return mySystemName; }
72   
73   //! Returns the given name of the class type (get_type_name)
74   Standard_CString Name() const { return myName; }
75   
76   //! Returns the size of the class instance in bytes
77   Standard_Size Size() const { return mySize; }
78
79   //! Returns descriptor of the base class in the hierarchy
80   const Handle(Standard_Type)& Parent () const { return myParent; }
81   
82   //! Returns True if this type is the same as theOther, or inherits from theOther.
83   //! Note that multiple inheritance is not supported.
84   Standard_EXPORT Standard_Boolean SubType (const Handle(Standard_Type)& theOther) const;
85
86   //! Returns True if this type is the same as theOther, or inherits from theOther.
87   //! Note that multiple inheritance is not supported.
88   Standard_EXPORT Standard_Boolean SubType (const Standard_CString theOther) const;
89
90   //! Prints type (address of descriptor + name) to a stream
91   Standard_EXPORT void Print (Standard_OStream& theStream) const;
92
93   //! Template function returning instance of the type descriptor for an argument class.
94   //!
95   //! For optimization, each type is registered only once (due to use of the static variable).
96   //!
97   //! See helper macro DEFINE_STANDARD_RTTI for defining these items in the class.
98   template <class T>
99   static const Handle(Standard_Type)& Instance()
100   {
101     return opencascade::type_instance<T>::get();
102   }
103
104   //! Register a type; returns either new or existing descriptor.
105   //!
106   //! @param theSystemName name of the class as returned by typeid(class).name()
107   //! @param theName name of the class to be stored in Name field
108   //! @param theSize size of the class instance
109   //! @param theParent base class in the Transient hierarchy
110   //!
111   //! Note that this function is intended for use by opencascade::type_instance only. 
112   Standard_EXPORT static 
113     Standard_Type* Register (const char* theSystemName, const char* theName,
114                              Standard_Size theSize, const Handle(Standard_Type)& theParent);
115
116   //! Destructor removes the type from the registry
117   Standard_EXPORT ~Standard_Type ();
118
119   // Define own RTTI
120   DEFINE_STANDARD_RTTI(Standard_Type, Standard_Transient)
121
122 private:
123
124   //! Constructor is private
125   Standard_Type (const char* theSystemName, const char* theName,
126                  Standard_Size theSize, const Handle(Standard_Type)& theParent)
127   : mySystemName(theSystemName), myName(theName), mySize(theSize), myParent(theParent)
128   {
129   }
130
131 private:
132   Standard_CString mySystemName;  //!< System name of the class (typeinfo.name)
133   Standard_CString myName;        //!< Given name of the class
134   Standard_Size mySize;           //!< Size of the class instance, in bytes
135   Handle(Standard_Type) myParent; //!< Type descriptor of parent class
136 };
137
138 namespace opencascade {
139
140   //! Template class providing instantiation of type descriptors as static
141   //! variables (one per binary module). Having type descriptors defined as 
142   //! static variables is essential to ensure that everything gets initialized
143   //! during library loading and thus no concurrency occurs when type system
144   //! is accessed from multiple threads.
145   template <typename T>
146   class type_instance
147   {
148     static Handle(Standard_Type) myInstance;
149   public:
150     static const Handle(Standard_Type)& get ();
151   };
152
153   //! Specialization of type descriptor instance for void; returns null handle
154   template <>
155   class type_instance<void>
156   {
157   public:
158     Standard_EXPORT static Handle(Standard_Type) get () { return 0; }
159   };
160
161   // Implementation of static function returning instance of the
162   // type descriptor
163   template <typename T>
164   const Handle(Standard_Type)& type_instance<T>::get ()
165   {
166     (void)myInstance; // ensure that myInstance is instantiated
167
168     // static variable inside function ensures that descriptors
169     // are initialized in correct sequence
170     static Handle(Standard_Type) anInstance =
171       Standard_Type::Register (typeid(T).name(), T::get_type_name(), sizeof(T), 
172                                type_instance<typename T::base_type>::get());
173     return anInstance;
174   }
175
176   // Static class field is defined to ensure initialization of all type
177   // descriptors at load time of the library
178   template <typename T>
179   Handle(Standard_Type) type_instance<T>::myInstance (get());
180
181 }
182
183 //! Operator printing type descriptor to stream
184 inline Standard_OStream& operator << (Standard_OStream& theStream, const Handle(Standard_Type)& theType) 
185 {
186   theType->Print (theStream);
187   return theStream;
188 }
189
190 //! Definition of Handle_Standard_Type as typedef for compatibility
191 DEFINE_STANDARD_HANDLE(Standard_Type,Standard_Transient)
192
193 #endif // _Standard_Type_HeaderFile