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:
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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>.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 );
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
106
src/Standard/Standard_Std.hxx
Normal file
106
src/Standard/Standard_Std.hxx
Normal 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
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user