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

0030550: Coding - Integer overflow in Standard_CString HashCodes

0030551: Foundation Classes - Integer overflow in NCollection_CellFilter HashCode

Signed integers are not used in hash code functions now to prevent undefined behavior on left shift operations with signed integers.
A possibility of negative values of hash codes is eliminated.
INT_MAX → IntegerLast() in hash code functions.
All found hash code functions behaves uniformly now: they return a value in the range [1, theUpperBound]. Relevant comments are added to such functions.
This commit is contained in:
tiv
2019-03-28 12:42:41 +03:00
committed by bugmaster
parent 833034f301
commit 2b2be3fb82
89 changed files with 878 additions and 580 deletions

View File

@@ -82,6 +82,7 @@ Standard_ShortReal.cxx
Standard_ShortReal.hxx
Standard_Size.hxx
Standard_SStream.hxx
Standard_Std.hxx
Standard_Stream.hxx
Standard_Strtod.cxx
Standard_ThreadId.hxx

View File

@@ -17,18 +17,23 @@
#include <Standard_Integer.hxx>
//============================================================================
//==== HashCode : Returns a HashCode CString
//============================================================================
inline Standard_Integer HashCode (const Standard_Address Value,
const Standard_Integer Upper)
//! Returns a hash code of the given memory pointer
//! @param thePointer the memory pointer which hash code it to be computed
//! @param theUpperBound the upper bound of the range a resulting hash code must be within
//! @return a value of a computed hash code, in range [1, UpperBound]
inline Standard_Integer HashCode (const void* const thePointer, const Standard_Integer theUpperBound)
{
union {Standard_Address L ;
Standard_Integer I[2] ;} U ;
U.I[0] = 0 ;
U.I[1] = 0 ;
U.L = Value;
return HashCode( ( ( U.I[0] ^ U.I[1] ) & 0x7fffffff ) , Upper ) ;
union
{
const void* L;
Standard_Integer I[2];
} U;
U.I[0] = 0;
U.I[1] = 0;
U.L = thePointer;
return HashCode (U.I[0] ^ U.I[1], theUpperBound);
}
//============================================================================

View File

@@ -28,31 +28,33 @@
#include <stdarg.h>
//============================================================================
//==== HashCode of a CString
// function : HashCode
// purpose :
//============================================================================
Standard_Integer HashCode (const Standard_CString Value,
const Standard_Integer Upper )
Standard_Integer HashCode (const Standard_CString theString, const Standard_Integer theUpperBound)
{
Standard_Integer aLen = (Standard_Integer)strlen(Value);
return HashCode (HashCodes (Value, aLen), Upper);
const Standard_Integer aLength = static_cast<Standard_Integer> (strlen (theString));
return HashCode (theString, aLength, theUpperBound);
}
//============================================================================
//==== HashCode of a CString
// function : HashCodes
// purpose :
//============================================================================
Standard_Integer HashCodes (const Standard_CString Value,
const Standard_Integer Len)
Standard_Integer HashCodes (const Standard_CString theString, const Standard_Integer theLength)
{
// compute DJB2 hash of a string
Standard_Integer hash = 0;
const Standard_Character *c = Value;
for (Standard_Integer i = 0; i < Len; i++, c++)
unsigned int hash = 0;
const Standard_Character* c = theString;
for (Standard_Integer i = 0; i < theLength; ++i, ++c)
{
/* hash = hash * 33 ^ c */
hash = ((hash << 5) + hash) ^ (*c);
}
return hash;
return static_cast<Standard_Integer>(hash);
}
//======================================================================

View File

@@ -31,20 +31,30 @@
#include <Standard_Integer.hxx>
//! Returns bounded hash code for a null-terminated string, in range [1, theUpper]
Standard_EXPORT Standard_Integer HashCode (const Standard_CString theStr, const Standard_Integer theUpper);
//! Returns bounded hash code for the null-terminated string, in the range [1, theUpperBound]
//! @param theString the null-terminated string which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
Standard_EXPORT Standard_Integer HashCode (Standard_CString theString, Standard_Integer theUpperBound);
//! Returns 32-bit hash code for the first theLen characters in the string theStr
Standard_EXPORT Standard_Integer HashCodes (const Standard_CString theStr, const Standard_Integer theLen);
//! Returns 32-bit hash code for the first theLen characters in the string theStr.
//! The result is unbound (may be not only positive, but also negative)
//! @param theString the string which hash code is to be computed
//! @param theLength the length of the given string
//! @return a computed hash code of the given string
Standard_EXPORT Standard_Integer HashCodes (Standard_CString theString, Standard_Integer theLength);
//! Returns bounded hash code for the first theLen characters in
//! the string theStr, in range [1, theUpper]
inline Standard_Integer HashCode (const Standard_CString theStr,
const Standard_Integer theLen,
const Standard_Integer theUpper)
//! Returns bounded hash code for the first theLength characters in the string theString, in the range [1, theUpperBound]
//! @param theString the string which hash code is to be computed
//! @param theLength the length of the initial substring of the given string which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code of the given string
inline Standard_Integer HashCode (const Standard_CString theString,
const Standard_Integer theLength,
const Standard_Integer theUpperBound)
{
// return (Abs( HashCodes( Value , Len ) ) % Upper ) + 1 ;
return HashCode (HashCodes (theStr, theLen), theUpper);
return HashCode (HashCodes (theString, theLength), theUpperBound);
}
//! Returns Standard_True if two strings are equal

View File

@@ -47,7 +47,7 @@ static Standard_Mutex theMutex;
static inline Standard_ThreadId GetThreadID()
{
#ifndef _WIN32
return pthread_self();
return (Standard_ThreadId)pthread_self();
#else
return GetCurrentThreadId();
#endif

View File

@@ -13,19 +13,22 @@
// commercial license or contractual agreement.
#include <Standard_ExtString.hxx>
#include <Standard_Type.hxx>
#include <Standard_OStream.hxx>
#include <Standard_Type.hxx>
Standard_Integer HashCode (const Standard_ExtString Value,
const Standard_Integer Upper)
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer HashCode (const Standard_ExtString theExtString, const Standard_Integer theUpperBound)
{
// compute SDBM hash of an ext string
Standard_Integer hash = 0;
for (const Standard_ExtCharacter *c = Value; *c; c++)
unsigned int hash = 0;
for (const Standard_ExtCharacter* c = theExtString; *c; ++c)
{
/* hash = hash * 33 ^ c */
hash = (*c) + (hash << 6) + (hash << 16) - hash;
}
return HashCode (hash, Upper);
return HashCode (hash, theUpperBound);
}

View File

@@ -24,9 +24,10 @@
#include <Standard_TypeDef.hxx>
//============================================================================
//==== HashCode : Returns a HashCode ExtString
//============================================================================
Standard_EXPORT Standard_Integer HashCode (const Standard_ExtString, const Standard_Integer);
//! Computes a hash code for the given wide character string, in the range [1, theUpperBound]
//! @param theExtString the wide character string which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
Standard_EXPORT Standard_Integer HashCode (Standard_ExtString theExtString, Standard_Integer theUpperBound);
#endif

View File

@@ -388,9 +388,13 @@ void Standard_GUID::ShallowDump(Standard_OStream& aStream) const
aStream << sguid;
}
Standard_Integer Standard_GUID::HashCode(const Standard_GUID& aGuid,const Standard_Integer Upper)
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer Standard_GUID::HashCode (const Standard_GUID& theGuid, const Standard_Integer theUpperBound)
{
return aGuid.Hash(Upper);
return theGuid.Hash (theUpperBound);
}
Standard_Integer Standard_GUID::Hash(const Standard_Integer Upper) const

View File

@@ -112,9 +112,12 @@ void operator = (const Standard_UUID& uid)
//! Hash function for GUID.
Standard_EXPORT Standard_Integer Hash (const Standard_Integer Upper) const;
//! H method used by collections.
Standard_EXPORT static Standard_Integer HashCode (const Standard_GUID& aguid, const Standard_Integer Upper);
//! Computes a hash code for the given GUID of the Standard_Integer type, in the range [1, theUpperBound]
//! @param theGUID the GUID which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
Standard_EXPORT static Standard_Integer HashCode (const Standard_GUID& theGUID, Standard_Integer theUpperBound);
//! Returns True when the two GUID are the same.
Standard_EXPORT static Standard_Boolean IsEqual (const Standard_GUID& string1, const Standard_GUID& string2);

View File

@@ -15,67 +15,15 @@
#define _Standard_Handle_HeaderFile
#include <Standard_Address.hxx>
#include <Standard_Std.hxx>
#include <Standard_Stream.hxx>
#include <Standard_Transient.hxx>
#include <type_traits>
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 : 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 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.
//!
//! This class is similar to boost::intrusive_ptr<>. The reference counter
@@ -462,11 +410,15 @@ namespace opencascade {
//! Define Handle() macro
#define Handle(Class) opencascade::handle<Class>
//! Global method HashCode(), for use in hash maps
template <class T>
inline Standard_Integer HashCode (const Handle(T)& theHandle, const Standard_Integer theUpper)
//! Computes a hash code for the standard handle, in the range [1, theUpperBound]
//! @param TheTransientType the type of the object the handle is referred to
//! @param theHandle the standard handle which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
template <class TheTransientType>
Standard_Integer HashCode (const Handle (TheTransientType) & theHandle, const Standard_Integer theUpperBound)
{
return ::HashCode (const_cast<Standard_Address>(static_cast<const void*>(theHandle.get())), theUpper);
return ::HashCode (theHandle.get(), theUpperBound);
}
//! For compatibility with previous versions of OCCT, define Handle_Class alias for opencascade::handle<Class>.

View File

@@ -15,6 +15,7 @@
#ifndef _Standard_Integer_HeaderFile
#define _Standard_Integer_HeaderFile
#include <Standard_Std.hxx>
#include <Standard_TypeDef.hxx>
#include <Standard_values.h>
@@ -30,54 +31,6 @@ inline Standard_Integer Abs (const Standard_Integer Value)
return Value >= 0 ? Value : -Value;
}
// ------------------------------------------------------------------
// Hascode : Computes a hascoding value for a given Integer
// ------------------------------------------------------------------
inline Standard_Integer HashCode (const Standard_Integer theMe,
const Standard_Integer theUpper)
{
//return (Abs (theMe) % theUpper) + 1;
return ((theMe & 0x7fffffff ) % theUpper) + 1;
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two integers are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_Integer theOne,
const Standard_Integer theTwo)
{
return theOne == theTwo;
}
// ------------------------------------------------------------------
// Hascode : Computes a hascoding value for a given long long integer
// ------------------------------------------------------------------
inline Standard_Integer HashCode(const long long int theMe,
const Standard_Integer theUpper)
{
return ((theMe & 0x7fffffffffffffff) % theUpper) + 1;
}
#if (defined(_LP64) || defined(__LP64__) || defined(_WIN64)) || defined(__APPLE__)
// ------------------------------------------------------------------
// Hascode : Computes a hascoding value for a given unsigned integer
// ------------------------------------------------------------------
inline Standard_Integer HashCode (const Standard_Utf32Char theMe,
const Standard_Integer theUpper)
{
return ((theMe & 0x7fffffff ) % theUpper) + 1;
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two integers are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_Utf32Char theOne,
const Standard_Utf32Char theTwo)
{
return theOne == theTwo;
}
#endif
// ------------------------------------------------------------------
// IsEven : Returns Standard_True if an integer is even
// ------------------------------------------------------------------
@@ -140,4 +93,87 @@ inline Standard_Integer IntegerLast()
inline Standard_Integer IntegerSize()
{ return BITS(Standard_Integer); }
//! Computes a hash code for the given value of some integer type, in range [1, theUpperBound]
//! @tparam TheInteger the type of the integer which hash code is to be computed
//! @param theValue the value of the TheInteger type which hash code is to be computed
//! @param theMask the mask for the last bits of the value that are used in the computation of a hash code
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in range [1, theUpperBound]
template <typename TheInteger>
typename opencascade::std::enable_if<opencascade::is_integer<TheInteger>::value, Standard_Integer>::type
IntegerHashCode (const TheInteger theValue,
const typename opencascade::disable_deduction<TheInteger>::type theMask,
const Standard_Integer theUpperBound)
{
return static_cast<Standard_Integer> ((theValue & theMask) % theUpperBound + 1);
}
//! Computes a hash code for the given value of the Standard_Integer type, in range [1, theUpperBound]
//! @param theValue the value of the Standard_Integer type which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in range [1, theUpperBound]
inline Standard_Integer HashCode (const Standard_Integer theValue,
const Standard_Integer theUpperBound)
{
// return (Abs (theMe) % theUpper) + 1;
return IntegerHashCode(theValue, IntegerLast(), theUpperBound);
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two integers are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_Integer theOne,
const Standard_Integer theTwo)
{
return theOne == theTwo;
}
//! Computes a hash value for the given unsigned integer, in range [1, theUpperBound]
//! @tparam TheUnsignedInteger the type of the given value (it is "unsigned int",
//! and must not be the same as Standard_Size, because the overload of the HashCode function
//! for Standard_Size type is already presented in Standard_Size.hxx)
//! @param theValue the unsigned integer which hash code is to be computed
//! @return a hash value computed for the given unsigned integer, in range [1, theUpperBound]
template <typename TheUnsignedInteger>
typename opencascade::std::enable_if<!opencascade::std::is_same<Standard_Size, unsigned int>::value
&& opencascade::std::is_same<TheUnsignedInteger, unsigned int>::value,
Standard_Integer>::type
HashCode (const TheUnsignedInteger theValue, const Standard_Integer theUpperBound)
{
return HashCode (static_cast<Standard_Integer> (theValue), theUpperBound);
}
//! Computes a hash code for the given value of the "long long int" type, in range [1, theUpperBound]
//! @param theValue the value of the "long long int" type which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in range [1, theUpperBound]
inline Standard_Integer HashCode (const long long int theValue, const Standard_Integer theUpperBound)
{
return IntegerHashCode(theValue, 0x7fffffffffffffff, theUpperBound);
}
#if (defined(_LP64) || defined(__LP64__) || defined(_WIN64)) || defined(__APPLE__)
//! Computes a hash code for the given value of the Standard_Utf32Char type, in range [1, theUpperBound]
//! @param theValue the value of the Standard_Utf32Char type which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in range [1, theUpperBound]
inline Standard_Integer HashCode (const Standard_Utf32Char theValue,
const Standard_Integer theUpperBound)
{
return IntegerHashCode(theValue, IntegerLast(), theUpperBound);
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two integers are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_Utf32Char theOne,
const Standard_Utf32Char theTwo)
{
return theOne == theTwo;
}
#endif
#endif

View File

@@ -22,23 +22,27 @@
static const Standard_Real ACosLimit = 1. + Epsilon(1.);
// ------------------------------------------------------------------
// Hascode : Computes a hascoding value for a given real
// ------------------------------------------------------------------
Standard_Integer HashCode(const Standard_Real me, const Standard_Integer Upper)
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer HashCode (const Standard_Real theReal, const Standard_Integer theUpperBound)
{
if (Upper < 1){
throw Standard_RangeError("Try to apply HashCode method with negative or null argument.");
if (theUpperBound < 1)
{
throw Standard_RangeError ("Try to apply HashCode method with negative or null argument.");
}
union
{
Standard_Real R;
union
{
Standard_Real R;
Standard_Integer I[2];
} U;
// U.R = Abs(me); // Treat me = -0.0 ADN 27/11/97
U.R = me ;
return HashCode( ( U.I[0] ^ U.I[1] ) , Upper ) ;
}
} U;
// U.R = Abs(me); // Treat me = -0.0 ADN 27/11/97
U.R = theReal;
return HashCode (U.I[0] ^ U.I[1], theUpperBound);
}
//-------------------------------------------------------------------
// ACos : Returns the value of the arc cosine of a real

View File

@@ -30,7 +30,12 @@
// ==================================
// Methods implemeted in Standard_Real.cxx
// ==================================
Standard_EXPORT Standard_Integer HashCode (const Standard_Real, const Standard_Integer);
//! Computes a hash code for the given real, in the range [1, theUpperBound]
//! @param theReal the real value which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
Standard_EXPORT Standard_Integer HashCode (Standard_Real theReal, Standard_Integer theUpperBound);
Standard_EXPORT Standard_Real ACos (const Standard_Real );
Standard_EXPORT Standard_Real ACosApprox (const Standard_Real );

View File

@@ -18,19 +18,22 @@
#include <Standard_Stream.hxx>
#include <Standard_OStream.hxx>
// ------------------------------------------------------------------
// Hascode : Computes a hascoding value for a given ShortReal
// ------------------------------------------------------------------
Standard_Integer HashCode(const Standard_ShortReal me, const Standard_Integer Upper)
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer HashCode (const Standard_ShortReal theShortReal, const Standard_Integer theUpperBound)
{
if (Upper < 1){
throw Standard_RangeError("Try to apply HashCode method with negative or null argument.");
if (theUpperBound < 1)
{
throw Standard_RangeError ("Try to apply HashCode method with negative or null argument.");
}
union
{
union
{
Standard_ShortReal R;
Standard_Integer I;
} U;
U.R = me;
return HashCode( U.I , Upper) ;
Standard_Integer I;
} U;
U.R = theShortReal;
return HashCode (U.I, theUpperBound);
}

View File

@@ -138,7 +138,12 @@ inline Standard_ShortReal Min (const Standard_ShortReal Val1,
// ==================================
// Methods implemeted in Standard_ShortReal.cxx
// ==================================
Standard_EXPORT Standard_Integer HashCode (const Standard_ShortReal, const Standard_Integer);
//! Computes a hash code for the given short real, in the range [1, theUpperBound]
//! @param theShortReal the short real value which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
Standard_EXPORT Standard_Integer HashCode (Standard_ShortReal theShortReal, Standard_Integer theUpperBound);
//-------------------------------------------------------------------
// IsEqual : Returns Standard_True if two ShortReals are equal

View File

@@ -16,21 +16,23 @@
#ifndef _Standard_Size_HeaderFile
#define _Standard_Size_HeaderFile
#include <Standard_Integer.hxx>
// msv 26.05.2009: add HashCode and IsEqual functions
// ------------------------------------------------------------------
// Hascode : Computes a hashcoding value for a given value
// ------------------------------------------------------------------
inline Standard_Integer HashCode(const Standard_Size Val,
const Standard_Integer Upper)
//! Computes a hash code for the given value of the Standard_Size type, in the range [1, theUpperBound]
//! @param theValue the value of the Standard_Size type which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
inline Standard_Integer HashCode (const Standard_Size theValue, const Standard_Integer theUpperBound)
{
Standard_Size aKey = ~Val + (Val << 18);
Standard_Size aKey = ~theValue + (theValue << 18);
aKey ^= (aKey >> 31);
aKey *= 21;
aKey ^= (aKey >> 11);
aKey += (aKey << 6);
aKey ^= (aKey >> 22);
return (Standard_Integer(aKey & 0x7fffffff) % Upper) + 1;
return IntegerHashCode(aKey, IntegerLast(), theUpperBound);
}
// ------------------------------------------------------------------

View File

@@ -0,0 +1,106 @@
// Created on: 2019-03-27
// Created by: Timur Izmaylov
// Copyright (c) 2019 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Standard_Std_HeaderFile
#define _Standard_Std_HeaderFile
#include <type_traits>
//! 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 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 : 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 opencascade::std::enable_if<opencascade::std::is_same<T1, T2>::value>::type>
: opencascade::std::false_type
{
};
//! The type trait that checks if the passed type is integer (it must be integral and not boolean)
//! @tparam TheInteger the checked type
template <typename TheInteger>
struct is_integer : std::integral_constant<bool,
opencascade::std::is_integral<TheInteger>::value
&& !opencascade::std::is_same<TheInteger, bool>::value>
{
};
//! The auxiliary template that is used for template argument deduction in function templates. A function argument
//! which type is a template type parameter and it is not needed to be deducted must be declared using this class
//! template based on the type of some other template type parameter of a function template
//! @tparam TheType the type that is used as a function argument type to prevent its deduction
template <typename TheType>
struct disable_deduction
{
typedef TheType type;
};
} // namespace opencascade
#endif

View File

@@ -16,25 +16,9 @@
#ifndef Standard_ThreadId_HeaderFile
#define Standard_ThreadId_HeaderFile
// Platform-dependent definition of the thread identifier type
#include <Standard_Size.hxx>
#ifdef _WIN32
#include <windows.h>
typedef DWORD Standard_ThreadId;
inline Standard_Integer HashCode(const Standard_ThreadId Value,
const Standard_Integer Upper)
{
// Size of int == size of unsigned long == 4 for WIN32 and WIN64
return HashCode((Standard_Integer)Value, Upper);
}
#else
#include <pthread.h>
typedef pthread_t Standard_ThreadId;
#endif
// Platform-independent definition of the thread identifier type
typedef Standard_Size Standard_ThreadId;
#endif

View File

@@ -105,10 +105,15 @@ private:
mutable volatile Standard_Integer count;
};
//! Global method HashCode(), for use in hash maps
inline Standard_Integer HashCode (const Standard_Transient* theObject, const Standard_Integer theUpper)
//! Computes a hash code for the given transient object, in the range [1, theUpperBound]
//! @param theTransientObject the transient object which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
inline Standard_Integer HashCode (const Standard_Transient* const theTransientObject,
const Standard_Integer theUpperBound)
{
return ::HashCode ((Standard_Address*)theObject, theUpper);
return ::HashCode (static_cast<const void*> (theTransientObject), theUpperBound);
}
//! Definition of Handle_Standard_Transient as typedef for compatibility

View File

@@ -74,9 +74,13 @@ namespace {
// Value-based hasher for plain C string (char*)
struct CStringHasher
{
static Standard_Integer HashCode (const Standard_CString& theKey, const Standard_Integer Upper)
//! Computes a hash code of the given Standard_CString, in the range [1, theUpperBound]
//! @param theKey the key which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in the range [1, theUpperBound]
static Standard_Integer HashCode (const Standard_CString& theKey, const Standard_Integer theUpperBound)
{
return ::HashCode (theKey, Upper);
return ::HashCode (theKey, theUpperBound);
}
static bool IsEqual (const Standard_CString& theKey1, const Standard_CString& theKey2)
{