1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0028824: Possibility to build OCCT 7.1.0 and above using Visual Studio 2008

Possibility to build OCCT using Visual Studio 2008 (VC9) is restored.
For that:

- template functions and classes from namespace std or tr1 (for VC9) are imported to namespace opencascade which is then used instead of std in relevant places
- templates not provided by compiler (VC9) but required for OCCT are defined in this namespace (in Standard_Handle.hxx)
- methods implementing move semantics are excluded for VC9 compiler (which does not support && syntax)
- support of vc9 compiler is restored in build procedures and environment scripts
- check of type of the current class in macros DEFINE_STANDARD_RTTI* is refactored

VS 2008 is restored in the list of supported platforms on Overview / System Requirements.
This commit is contained in:
oan
2017-09-14 11:39:36 +03:00
committed by bugmaster
parent a4ab454c0f
commit 71c810df61
23 changed files with 201 additions and 122 deletions

View File

@@ -18,6 +18,12 @@
#include <fstream>
// Suppress VC9 warning on xsputn() function
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4996)
#endif
//! Custom buffer object implementing STL interface std::streambuf for streamed reading from allocated memory block.
//! Implements minimal sub-set of methods for passing buffer to std::istream, including seek support.
//!
@@ -110,4 +116,8 @@ protected:
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // _Standard_ArrayStreamBuffer_HeaderFile

View File

@@ -22,16 +22,59 @@
class Standard_Transient;
//! Namespace opencascade is intended for low-level template classes and functions
namespace opencascade {
//! Namespace opencascade::std includes templates from C++11 std namespace used by
//! OCCT classes. These definitions are imported from std namespace, plus (on older
//! compilers) from std::tr1, or implemented by custom code where neither std
//! not std::tr1 provide necessary definitions.
namespace std
{
// import all available standard stuff from std namespace
using namespace ::std;
// for old MSVC compiler, some standard templates are defined in std::tr1 namespace,
// and some missing ones are implemented here
#if(defined(_MSC_VER) && (_MSC_VER < 1600))
using namespace ::std::tr1;
// C++11 template class enable_if
template<bool Test, class Type = void>
struct enable_if
{// type is undefined for assumed !_Test
};
template<class _Type>
struct enable_if<true, _Type>
{// type is _Type for _Test
typedef _Type type;
};
template<bool Condition, typename TypeTrue, typename TypeFalse>
struct conditional
{
typedef TypeTrue type;
};
template<typename TypeTrue, typename TypeFalse>
struct conditional<false, TypeTrue, TypeFalse>
{
typedef TypeFalse type;
};
#endif
} // namespace opencascade::std
//! Trait yielding true if class T1 is base of T2 but not the same
template <class T1, class T2, class Dummy = void>
struct is_base_but_not_same : std::is_base_of <T1, T2> {};
struct is_base_but_not_same : opencascade::std::is_base_of <T1, T2> {};
//! Explicit specialization of is_base_of trait to workaround the
//! requirement of type to be complete when T1 and T2 are the same.
template <class T1, class T2>
struct is_base_but_not_same <T1, T2, typename std::enable_if <std::is_same <T1, T2>::value>::type> : std::false_type {};
struct is_base_but_not_same <T1, T2, typename opencascade::std::enable_if <opencascade::std::is_same <T1, T2>::value>::type> : opencascade::std::false_type {};
//! Intrusive smart pointer for use with Standard_Transient class and its descendants.
//!
@@ -79,11 +122,14 @@ namespace opencascade {
BeginScope();
}
#if(defined(_MSC_VER) && (_MSC_VER < 1600))
#else
//! Move constructor
handle (handle&& theHandle) : entity(theHandle.entity)
{
theHandle.entity = 0;
}
#endif
//! Destructor
~handle ()
@@ -120,12 +166,15 @@ namespace opencascade {
return *this;
}
#if(defined(_MSC_VER) && (_MSC_VER < 1600))
#else
//! Move operator
handle& operator= (handle&& theHandle)
{
std::swap (this->entity, theHandle.entity);
return *this;
}
#endif
//! STL-like cast to pointer to referred object (note non-const).
//! @sa std::shared_ptr::get()
@@ -188,7 +237,7 @@ namespace opencascade {
//! Down casting operator from handle to base type
template <class T2>
static typename std::enable_if<is_base_but_not_same<T2, T>::value, handle>::type
static typename opencascade::std::enable_if<is_base_but_not_same<T2, T>::value, handle>::type
DownCast (const handle<T2>& theObject)
{
return handle (dynamic_cast<T*>(const_cast<T2*>(theObject.get())));
@@ -196,7 +245,7 @@ namespace opencascade {
//! Down casting operator from pointer to base type
template <class T2>
static typename std::enable_if<is_base_but_not_same<T2, T>::value, handle>::type
static typename opencascade::std::enable_if<is_base_but_not_same<T2, T>::value, handle>::type
DownCast (const T2* thePtr)
{
return handle (dynamic_cast<T*>(const_cast<T2*>(thePtr)));
@@ -205,7 +254,7 @@ namespace opencascade {
//! For compatibility, define down casting operator from non-base type, as deprecated
template <class T2>
Standard_DEPRECATED("down-casting from object of the same or unrelated type is meaningless")
static handle DownCast (const handle<T2>& theObject, typename std::enable_if<!is_base_but_not_same<T2, T>::value, void*>::type = 0)
static handle DownCast (const handle<T2>& theObject, typename opencascade::std::enable_if<!is_base_but_not_same<T2, T>::value, void*>::type = 0)
{
return handle (dynamic_cast<T*>(const_cast<T2*>(theObject.get())));
}
@@ -213,7 +262,7 @@ namespace opencascade {
//! For compatibility, define down casting operator from non-base type, as deprecated
template <class T2>
Standard_DEPRECATED("down-casting from object of the same or unrelated type is meaningless")
static handle DownCast (const T2* thePtr, typename std::enable_if<!is_base_but_not_same<T2, T>::value, void*>::type = 0)
static handle DownCast (const T2* thePtr, typename opencascade::std::enable_if<!is_base_but_not_same<T2, T>::value, void*>::type = 0)
{
return handle (dynamic_cast<T*>(const_cast<T2*>(thePtr)));
}
@@ -312,6 +361,8 @@ namespace opencascade {
BeginScope();
}
#if(defined(_MSC_VER) && (_MSC_VER < 1600))
#else
//! Generalized move constructor
template <class T2>
handle (handle<T2>&& theHandle, typename std::enable_if <is_base_but_not_same <T, T2>::value>::type* = nullptr)
@@ -319,6 +370,7 @@ namespace opencascade {
{
theHandle.entity = 0;
}
#endif
//! Generalized assignment operator.
template <class T2>
@@ -330,6 +382,8 @@ namespace opencascade {
return *this;
}
#if(defined(_MSC_VER) && (_MSC_VER < 1600))
#else
//! Generalized move operator
template <class T2>
handle& operator= (handle<T2>&& theHandle)
@@ -339,6 +393,7 @@ namespace opencascade {
std::swap (this->entity, theHandle.entity);
return *this;
}
#endif
#else
@@ -351,7 +406,7 @@ namespace opencascade {
{
// error "type is not a member of enable_if" will be generated if T2 is not sub-type of T
// (handle is being cast to const& to handle of non-base type)
return reinterpret_cast<typename std::enable_if<is_base_but_not_same<T2, T>::value, const handle<T2>&>::type>(*this);
return reinterpret_cast<typename opencascade::std::enable_if<is_base_but_not_same<T2, T>::value, const handle<T2>&>::type>(*this);
}
//! Upcast to non-const reference to base type.
@@ -362,7 +417,7 @@ namespace opencascade {
{
// error "type is not a member of enable_if" will be generated if T2 is not sub-type of T
// (handle is being cast to const& to handle of non-base type)
return reinterpret_cast<typename std::enable_if<is_base_but_not_same<T2, T>::value, handle<T2>&>::type>(*this);
return reinterpret_cast<typename opencascade::std::enable_if<is_base_but_not_same<T2, T>::value, handle<T2>&>::type>(*this);
}
#endif /* OCCT_HANDLE_NOCAST */

View File

@@ -24,10 +24,12 @@
// Auxiliary tools to check at compile time that class declared as base in
// DEFINE_STANDARD_RTTI* macro is actually a base class.
#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.
#if ! defined(OCC_CHECK_BASE_CLASS)
#if (defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)))
#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);
#else /* ! GCC 4.7+ */
#elif (defined(_MSC_VER) && (_MSC_VER < 1600))
// VC9 does not support static_assert and decltype at all
#define OCC_CHECK_BASE_CLASS(Class,Base)
#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 {

View File

@@ -17,7 +17,22 @@
#include <cstddef>
#include <ctime>
#include <stdint.h>
// VC9 does not have stdint.h
#if(defined(_MSC_VER) && (_MSC_VER < 1600))
// old MSVC - hasn't stdint header
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
#else
#include <stdint.h>
#endif
#if(defined(_MSC_VER) && (_MSC_VER < 1800))
// only Visual Studio 2013 (vc12) provides <cinttypes> header
@@ -64,8 +79,8 @@ typedef std::time_t Standard_Time;
// Unicode primitives, char16_t, char32_t
typedef char Standard_Utf8Char; //!< signed UTF-8 char
typedef unsigned char Standard_Utf8UChar; //!< unsigned UTF-8 char
#if (defined(__GNUC__) && !defined(__clang__) && ((__GNUC__ == 4 && __GNUC_MINOR__ <= 3) || __GNUC__ < 4))
// compatibility with old GCC compilers
#if ((defined(__GNUC__) && !defined(__clang__) && ((__GNUC__ == 4 && __GNUC_MINOR__ <= 3) || __GNUC__ < 4)) || (defined(_MSC_VER) && (_MSC_VER < 1600)))
// compatibility with old GCC and MSVC compilers
typedef uint16_t Standard_ExtCharacter;
typedef uint16_t Standard_Utf16Char;
typedef uint32_t Standard_Utf32Char;