1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00

0027016: Restore global type descriptors for old compilers

Global type descriptors are restored for VC++ 10 - 12 and GCC before 4.3.

Checks of compiler support of C++ features are corrected for GCC, ICC, and CLang in Standard_Handle.hxx
This commit is contained in:
abv 2015-12-19 17:55:41 +03:00 committed by bugmaster
parent 727b5ad9fb
commit d9e9090564
2 changed files with 40 additions and 9 deletions

View File

@ -182,7 +182,9 @@ namespace opencascade {
return handle (dynamic_cast<T*>(const_cast<T2*>(thePtr))); return handle (dynamic_cast<T*>(const_cast<T2*>(thePtr)));
} }
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) || (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6) #if (defined(__clang__)) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1300) || \
(defined(_MSC_VER) && _MSC_VER >= 1800) || \
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
//! Conversion to bool for use in conditional expressions //! Conversion to bool for use in conditional expressions
explicit operator bool () const explicit operator bool () const
@ -201,7 +203,9 @@ namespace opencascade {
#endif #endif
//! Upcast to const reference to base type. //! Upcast to const reference to base type.
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) || (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3) #if (defined(__clang__)) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1206) || \
(defined(_MSC_VER) && _MSC_VER >= 1800) || \
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
//! Upcast to const reference to base type. //! Upcast to const reference to base type.
template <class T2, typename = typename std::enable_if<std::is_base_of<T2, T>::value>::type> template <class T2, typename = typename std::enable_if<std::is_base_of<T2, T>::value>::type>

View File

@ -57,7 +57,7 @@ public: \
// forward declaration of type_instance class // forward declaration of type_instance class
namespace opencascade { namespace opencascade {
template <typename T> template <typename T>
struct type_instance; class type_instance;
} }
//! This class provides legacy interface (type descriptor) to run-time type //! This class provides legacy interface (type descriptor) to run-time type
@ -154,20 +154,28 @@ private:
namespace opencascade { namespace opencascade {
//! Template class providing instantiation of type descriptors as static //! Template class providing instantiation of type descriptors as singletons.
//! variables (one per binary module). Having type descriptors defined as //! The descriptors are defined as static variables in function get(), which
//! static variables is essential to ensure that descriptors are initialized //! is essential to ensure that they are initialized in correct sequence.
//! once and in correct order. //!
//! For compilers that do not provide thread-safe initialization of static
//! variables (C++11 feature, N2660), additional global variable is
//! defined for each type to hold its type descriptor. These globals ensure
//! that all types get initialized during the library loading and thus no
//! concurrency occurs when type system is accessed from multiple threads.
template <typename T> template <typename T>
struct type_instance class type_instance
{ {
static Handle(Standard_Type) myInstance;
public:
static const Handle(Standard_Type)& get (); static const Handle(Standard_Type)& get ();
}; };
//! Specialization of type descriptor instance for void; returns null handle //! Specialization of type descriptor instance for void; returns null handle
template <> template <>
struct type_instance<void> class type_instance<void>
{ {
public:
Standard_EXPORT static Handle(Standard_Type) get () { return 0; } Standard_EXPORT static Handle(Standard_Type) get () { return 0; }
}; };
@ -176,6 +184,9 @@ namespace opencascade {
template <typename T> template <typename T>
const Handle(Standard_Type)& type_instance<T>::get () const Handle(Standard_Type)& type_instance<T>::get ()
{ {
// ensure that myInstance is instantiated
(void)myInstance;
// static variable inside function ensures that descriptors // static variable inside function ensures that descriptors
// are initialized in correct sequence // are initialized in correct sequence
static Handle(Standard_Type) anInstance = static Handle(Standard_Type) anInstance =
@ -184,6 +195,22 @@ namespace opencascade {
return anInstance; return anInstance;
} }
// Static class field is defined to ensure initialization of all type
// descriptors at load time of the library on compilers not supporting N2660:
// - VC++ below 14 (VS 2015)
// - GCC below 4.3
// Intel compiler reports itself as GCC on Linux and VC++ on Windows,
// and is claimed to support N2660 on Linux and on Windows "in VS2015 mode".
// CLang should support N2660 since version 2.9, but it is not clear how to
// check its version reliably (on Linux it says it is GCC 4.2).
#if (defined(_MSC_VER) && _MSC_VER < 1800) || \
(defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)) && \
! defined(__clang__) && ! defined(__INTEL_COMPILER))
template <typename T>
Handle(Standard_Type) type_instance<T>::myInstance (get());
#endif
} }
//! Operator printing type descriptor to stream //! Operator printing type descriptor to stream