]> OCCT Git - occt.git/commitdiff
0027016: Restore global type descriptors for old compilers
authorabv <abv@opencascade.com>
Sat, 19 Dec 2015 14:55:41 +0000 (17:55 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 22 Dec 2015 11:15:01 +0000 (14:15 +0300)
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

src/Standard/Standard_Handle.hxx
src/Standard/Standard_Type.hxx

index c17eda072f585b906cc874feb6fecbdcad54706d..896500a447685a17e0de8817619706dc72c9029f 100644 (file)
@@ -182,7 +182,9 @@ namespace opencascade {
       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
     explicit operator bool () const
@@ -201,7 +203,9 @@ namespace opencascade {
 #endif
 
     //! 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.
     template <class T2, typename = typename std::enable_if<std::is_base_of<T2, T>::value>::type>
index 98317e3b5cacfef337d15ae48d3b296d1ced10ad..87b52c2525c0d233cfdfc8bbb23c3480bb682846 100644 (file)
@@ -57,7 +57,7 @@ public: \
 // forward declaration of type_instance class
 namespace opencascade {
   template <typename T>
-  struct type_instance;
+  class type_instance;
 }
 
 //! This class provides legacy interface (type descriptor) to run-time type
@@ -154,20 +154,28 @@ private:
 
 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 descriptors are initialized
-  //! once and in correct order.
+  //! Template class providing instantiation of type descriptors as singletons.
+  //! The descriptors are defined as static variables in function get(), which
+  //! is essential to ensure that they are initialized in correct sequence.
+  //!
+  //! 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>
-  struct type_instance
+  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 <>
-  struct type_instance<void>
+  class type_instance<void>
   {
+  public:
     Standard_EXPORT static Handle(Standard_Type) get () { return 0; }
   };
 
@@ -176,6 +184,9 @@ namespace opencascade {
   template <typename T>
   const Handle(Standard_Type)& type_instance<T>::get ()
   {
+    // ensure that myInstance is instantiated
+    (void)myInstance;
+
     // static variable inside function ensures that descriptors
     // are initialized in correct sequence
     static Handle(Standard_Type) anInstance =
@@ -184,6 +195,22 @@ namespace opencascade {
     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