Fix of compiler warnings on OCCT 7.0.0.beta (CLang and VC++ 14)
[occt.git] / src / Standard / Standard_Type.hxx
CommitLineData
69ff08ff 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>
e7195ab4 19#include <Standard_Handle.hxx>
69ff08ff 20#include <Standard_Transient.hxx>
e7195ab4 21#include <Standard_OStream.hxx>
69ff08ff 22
23#include <typeinfo>
24
e7195ab4 25//! Helper macro to get instance of a type descriptor for a class in a legacy way.
f5f4ebd0 26#define STANDARD_TYPE(theType) theType::get_type_descriptor()
e7195ab4 27
28//! Helper macro to be included in definition of the classes inheriting
f5f4ebd0 29//! Standard_Transient to enable use of OCCT RTTI.
30//!
31//! Inline version, does not require IMPLEMENT_STANDARD_RTTIEXT, but when used
32//! for big hierarchies of classes may cause considerable increase of size of binaries.
33#define DEFINE_STANDARD_RTTI_INLINE(Class,Base) \
e7195ab4 34public: \
35 typedef Base base_type; \
36 static const char* get_type_name () { return #Class; } \
f5f4ebd0 37 static const Handle(Standard_Type)& get_type_descriptor () { return Standard_Type::Instance<Class>(); } \
79104795 38 virtual const Handle(Standard_Type)& DynamicType() const Standard_OVERRIDE \
39 { return STANDARD_TYPE(Class); }
e7195ab4 40
f5f4ebd0 41//! Helper macro to be included in definition of the classes inheriting
42//! Standard_Transient to enable use of OCCT RTTI.
43//!
44//! Out-of-line version, requires IMPLEMENT_STANDARD_RTTIEXT.
45#define DEFINE_STANDARD_RTTIEXT(Class,Base) \
46public: \
47 typedef Base base_type; \
48 static const char* get_type_name () { return #Class; } \
49 Standard_EXPORT static const Handle(Standard_Type)& get_type_descriptor (); \
50 Standard_EXPORT virtual const Handle(Standard_Type)& DynamicType() const Standard_OVERRIDE;
51
52//! Defines implementation of type descriptor and DynamicType() function
53#define IMPLEMENT_STANDARD_RTTIEXT(Class,Base) \
54 const Handle(Standard_Type)& Class::get_type_descriptor () { return Standard_Type::Instance<Class>(); } \
55 const Handle(Standard_Type)& Class::DynamicType() const { return get_type_descriptor(); }
56
e7195ab4 57// forward declaration of type_instance class
58namespace opencascade {
59 template <typename T>
d9e90905 60 class type_instance;
e7195ab4 61}
69ff08ff 62
63//! This class provides legacy interface (type descriptor) to run-time type
64//! information (RTTI) for OCCT classes inheriting from Standard_Transient.
65//!
66//! In addition to features provided by standard C++ RTTI (type_info),
67//! Standard_Type allows passing descriptor as an object and using it for
68//! analysis of the type:
69//! - get descriptor of a parent class
70//! - get user-defined name of the class
71//! - get size of the object
72//!
73//! Use static template method Instance() to get descriptor for a given type.
74//! Objects supporting OCCT RTTI return their type descriptor by method DynamicType().
75//!
76//! To be usable with OCCT type system, the class should provide:
77//! - typedef base_type to its base class in the hierarchy
78//! - method get_type_name() returning programmer-defined name of the class
79//! (as a statically allocated constant C string or string literal)
80//!
81//! Note that user-defined name is used since typeid.name() is usually mangled in
82//! compiler-dependent way.
83//!
84//! Only single chain of inheritance is supported, with a root base class Standard_Transient.
85
86class Standard_Type : public Standard_Transient
87{
88public:
89
90 //! Returns the system type name of the class (typeinfo.name)
91 Standard_CString SystemName() const { return mySystemName; }
92
93 //! Returns the given name of the class type (get_type_name)
94 Standard_CString Name() const { return myName; }
95
96 //! Returns the size of the class instance in bytes
97 Standard_Size Size() const { return mySize; }
98
99 //! Returns descriptor of the base class in the hierarchy
100 const Handle(Standard_Type)& Parent () const { return myParent; }
101
102 //! Returns True if this type is the same as theOther, or inherits from theOther.
103 //! Note that multiple inheritance is not supported.
104 Standard_EXPORT Standard_Boolean SubType (const Handle(Standard_Type)& theOther) const;
105
106 //! Returns True if this type is the same as theOther, or inherits from theOther.
107 //! Note that multiple inheritance is not supported.
108 Standard_EXPORT Standard_Boolean SubType (const Standard_CString theOther) const;
109
110 //! Prints type (address of descriptor + name) to a stream
111 Standard_EXPORT void Print (Standard_OStream& theStream) const;
112
113 //! Template function returning instance of the type descriptor for an argument class.
114 //!
115 //! For optimization, each type is registered only once (due to use of the static variable).
116 //!
117 //! See helper macro DEFINE_STANDARD_RTTI for defining these items in the class.
118 template <class T>
119 static const Handle(Standard_Type)& Instance()
120 {
121 return opencascade::type_instance<T>::get();
122 }
123
124 //! Register a type; returns either new or existing descriptor.
125 //!
126 //! @param theSystemName name of the class as returned by typeid(class).name()
127 //! @param theName name of the class to be stored in Name field
128 //! @param theSize size of the class instance
129 //! @param theParent base class in the Transient hierarchy
130 //!
131 //! Note that this function is intended for use by opencascade::type_instance only.
132 Standard_EXPORT static
e7195ab4 133 Standard_Type* Register (const char* theSystemName, const char* theName,
134 Standard_Size theSize, const Handle(Standard_Type)& theParent);
69ff08ff 135
136 //! Destructor removes the type from the registry
137 Standard_EXPORT ~Standard_Type ();
138
139 // Define own RTTI
f5f4ebd0 140 DEFINE_STANDARD_RTTIEXT(Standard_Type,Standard_Transient)
69ff08ff 141
142private:
143
144 //! Constructor is private
145 Standard_Type (const char* theSystemName, const char* theName,
a0218ba1 146 Standard_Size theSize, const Handle(Standard_Type)& theParent);
69ff08ff 147
148private:
149 Standard_CString mySystemName; //!< System name of the class (typeinfo.name)
150 Standard_CString myName; //!< Given name of the class
151 Standard_Size mySize; //!< Size of the class instance, in bytes
152 Handle(Standard_Type) myParent; //!< Type descriptor of parent class
153};
154
155namespace opencascade {
156
d9e90905 157 //! Template class providing instantiation of type descriptors as singletons.
158 //! The descriptors are defined as static variables in function get(), which
159 //! is essential to ensure that they are initialized in correct sequence.
160 //!
161 //! For compilers that do not provide thread-safe initialization of static
162 //! variables (C++11 feature, N2660), additional global variable is
163 //! defined for each type to hold its type descriptor. These globals ensure
164 //! that all types get initialized during the library loading and thus no
165 //! concurrency occurs when type system is accessed from multiple threads.
69ff08ff 166 template <typename T>
d9e90905 167 class type_instance
69ff08ff 168 {
d9e90905 169 static Handle(Standard_Type) myInstance;
170 public:
69ff08ff 171 static const Handle(Standard_Type)& get ();
172 };
173
174 //! Specialization of type descriptor instance for void; returns null handle
175 template <>
d9e90905 176 class type_instance<void>
69ff08ff 177 {
d9e90905 178 public:
69ff08ff 179 Standard_EXPORT static Handle(Standard_Type) get () { return 0; }
180 };
181
182 // Implementation of static function returning instance of the
183 // type descriptor
184 template <typename T>
185 const Handle(Standard_Type)& type_instance<T>::get ()
186 {
8bb8064e 187#if (defined(_MSC_VER) && _MSC_VER < 1800) || \
188 (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)) && \
189 ! defined(__clang__) && ! defined(__INTEL_COMPILER))
d9e90905 190 // ensure that myInstance is instantiated
191 (void)myInstance;
8bb8064e 192#endif
d9e90905 193
69ff08ff 194 // static variable inside function ensures that descriptors
195 // are initialized in correct sequence
196 static Handle(Standard_Type) anInstance =
197 Standard_Type::Register (typeid(T).name(), T::get_type_name(), sizeof(T),
198 type_instance<typename T::base_type>::get());
199 return anInstance;
200 }
201
d9e90905 202 // Static class field is defined to ensure initialization of all type
203 // descriptors at load time of the library on compilers not supporting N2660:
204 // - VC++ below 14 (VS 2015)
205 // - GCC below 4.3
206 // Intel compiler reports itself as GCC on Linux and VC++ on Windows,
207 // and is claimed to support N2660 on Linux and on Windows "in VS2015 mode".
208 // CLang should support N2660 since version 2.9, but it is not clear how to
209 // check its version reliably (on Linux it says it is GCC 4.2).
210#if (defined(_MSC_VER) && _MSC_VER < 1800) || \
211 (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)) && \
212 ! defined(__clang__) && ! defined(__INTEL_COMPILER))
213
214 template <typename T>
215 Handle(Standard_Type) type_instance<T>::myInstance (get());
216
217#endif
69ff08ff 218}
219
220//! Operator printing type descriptor to stream
221inline Standard_OStream& operator << (Standard_OStream& theStream, const Handle(Standard_Type)& theType)
222{
223 theType->Print (theStream);
224 return theStream;
225}
226
e7195ab4 227//! Definition of Handle_Standard_Type as typedef for compatibility
228DEFINE_STANDARD_HANDLE(Standard_Type,Standard_Transient)
229
69ff08ff 230#endif // _Standard_Type_HeaderFile