0028824: Possibility to build OCCT 7.1.0 and above using Visual Studio 2008
[occt.git] / src / Standard / Standard_Type.hxx
index bbcf007..b21ba3a 100644 (file)
 
 // Auxiliary tools to check at compile time that class declared as base in 
 // DEFINE_STANDARD_RTTI* macro is actually a base class.
-// For GCC 4.7+, more strict check is possible -- ensuring that base class 
-// is direct base -- using non-standard C++ reflection functionality.
 #if ! defined(OCC_CHECK_BASE_CLASS)
+
 #if (defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)))
 
+// For GCC 4.7+, more strict check is possible -- ensuring that base class 
+// is direct base -- using non-standard C++ reflection functionality.
+
 #include <tr2/type_traits>
 #include <tuple>
 
@@ -58,14 +60,30 @@ namespace opencascade
 
 #define OCC_CHECK_BASE_CLASS(Class,Base) \
   using direct_base_classes = opencascade::direct_base_class_as_tuple<std::tr2::direct_bases<Class>::type>::type; \
-  static_assert(opencascade::has_type<Base, direct_base_classes>::type::value, "OCCT RTTI definition is incorrect: " #Base " is not direct base class of " #Class);
+  static_assert(opencascade::has_type<Base, direct_base_classes>::type::value, "OCCT RTTI definition is incorrect: " #Base " is not direct base class of " #Class); \
+  static_assert(&get_type_name == &Class::get_type_name, "OCCT RTTI definition is misplaced: current class is not " #Class);
+
+#elif (defined(_MSC_VER) && (_MSC_VER < 1600))
+
+// VC9 does not support static_assert and decltype at all
+#define OCC_CHECK_BASE_CLASS(Class,Base)
 
-#else /* ! GCC 4.7+ */
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1900))
 
+// VC14+ allow using address of member functions in static checks,
+// that allows checking for the current type being correctly named in the macro
+#define OCC_CHECK_BASE_CLASS(Class,Base) \
+  static_assert(opencascade::is_base_but_not_same<Base, Class>::value, "OCCT RTTI definition is incorrect: " #Base " is not base class of " #Class); \
+  static_assert(&get_type_name == &Class::get_type_name, "OCCT RTTI definition is misplaced: current class is not " #Class);
+
+#else
+
+// by default, check only the base class
 #define OCC_CHECK_BASE_CLASS(Class,Base) \
   static_assert(opencascade::is_base_but_not_same<Base, Class>::value, "OCCT RTTI definition is incorrect: " #Base " is not base class of " #Class);
 
-#endif /* GCC 4.7+ */
+#endif
+
 #endif /* ! defined(OCC_CHECK_BASE_CLASS) */
 
 //! Helper macro to get instance of a type descriptor for a class in a legacy way.
@@ -81,10 +99,7 @@ public: \
   typedef Base base_type; \
   static const char* get_type_name () { return #Class; OCC_CHECK_BASE_CLASS(Class,Base) } \
   static const Handle(Standard_Type)& get_type_descriptor () { return Standard_Type::Instance<Class>(); } \
-  virtual const Handle(Standard_Type)& DynamicType() const Standard_OVERRIDE { \
-    static_assert(std::is_same<const Class*, decltype(this)>::value, "OCCT RTTI definition is misplaced: current class is not " #Class); \
-    return get_type_descriptor (); \
-  }
+  virtual const Handle(Standard_Type)& DynamicType() const Standard_OVERRIDE { return get_type_descriptor (); }
 
 //! Helper macro to be included in definition of the classes inheriting
 //! Standard_Transient to enable use of OCCT RTTI.
@@ -100,10 +115,7 @@ public: \
 //! Defines implementation of type descriptor and DynamicType() function
 #define IMPLEMENT_STANDARD_RTTIEXT(Class,Base) \
   const Handle(Standard_Type)& Class::get_type_descriptor () { return Standard_Type::Instance<Class>(); } \
-  const Handle(Standard_Type)& Class::DynamicType() const { \
-    static_assert(std::is_same<const Class*, decltype(this)>::value, "OCCT RTTI definition is misplaced: current class is not " #Class); \
-    return STANDARD_TYPE(Class); \
-  }
+  const Handle(Standard_Type)& Class::DynamicType() const { return STANDARD_TYPE(Class); }
 
 // forward declaration of type_instance class
 namespace opencascade {