1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0033370: Foundation Classes - Moving into STL and Boost functionality

NCollection containers update:
  - NCollection_Array1 - updated functionality
  - NCollection_Array2 - NCollection_Array1 as a wrapper for 2array
  - NCollection_Vector -> NCollection_DynamicArray was renamed and reworked.
TCollection:
  - Use static empty string to avoid allocations on empty string
 NCollection allocators update:
  - NCollection_Allocator - allocator that used Standard::Allocate
  - NCollection_OccAllocator - allocator-wrapper that used OCC BaseAllocator objects
  - NCollection_IncAllocator - rework to increase performance
Standard:
  - Rework functionality to use different allocation libs
  - Implement basic of new way to wrap allocations tools
  - Define 4 ways to allocation (defines in configure stage)
 Additional changes:
  - Hash function uses std::hash functionality
   - size_t as a hash value
  - New HashUtils with Murmur and FVN hash algo for x32 and x64
  - Deprecated _0.cxx and .gxx DE classes reorganized
  - Create own utility for std memory
  - Update Standard_Transient to be more platform-independent
 Math TK changes:
  - math_Vector -> match_BaseVector<>
    - Buffer decreased to cash 32 elements instead of 512
This commit is contained in:
dpasukhi
2023-08-05 17:53:19 +01:00
parent 6dbfade692
commit 1103eb60af
649 changed files with 10704 additions and 12037 deletions

View File

@@ -1,7 +1,6 @@
Standard.cxx
Standard.hxx
Standard_AbortiveTransaction.hxx
Standard_Address.hxx
Standard_ArrayStreamBuffer.hxx
Standard_ArrayStreamBuffer.cxx
Standard_Assert.hxx
@@ -17,6 +16,7 @@ Standard_ConstructionError.hxx
Standard_Copy.tcl
Standard_CString.cxx
Standard_CString.hxx
Standard_CStringHasher.hxx
Standard_DefineAlloc.hxx
Standard_DefineException.hxx
Standard_DefineHandle.hxx
@@ -29,8 +29,6 @@ Standard_Dump.hxx
Standard_ErrorHandler.cxx
Standard_ErrorHandler.hxx
Standard_ExtCharacter.hxx
Standard_ExtString.cxx
Standard_ExtString.hxx
Standard_Failure.cxx
Standard_Failure.hxx
Standard_WarningDisableFunctionCast.hxx
@@ -38,6 +36,8 @@ Standard_GUID.cxx
Standard_GUID.hxx
Standard_Handle.hxx
Standard_HandlerStatus.hxx
Standard_HashUtils.hxx
Standard_HashUtils.lxx
Standard_ImmutableObject.hxx
Standard_Integer.hxx
Standard_IStream.hxx
@@ -45,16 +45,11 @@ Standard_JmpBuf.hxx
Standard_LicenseError.hxx
Standard_LicenseNotFound.hxx
Standard_Macro.hxx
Standard_math.cxx
Standard_math.hxx
Standard_MemoryUtils.hxx
Standard_MMgrOpt.cxx
Standard_MMgrOpt.hxx
Standard_MMgrRaw.cxx
Standard_MMgrRaw.hxx
Standard_MMgrRoot.cxx
Standard_MMgrRoot.hxx
Standard_MMgrTBBalloc.cxx
Standard_MMgrTBBalloc.hxx
Standard_MultiplyDefined.hxx
Standard_Mutex.cxx
Standard_Mutex.hxx
@@ -83,9 +78,7 @@ Standard_ReadBuffer.hxx
Standard_ReadLineBuffer.hxx
Standard_Real.cxx
Standard_Real.hxx
Standard_ShortReal.cxx
Standard_ShortReal.hxx
Standard_Size.hxx
Standard_SStream.hxx
Standard_StackTrace.cxx
Standard_Std.hxx
@@ -101,7 +94,6 @@ Standard_TypeDef.hxx
Standard_TypeMismatch.hxx
Standard_Underflow.hxx
Standard_UUID.hxx
Standard_values.h
Standard_Version.hxx
Standard_WarningsDisable.hxx
Standard_WarningsRestore.hxx
Standard_WarningsRestore.hxx

View File

@@ -1,7 +1,4 @@
// Created on: 2005-03-15
// Created by: Peter KURNEV
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
// Copyright (c) 1999-2023 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
@@ -14,26 +11,70 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Standard.hxx>
#include <Standard_MMgrOpt.hxx>
#include <Standard_MMgrRaw.hxx>
#include <Standard_MMgrTBBalloc.hxx>
#include <Standard_Assert.hxx>
#include <Standard_OutOfMemory.hxx>
#include <stdlib.h>
#if(defined(_WIN32) || defined(__WIN32__))
#include <windows.h>
#include <malloc.h>
#include <locale.h>
#include <windows.h>
#include <malloc.h>
#include <locale.h>
#endif
#if defined(_MSC_VER) || defined(__ANDROID__) || defined(__QNX__)
#include <malloc.h>
#include <malloc.h>
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
#include <mm_malloc.h>
#include <mm_malloc.h>
#else
extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theSize);
extern "C" int posix_memalign(void** thePtr, size_t theAlign, size_t theSize);
#endif
// Temp define, after it will be part of CMake
#define OCCT_MMGT_OPT_NATIVE
namespace
{
static Standard::AllocatorType& allocatorTypeInstance()
{
static Standard::AllocatorType aType =
#ifdef OCCT_MMGT_OPT_FLEXIBLE
Standard::AllocatorType::NATIVE;
#elif defined OCCT_MMGT_OPT_NATIVE
Standard::AllocatorType::NATIVE;
#elif defined OCCT_MMGT_OPT_TBB
Standard::AllocatorType::TBB;
#elif defined OCCT_MMGT_OPT_JEMALLOC
Standard::AllocatorType::JEMALLOC;
#endif
return aType;
}
}
#ifdef OCCT_MMGT_OPT_JEMALLOC
#define JEMALLOC_NO_DEMANGLE
#include <jemalloc/jemalloc.h>
#endif // OCCT_MMGT_OPT_JEMALLOC
// Available macros definition
// - OCCT_MMGT_OPT_FLEXIBLE, modifiable in real time
// - OCCT_MMGT_OPT_TBB, using tbb::scalable_allocator
// - OCCT_MMGT_OPT_NATIVE, using native calloc, free
// - OCCT_MMGT_OPT_JEMALLOC, using external jecalloc, jefree
#ifdef OCCT_MMGT_OPT_FLEXIBLE
#include <Standard_MMgrOpt.hxx>
#include <Standard_Assert.hxx>
// paralleling with Intel TBB
#ifdef HAVE_TBB
#pragma comment (lib, "tbbmalloc.lib")
#include <tbb/scalable_allocator.h>
#else
#define scalable_malloc malloc
#define scalable_calloc calloc
#define scalable_realloc realloc
#define scalable_free free
#endif
// There is no support for environment variables in UWP
@@ -45,270 +86,437 @@
#ifndef OCCT_MMGT_OPT_DEFAULT
#define OCCT_MMGT_OPT_DEFAULT 0
#endif
//=======================================================================
//class : Standard_MMgrFactory
//purpose : Container for pointer to memory manager;
// used to construct appropriate memory manager according
// to environment settings, and to ensure destruction upon exit
//=======================================================================
class Standard_MMgrFactory
namespace
{
public:
static Standard_MMgrRoot* GetMMgr();
~Standard_MMgrFactory();
/**
* Implementation of raw OCC memory manager which uses standard C
* functions: malloc (or calloc), free and realloc
* without any optimization
*/
class Standard_MMgrRaw : public Standard_MMgrRoot
{
public:
//! Constructor; if theToClear is True, the memory will be nullified
//! upon allocation.
Standard_MMgrRaw(const Standard_Boolean theToClear = Standard_False)
{
myClear = theToClear;
}
private:
Standard_MMgrFactory();
Standard_MMgrFactory (const Standard_MMgrFactory&);
Standard_MMgrFactory& operator= (const Standard_MMgrFactory&);
//! Allocate theSize bytes
Standard_Address Allocate(const Standard_Size theSize) override
{
// we use ?: operator instead of if() since it is faster :-)
Standard_Address aPtr = (myClear ? calloc(theSize, sizeof(char)) :
malloc(theSize));
if (!aPtr)
throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
return aPtr;
}
private:
Standard_MMgrRoot* myFMMgr;
};
//! Reallocate thePtr to the size theSize.
//! The new pointer is returned.
Standard_Address Reallocate(Standard_Address thePtr,
const Standard_Size theSize) override
{
Standard_Address newStorage = (Standard_Address)realloc(thePtr, theSize);
if (!newStorage)
throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
// Note that it is not possible to ensure that additional memory
// allocated by realloc will be cleared (so as to satisfy myClear mode);
// in order to do that we would need using memset...
return newStorage;
}
//=======================================================================
//function : Standard_MMgrFactory
//purpose : Check environment variables and create appropriate memory manager
//=======================================================================
//! Free allocated memory. The pointer is nullified.
void Free(Standard_Address thePtr) override
{
free(thePtr);
}
Standard_MMgrFactory::Standard_MMgrFactory()
: myFMMgr (NULL)
{
/*#if defined(_MSC_VER) && (_MSC_VER > 1400)
// Turn ON thread-safe C locale globally to avoid side effects by setlocale() calls between threads.
// After this call all following _configthreadlocale() will be ignored assuming
// Notice that this is MSVCRT feature - on POSIX systems xlocale API (uselocale instead of setlocale)
// should be used explicitly to ensure thread-safety!
protected:
Standard_Boolean myClear; //! Option to nullify allocated memory
};
// This is not well documented call because _ENABLE_PER_THREAD_LOCALE_GLOBAL flag is defined but not implemented for some reason.
// -1 will set global locale flag to force _ENABLE_PER_THREAD_LOCALE_GLOBAL + _ENABLE_PER_THREAD_LOCALE_NEW behaviour
// although there NO way to turn it off again and following calls will have no effect (locale will be changed only for current thread).
_configthreadlocale (-1);
#endif*/
//! Implementation of OCC memory manager which uses Intel TBB
//! scalable allocator.
//!
//! On configurations where TBB is not available standard RTL functions
//! malloc() / free() are used.
class Standard_MMgrTBBalloc : public Standard_MMgrRoot
{
public:
//! Constructor; if theClear is True, the memory will be nullified
//! upon allocation.
Standard_MMgrTBBalloc(const Standard_Boolean theClear = Standard_False)
{
myClear = theClear;
}
// Check basic assumption.
// If assertion happens, then OCCT should be corrected for compatibility with such CPU architecture.
Standard_STATIC_ASSERT(sizeof(Standard_Utf8Char) == 1);
Standard_STATIC_ASSERT(sizeof(short) == 2);
Standard_STATIC_ASSERT(sizeof(Standard_Utf16Char) == 2);
Standard_STATIC_ASSERT(sizeof(Standard_Utf32Char) == 4);
//! Allocate theSize bytes
Standard_Address Allocate(const Standard_Size theSize) override
{
// we use ?: operator instead of if() since it is faster :-)
Standard_Address aPtr = (myClear ? scalable_calloc(theSize, sizeof(char)) :
scalable_malloc(theSize));
if (!aPtr)
throw Standard_OutOfMemory("Standard_MMgrTBBalloc::Allocate(): malloc failed");
return aPtr;
}
//! Reallocate thePtr to the size theSize.
//! The new pointer is returned.
Standard_Address Reallocate(Standard_Address thePtr,
const Standard_Size theSize) override
{
Standard_Address newStorage = (Standard_Address)scalable_realloc(thePtr, theSize);
if (!newStorage)
throw Standard_OutOfMemory("Standard_MMgrTBBalloc::Reallocate(): realloc failed");
// Note that it is not possible to ensure that additional memory
// allocated by realloc will be cleared (so as to satisfy myClear mode);
// in order to do that we would need using memset...
return newStorage;
}
//! Free allocated memory
void Free(Standard_Address thePtr) override
{
scalable_free(thePtr);
}
protected:
Standard_Boolean myClear; //! Option to nullify allocated memory
};
//=======================================================================
//class : Standard_MMgrFactory
//purpose : Container for pointer to memory manager;
// used to construct appropriate memory manager according
// to environment settings, and to ensure destruction upon exit
//=======================================================================
class Standard_MMgrFactory
{
public:
static Standard_MMgrRoot* GetMMgr();
~Standard_MMgrFactory();
private:
Standard_MMgrFactory();
Standard_MMgrFactory(const Standard_MMgrFactory&);
Standard_MMgrFactory& operator= (const Standard_MMgrFactory&);
private:
Standard_MMgrRoot* myFMMgr;
};
//=======================================================================
//function : Standard_MMgrFactory
//purpose : Check environment variables and create appropriate memory manager
//=======================================================================
Standard_MMgrFactory::Standard_MMgrFactory()
: myFMMgr(NULL)
{
/*#if defined(_MSC_VER) && (_MSC_VER > 1400)
// Turn ON thread-safe C locale globally to avoid side effects by setlocale() calls between threads.
// After this call all following _configthreadlocale() will be ignored assuming
// Notice that this is MSVCRT feature - on POSIX systems xlocale API (uselocale instead of setlocale)
// should be used explicitly to ensure thread-safety!
// This is not well documented call because _ENABLE_PER_THREAD_LOCALE_GLOBAL flag is defined but not implemented for some reason.
// -1 will set global locale flag to force _ENABLE_PER_THREAD_LOCALE_GLOBAL + _ENABLE_PER_THREAD_LOCALE_NEW behaviour
// although there NO way to turn it off again and following calls will have no effect (locale will be changed only for current thread).
_configthreadlocale (-1);
#endif*/
// Check basic assumption.
// If assertion happens, then OCCT should be corrected for compatibility with such CPU architecture.
Standard_STATIC_ASSERT(sizeof(Standard_Utf8Char) == 1);
Standard_STATIC_ASSERT(sizeof(short) == 2);
Standard_STATIC_ASSERT(sizeof(Standard_Utf16Char) == 2);
Standard_STATIC_ASSERT(sizeof(Standard_Utf32Char) == 4);
#ifdef _WIN32
Standard_STATIC_ASSERT(sizeof(Standard_WideChar) == sizeof(Standard_Utf16Char));
Standard_STATIC_ASSERT(sizeof(Standard_WideChar) == sizeof(Standard_Utf16Char));
#endif
char* aVar;
aVar = getenv ("MMGT_OPT");
Standard_Integer anAllocId = (aVar ? atoi (aVar): OCCT_MMGT_OPT_DEFAULT);
char* aVar;
aVar = getenv("MMGT_OPT");
Standard_Integer anAllocId = (aVar ? atoi(aVar) : OCCT_MMGT_OPT_DEFAULT);
#if defined(HAVE_TBB) && defined(_M_IX86)
if (anAllocId == 2)
{
// CR25396: Check if SSE2 instructions are supported on 32-bit x86 processor on Windows platform,
// if not then use MMgrRaw instead of MMgrTBBalloc.
// It is to avoid runtime crash when running on a CPU
// that supports SSE but does not support SSE2 (some modifications of AMD Sempron).
static const DWORD _SSE2_FEATURE_BIT(0x04000000);
DWORD volatile dwFeature;
_asm
if (anAllocId == 2)
{
push eax
push ebx
push ecx
push edx
// CR25396: Check if SSE2 instructions are supported on 32-bit x86 processor on Windows platform,
// if not then use MMgrRaw instead of MMgrTBBalloc.
// It is to avoid runtime crash when running on a CPU
// that supports SSE but does not support SSE2 (some modifications of AMD Sempron).
static const DWORD _SSE2_FEATURE_BIT(0x04000000);
DWORD volatile dwFeature;
_asm
{
push eax
push ebx
push ecx
push edx
// get the CPU feature bits
mov eax, 1
cpuid
mov dwFeature, edx
// get the CPU feature bits
mov eax, 1
cpuid
mov dwFeature, edx
pop edx
pop ecx
pop ebx
pop eax
pop edx
pop ecx
pop ebx
pop eax
}
if ((dwFeature & _SSE2_FEATURE_BIT) == 0)
anAllocId = 0;
}
if ((dwFeature & _SSE2_FEATURE_BIT) == 0)
anAllocId = 0;
}
#endif
aVar = getenv ("MMGT_CLEAR");
Standard_Boolean toClear = (aVar ? (atoi (aVar) != 0) : Standard_True);
aVar = getenv("MMGT_CLEAR");
Standard_Boolean toClear = (aVar ? (atoi(aVar) != 0) : Standard_True);
// on Windows (actual for XP and 2000) activate low fragmentation heap
// for CRT heap in order to get best performance.
// Environment variable MMGT_LFH can be used to switch off this action (if set to 0)
// on Windows (actual for XP and 2000) activate low fragmentation heap
// for CRT heap in order to get best performance.
// Environment variable MMGT_LFH can be used to switch off this action (if set to 0)
#if defined(_MSC_VER)
aVar = getenv ("MMGT_LFH");
if ( aVar == NULL || atoi (aVar) != 0 )
{
ULONG aHeapInfo = 2;
HANDLE aCRTHeap = (HANDLE)_get_heap_handle();
HeapSetInformation (aCRTHeap, HeapCompatibilityInformation, &aHeapInfo, sizeof(aHeapInfo));
}
aVar = getenv("MMGT_LFH");
if (aVar == NULL || atoi(aVar) != 0)
{
ULONG aHeapInfo = 2;
HANDLE aCRTHeap = (HANDLE)_get_heap_handle();
HeapSetInformation(aCRTHeap, HeapCompatibilityInformation, &aHeapInfo, sizeof(aHeapInfo));
}
#endif
switch (anAllocId)
{
case 1: // OCCT optimized memory allocator
switch (anAllocId)
{
aVar = getenv ("MMGT_MMAP");
Standard_Boolean bMMap = (aVar ? (atoi (aVar) != 0) : Standard_True);
aVar = getenv ("MMGT_CELLSIZE");
Standard_Integer aCellSize = (aVar ? atoi (aVar) : 200);
aVar = getenv ("MMGT_NBPAGES");
Standard_Integer aNbPages = (aVar ? atoi (aVar) : 1000);
aVar = getenv ("MMGT_THRESHOLD");
Standard_Integer aThreshold = (aVar ? atoi (aVar) : 40000);
myFMMgr = new Standard_MMgrOpt (toClear, bMMap, aCellSize, aNbPages, aThreshold);
break;
case 1: // OCCT optimized memory allocator
{
aVar = getenv("MMGT_MMAP");
Standard_Boolean bMMap = (aVar ? (atoi(aVar) != 0) : Standard_True);
aVar = getenv("MMGT_CELLSIZE");
Standard_Integer aCellSize = (aVar ? atoi(aVar) : 200);
aVar = getenv("MMGT_NBPAGES");
Standard_Integer aNbPages = (aVar ? atoi(aVar) : 1000);
aVar = getenv("MMGT_THRESHOLD");
Standard_Integer aThreshold = (aVar ? atoi(aVar) : 40000);
myFMMgr = new Standard_MMgrOpt(toClear, bMMap, aCellSize, aNbPages, aThreshold);
break;
}
case 2: // TBB memory allocator
myFMMgr = new Standard_MMgrTBBalloc(toClear);
break;
case 0:
default: // system default memory allocator
myFMMgr = new Standard_MMgrRaw(toClear);
}
case 2: // TBB memory allocator
myFMMgr = new Standard_MMgrTBBalloc (toClear);
break;
case 0:
default: // system default memory allocator
myFMMgr = new Standard_MMgrRaw (toClear);
allocatorTypeInstance() = static_cast<Standard::AllocatorType>(anAllocId);
}
//=======================================================================
//function : ~Standard_MMgrFactory
//purpose :
//=======================================================================
Standard_MMgrFactory::~Standard_MMgrFactory()
{
if (myFMMgr)
myFMMgr->Purge(Standard_True);
}
//=======================================================================
// function: GetMMgr
//
// This static function has a purpose to wrap static holder for memory
// manager instance.
//
// Wrapping holder inside a function is needed to ensure that it will
// be initialized not later than the first call to memory manager (that
// would be impossible to guarantee if holder was static variable on
// global or file scope, because memory manager may be called from
// constructors of other static objects).
//
// Note that at the same time we could not guarantee that the holder
// object is destroyed after last call to memory manager, since that
// last call may be from static Handle() object which has been initialized
// dynamically during program execution rather than in its constructor.
//
// Therefore holder currently does not call destructor of the memory manager
// but only its method Purge() with Standard_True.
//
// To free the memory completely, we probably could use compiler-specific
// pragmas (such as '#pragma fini' on SUN Solaris and '#pragma init_seg' on
// WNT MSVC++) to put destructing function in code segment that is called
// after destructors of other (even static) objects. However, this is not
// done by the moment since it is compiler-dependent and there is no guarantee
// that some other object calling memory manager is not placed also in that segment...
//
// Note that C runtime function atexit() could not help in this problem
// since its behaviour is the same as for destructors of static objects
// (see ISO 14882:1998 "Programming languages -- C++" 3.6.3)
//
// The correct approach to deal with the problem would be to have memory manager
// to properly control its memory allocation and caching free blocks so
// as to release all memory as soon as it is returned to it, and probably
// even delete itself if all memory it manages has been released and
// last call to method Purge() was with True.
//
// Note that one possible method to control memory allocations could
// be counting calls to Allocate() and Free()...
//
//=======================================================================
Standard_MMgrRoot* Standard_MMgrFactory::GetMMgr()
{
static Standard_MMgrFactory aFactory;
return aFactory.myFMMgr;
}
}
#endif // OCCT_MMGT_OPT_FLEXIBLE
//=======================================================================
//function : ~Standard_MMgrFactory
//purpose :
//function : Allocate
//purpose :
//=======================================================================
Standard_MMgrFactory::~Standard_MMgrFactory()
Standard::AllocatorType Standard::GetAllocatorType()
{
if ( myFMMgr )
myFMMgr->Purge(Standard_True);
}
//=======================================================================
// function: GetMMgr
//
// This static function has a purpose to wrap static holder for memory
// manager instance.
//
// Wrapping holder inside a function is needed to ensure that it will
// be initialized not later than the first call to memory manager (that
// would be impossible to guarantee if holder was static variable on
// global or file scope, because memory manager may be called from
// constructors of other static objects).
//
// Note that at the same time we could not guarantee that the holder
// object is destroyed after last call to memory manager, since that
// last call may be from static Handle() object which has been initialized
// dynamically during program execution rather than in its constructor.
//
// Therefore holder currently does not call destructor of the memory manager
// but only its method Purge() with Standard_True.
//
// To free the memory completely, we probably could use compiler-specific
// pragmas (such as '#pragma fini' on SUN Solaris and '#pragma init_seg' on
// WNT MSVC++) to put destructing function in code segment that is called
// after destructors of other (even static) objects. However, this is not
// done by the moment since it is compiler-dependent and there is no guarantee
// that some other object calling memory manager is not placed also in that segment...
//
// Note that C runtime function atexit() could not help in this problem
// since its behaviour is the same as for destructors of static objects
// (see ISO 14882:1998 "Programming languages -- C++" 3.6.3)
//
// The correct approach to deal with the problem would be to have memory manager
// to properly control its memory allocation and caching free blocks so
// as to release all memory as soon as it is returned to it, and probably
// even delete itself if all memory it manages has been released and
// last call to method Purge() was with True.
//
// Note that one possible method to control memory allocations could
// be counting calls to Allocate() and Free()...
//
//=======================================================================
Standard_MMgrRoot* Standard_MMgrFactory::GetMMgr()
{
static Standard_MMgrFactory aFactory;
return aFactory.myFMMgr;
return allocatorTypeInstance();
}
//=======================================================================
//function : Allocate
//purpose :
//purpose :
//=======================================================================
Standard_Address Standard::Allocate(const Standard_Size size)
Standard_Address Standard::Allocate(const Standard_Size theSize)
{
return Standard_MMgrFactory::GetMMgr()->Allocate(size);
#ifdef OCCT_MMGT_OPT_FLEXIBLE
return Standard_MMgrFactory::GetMMgr()->Allocate(theSize);
#elif defined OCCT_MMGT_OPT_NATIVE
Standard_Address aPtr = calloc(theSize, sizeof(char));
if (!aPtr)
throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
return aPtr;
#elif defined OCCT_MMGT_OPT_JEMALLOC
Standard_Address aPtr = je_calloc(theSize, sizeof(char));
if (!aPtr)
throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
return aPtr;
#endif // OCCT_MMGT_OPT_FLEXIBLE
}
//=======================================================================
//function : AllocateOptimal
//purpose :
//=======================================================================
Standard_Address Standard::AllocateOptimal(const Standard_Size theSize)
{
#ifdef OCCT_MMGT_OPT_FLEXIBLE
return Standard_MMgrFactory::GetMMgr()->Allocate(theSize);
#elif defined OCCT_MMGT_OPT_NATIVE
return malloc(theSize);
#elif defined OCCT_MMGT_OPT_JEMALLOC
return je_malloc(theSize);
#endif
}
//=======================================================================
//function : Free
//purpose :
//purpose :
//=======================================================================
void Standard::Free (Standard_Address theStorage)
void Standard::Free(Standard_Address theStorage)
{
#ifdef OCCT_MMGT_OPT_FLEXIBLE
Standard_MMgrFactory::GetMMgr()->Free(theStorage);
#elif defined OCCT_MMGT_OPT_NATIVE
free(theStorage);
#elif defined OCCT_MMGT_OPT_JEMALLOC
return je_free(theStorage);
#endif
}
//=======================================================================
//function : Reallocate
//purpose :
//purpose :
//=======================================================================
Standard_Address Standard::Reallocate (Standard_Address theStorage,
const Standard_Size theSize)
Standard_Address Standard::Reallocate(Standard_Address theStorage,
const Standard_Size theSize)
{
return Standard_MMgrFactory::GetMMgr()->Reallocate (theStorage, theSize);
// Note that it is not possible to ensure that additional memory
// allocated by realloc will be cleared (so as to satisfy myClear mode);
// in order to do that we would need using memset..
#ifdef OCCT_MMGT_OPT_FLEXIBLE
return Standard_MMgrFactory::GetMMgr()->Reallocate(theStorage, theSize);
#elif defined OCCT_MMGT_OPT_NATIVE
Standard_Address aNewStorage = (Standard_Address)realloc(theStorage, theSize);
if (!aNewStorage)
throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
return aNewStorage;
#elif defined OCCT_MMGT_OPT_JEMALLOC
Standard_Address newStorage = (Standard_Address)je_realloc(theStorage, theSize);
if (!newStorage)
throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
return newStorage;
#endif
}
//=======================================================================
//function : Purge
//purpose :
//purpose :
//=======================================================================
Standard_Integer Standard::Purge()
{
#ifdef OCCT_MMGT_OPT_FLEXIBLE
return Standard_MMgrFactory::GetMMgr()->Purge();
#else
return true;
#endif // OCCT_MMGT_OPT_FLEXIBLE
}
//=======================================================================
//function : AllocateAligned
//purpose :
//=======================================================================
Standard_Address Standard::AllocateAligned (const Standard_Size theSize,
const Standard_Size theAlign)
Standard_Address Standard::AllocateAligned(const Standard_Size theSize,
const Standard_Size theAlign)
{
#if defined(OCCT_MMGT_OPT_FLEXIBLE) || defined(OCCT_MMGT_OPT_NATIVE)
#if defined(_MSC_VER)
return _aligned_malloc (theSize, theAlign);
return _aligned_malloc(theSize, theAlign);
#elif defined(__ANDROID__) || defined(__QNX__)
return memalign (theAlign, theSize);
return memalign(theAlign, theSize);
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
return _mm_malloc (theSize, theAlign);
return _mm_malloc(theSize, theAlign);
#else
void* aPtr;
if (posix_memalign (&aPtr, theAlign, theSize))
if (posix_memalign(&aPtr, theAlign, theSize))
{
return NULL;
}
return aPtr;
#endif
#elif defined OCCT_MMGT_OPT_JEMALLOC
return je_aligned_alloc(theAlign, theSize);
#endif
}
//=======================================================================
//function : FreeAligned
//purpose :
//=======================================================================
void Standard::FreeAligned (Standard_Address thePtrAligned)
void Standard::FreeAligned(Standard_Address thePtrAligned)
{
#if defined(OCCT_MMGT_OPT_FLEXIBLE) || defined(OCCT_MMGT_OPT_NATIVE)
#if defined(_MSC_VER)
_aligned_free (thePtrAligned);
_aligned_free(thePtrAligned);
#elif defined(__ANDROID__) || defined(__QNX__)
free (thePtrAligned);
free(thePtrAligned);
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
_mm_free (thePtrAligned);
_mm_free(thePtrAligned);
#else
free (thePtrAligned);
free(thePtrAligned);
#endif
#elif defined OCCT_MMGT_OPT_JEMALLOC
return je_free(thePtrAligned);
#endif
}

View File

@@ -18,11 +18,8 @@
#define _Standard_HeaderFile
#include <Standard_DefineAlloc.hxx>
#include <Standard_Address.hxx>
#include <Standard_Size.hxx>
#include <Standard_Integer.hxx>
//! The package Standard provides global memory allocator and other basic
//! services used by other OCCT components.
@@ -32,10 +29,25 @@ public:
DEFINE_STANDARD_ALLOC
//! Enumiration of possible allocator types
enum class AllocatorType
{
NATIVE = 0,
OPT = 1,
TBB = 2,
JEMALLOC = 3
};
//! Returns default allocator type
Standard_EXPORT static AllocatorType GetAllocatorType();
//! Allocates memory blocks
//! aSize - bytes to allocate
Standard_EXPORT static Standard_Address Allocate (const Standard_Size aSize);
//! theSize - bytes to allocate
Standard_EXPORT static Standard_Address Allocate (const Standard_Size theSize);
//! Allocates memory blocks
//! theSize - bytes to allocate
Standard_EXPORT static Standard_Address AllocateOptimal (const Standard_Size theSize);
//! Deallocates memory blocks
//! @param thePtr - previously allocated memory block to be freed
@@ -51,9 +63,9 @@ public:
}
//! Reallocates memory blocks
//! aStorage - previously allocated memory block
//! aNewSize - new size in bytes
Standard_EXPORT static Standard_Address Reallocate (const Standard_Address aStorage, const Standard_Size aNewSize);
//! theStorage - previously allocated memory block
//! theNewSize - new size in bytes
Standard_EXPORT static Standard_Address Reallocate (const Standard_Address theStorage, const Standard_Size theNewSize);
//! Allocates aligned memory blocks.
//! Should be used with CPU instructions which require specific alignment.
@@ -104,8 +116,4 @@ public:
};
// include definition of handle to make it always visible
// (put at the and of the file due to cyclic dependency between headers)
#include <Standard_Transient.hxx>
#endif // _Standard_HeaderFile

View File

@@ -1,47 +0,0 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 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_Address_HeaderFile
#define _Standard_Address_HeaderFile
#include <Standard_Integer.hxx>
//! 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
{
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);
}
//============================================================================
// IsEqual : Returns Standard_True if two CString have the same value
//============================================================================
inline Standard_Boolean IsEqual(const Standard_Address One
,const Standard_Address Two)
{ return One == Two; }
#endif

View File

@@ -24,36 +24,6 @@
#include <string.h>
#include <stdarg.h>
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer HashCode (const Standard_CString theString, const Standard_Integer theUpperBound)
{
const Standard_Integer aLength = static_cast<Standard_Integer> (strlen (theString));
return HashCode (theString, aLength, theUpperBound);
}
//============================================================================
// function : HashCodes
// purpose :
//============================================================================
Standard_Integer HashCodes (const Standard_CString theString, const Standard_Integer theLength)
{
// compute DJB2 hash of a string
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 static_cast<Standard_Integer>(hash);
}
//======================================================================
// Locale-independent equivalents of C functions dealing with conversion
// of string to real and vice-versa
@@ -89,13 +59,6 @@ Standard_Integer HashCodes (const Standard_CString theString, const Standard_Int
#define vfprintf_l(theFile, theLocale, theFormat, theArgPtr) vfprintf(theFile, theFormat, theArgPtr)
#endif
/*
double Strtod (const char* theStr, char** theNextPtr)
{
return strtod_l (theStr, theNextPtr, Standard_CLocaleSentry::GetCLocale());
}
*/
double Atof (const char* theStr)
{
return Strtod (theStr, NULL);

View File

@@ -36,33 +36,7 @@
// C++ only definitions
#ifdef __cplusplus
#include <Standard_Integer.hxx>
//! 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.
//! 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 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 (theString, theLength), theUpperBound);
}
#include <Standard_TypeDef.hxx>
//! Returns Standard_True if two strings are equal
inline Standard_Boolean IsEqual (const Standard_CString theOne, const Standard_CString theTwo)

View File

@@ -0,0 +1,45 @@
// Copyright (c) 2023 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_CStringHasher_HeaderFile
#define _Standard_CStringHasher_HeaderFile
#include <Standard_CString.hxx>
#include <Standard_HashUtils.hxx>
#include <Standard_TypeDef.hxx>
#include <functional>
class Standard_CStringHasher
{
public:
size_t operator()(const Standard_CString& theString) const noexcept
{
const int aLen = static_cast<int>(strlen(theString));
if (aLen < 4)
{
return opencascade::FNVHash::hash_combine(*theString, aLen);
}
return opencascade::hashBytes(theString, aLen);
}
bool operator()(const Standard_CString& theString1,
const Standard_CString& theString2) const noexcept
{
return strcmp(theString1, theString2) == 0;
}
};
#endif

View File

@@ -1,34 +0,0 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 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.
#include <Standard_ExtString.hxx>
#include <Standard_Type.hxx>
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer HashCode (const Standard_ExtString theExtString, const Standard_Integer theUpperBound)
{
// compute SDBM hash of an ext string
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, theUpperBound);
}

View File

@@ -1,33 +0,0 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 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.
//============================================================================
//==== Title: Standard_ExtString.hxx
//====
//==== Implementation: This is a primitive type implementadef with typedef
//==== typedef short* Standard_ExtString;
//============================================================================
#ifndef _Standard_ExtString_HeaderFile
#define _Standard_ExtString_HeaderFile
#include <Standard_TypeDef.hxx>
//! 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

@@ -387,30 +387,3 @@ void Standard_GUID::ShallowDump(Standard_OStream& aStream) const
ToCString(sguid);
aStream << sguid;
}
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer Standard_GUID::HashCode (const Standard_GUID& theGuid, const Standard_Integer theUpperBound)
{
return theGuid.Hash (theUpperBound);
}
Standard_Integer Standard_GUID::Hash(const Standard_Integer Upper) const
{
if (Upper < 1){
throw Standard_RangeError("Standard_GUID::Hash: Try to apply HashCode method with negative or null argument.");
}
char sguid[Standard_GUID_SIZE_ALLOC];
ToCString(sguid);
return ::HashCode(sguid,Upper);
}
Standard_Boolean Standard_GUID::IsEqual(const Standard_GUID& aGuid1,const Standard_GUID& aGuid2)
{
return (aGuid1 == aGuid2);
}

View File

@@ -104,32 +104,12 @@ void operator = (const Standard_UUID& uid)
//! Check the format of a GUID string.
//! It checks the size, the position of the '-' and the correct size of fields.
Standard_EXPORT static Standard_Boolean CheckGUIDFormat (const Standard_CString aGuid);
//! Hash function for GUID.
Standard_EXPORT Standard_Integer Hash (const Standard_Integer Upper) const;
//! 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);
protected:
template<class T>
friend struct std::hash;
private:
Standard_Integer my32b;
Standard_ExtCharacter my16b1;
Standard_ExtCharacter my16b2;
@@ -140,12 +120,38 @@ private:
Standard_Byte my8b4;
Standard_Byte my8b5;
Standard_Byte my8b6;
};
namespace std
{
template <>
struct hash<Standard_GUID>
{
size_t operator()(const Standard_GUID& theGUID) const noexcept
{
struct GUID
{
Standard_Integer my32b;
Standard_ExtCharacter my16b1;
Standard_ExtCharacter my16b2;
Standard_ExtCharacter my16b3;
Standard_Byte my8b1;
Standard_Byte my8b2;
Standard_Byte my8b3;
Standard_Byte my8b4;
Standard_Byte my8b5;
Standard_Byte my8b6;
};
GUID aGUID{ theGUID.my32b, theGUID.my16b1,
theGUID.my16b2, theGUID.my16b3,
theGUID.my8b1, theGUID.my8b2,
theGUID.my8b3, theGUID.my8b4,
theGUID.my8b5, theGUID.my8b6 };
return opencascade::hashBytes(&aGUID, sizeof(GUID));
}
};
}

View File

@@ -14,7 +14,6 @@
#ifndef _Standard_Handle_HeaderFile
#define _Standard_Handle_HeaderFile
#include <Standard_Address.hxx>
#include <Standard_Std.hxx>
#include <Standard_Stream.hxx>
#include <Standard_Transient.hxx>
@@ -399,14 +398,18 @@ namespace opencascade {
//! Define Handle() macro
#define Handle(Class) opencascade::handle<Class>
//! Computes a hash code for the standard handle, in the range [1, theUpperBound]
//! @param theHandle the 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)
#include <Standard_HashUtils.hxx>
namespace std
{
return ::HashCode (theHandle.get(), theUpperBound);
template <class TheTransientType>
struct hash<Handle(TheTransientType)>
{
size_t operator()(const Handle(TheTransientType)& theHandle) const noexcept
{
return static_cast<size_t>(reinterpret_cast<std::uintptr_t>(theHandle.get()));
}
};
}
//! For compatibility with previous versions of OCCT, define Handle_Class alias for opencascade::handle<Class>.

View File

@@ -0,0 +1,120 @@
// Copyright (c) 2023 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_HashUtils_HeaderFile
#define _Standard_HashUtils_HeaderFile
#include <Standard_Macro.hxx>
#include <cstdint>
#include <cstddef>
#include <functional>
#include <type_traits>
namespace opencascade
{
//! Implementation of Murmur hash with autodetect of sizeof(size_t).
//!
//! The default value for the seed is optimal for general cases at a certain hash size.
namespace MurmurHash
{
uint32_t MurmurHash2A(const void* theKey, int theLen, uint32_t theSeed);
uint64_t MurmurHash64A(const void* theKey, int theLen, uint64_t theSeed);
template <typename T1, typename T = size_t>
typename std::enable_if<sizeof(T) == 8, uint64_t>::type
hash_combine(const T1& theValue, const int theLen = sizeof(T1), const T theSeed = 0xA329F1D3A586ULL)
{
return MurmurHash::MurmurHash64A(&theValue, theLen, theSeed);
}
template <typename T1, typename T = size_t>
typename std::enable_if<sizeof(T) != 8, T>::type
hash_combine(const T1& theValue, const int theLen = sizeof(T1), const T theSeed = 0xc70f6907U)
{
return static_cast<T>(MurmurHash::MurmurHash2A(&theValue, theLen, theSeed));
}
template <typename T = size_t>
constexpr typename std::enable_if<sizeof(T) == 8, uint64_t>::type optimalSeed()
{
return 0xA329F1D3A586ULL;
}
template <typename T = size_t>
constexpr typename std::enable_if<sizeof(T) != 8, T >::type optimalSeed()
{
return static_cast<T>(0xc70f6907U);
}
};
//! Implementation of FNV-1a with autodetect of sizeof(size_t).
//! This function should work on unsigned char, otherwise it does not
//! correctly implement the FNV-1a algorithm.
//! The existing behaviour is retained for backwards compatibility.
//!
//! The default value for the seed is optimal for general cases at a certain hash size.
namespace FNVHash
{
uint32_t FNVHash1A(const void* theKey, int theLen, uint32_t theSeed);
uint64_t FNVHash64A(const void* theKey, int theLen, uint64_t theSeed);
template <typename T1, typename T = size_t>
static typename std::enable_if<sizeof(T) == 8, uint64_t>::type
hash_combine(const T1& theValue, const int theLen = sizeof(T1), const T theSeed = 14695981039346656037ULL)
{
return FNVHash::FNVHash64A(&theValue, theLen, theSeed);
}
template <typename T1, typename T = size_t>
static typename std::enable_if<sizeof(T) != 8, T>::type
hash_combine(const T1& theValue, const int theLen = sizeof(T1), const T theSeed = 2166136261U)
{
return static_cast<T>(FNVHash::FNVHash1A(&theValue, theLen, theSeed));
}
template <typename T = size_t>
constexpr typename std::enable_if<sizeof(T) == 8, uint64_t>::type optimalSeed()
{
return 14695981039346656037ULL;
}
template <typename T = size_t>
constexpr typename std::enable_if<sizeof(T) != 8, T>::type optimalSeed()
{
return static_cast<T>(2166136261U);
}
};
template <typename T1, typename T = size_t>
T hash(const T1 theValue) noexcept
{
return opencascade::MurmurHash::hash_combine<T1, T>(theValue);
}
template <typename T1, typename T = size_t>
T hashBytes(const T1* theKey, int theLen)
{
return opencascade::MurmurHash::hash_combine<T1, T>(*theKey, theLen);
}
template <typename T1, typename T = size_t>
T hash_combine(const T1 theValue, const int theLen, const T theSeed)
{
return opencascade::MurmurHash::hash_combine<T1, T>(theValue, theLen, theSeed);
}
}
#include <Standard_HashUtils.lxx>
#endif

View File

@@ -0,0 +1,159 @@
// Copyright (c) 2023 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.
#include <cstring>
namespace opencascade
{
namespace MurmurHash
{
namespace MurmurHashUtils
{
inline uint64_t shift_mix(uint64_t theV)
{
return theV ^ (theV >> 47);
}
// Loads n bytes, where 1 <= n < 8.
inline uint64_t load_bytes(const char* thePnt, int theNb)
{
uint64_t aRes = 0;
--theNb;
do
aRes = (aRes << 8) + static_cast<unsigned char>(thePnt[theNb]);
while (--theNb >= 0);
return aRes;
}
template <typename T>
inline T unaligned_load(const char* thePnt)
{
T aRes;
memcpy(&aRes, thePnt, sizeof(aRes));
return aRes;
}
}
//=======================================================================
//function : MurmurHash64A
//purpose :
//=======================================================================
inline uint64_t MurmurHash64A(const void* theKey, int theLen, uint64_t theSeed)
{
static constexpr uint64_t aMul = (((uint64_t)0xc6a4a793UL) << 32UL)
+ (uint64_t)0x5bd1e995UL;
const char* const aBuf = static_cast<const char*>(theKey);
// Remove the bytes not divisible by the sizeof(uint64_t). This
// allows the main loop to process the data as 64-bit integers.
const uint64_t aLenAligned = theLen & ~(uint64_t)0x7;
const char* const anEnd = aBuf + aLenAligned;
uint64_t aHash = theSeed ^ (theLen * aMul);
for (const char* aPnt = aBuf; aPnt != anEnd; aPnt += 8)
{
const uint64_t aData = MurmurHashUtils::shift_mix(MurmurHashUtils::unaligned_load<uint64_t>(aPnt) * aMul) * aMul;
aHash ^= aData;
aHash *= aMul;
}
if ((theLen & 0x7) != 0)
{
const uint64_t data = MurmurHashUtils::load_bytes(anEnd, theLen & 0x7);
aHash ^= data;
aHash *= aMul;
}
aHash = MurmurHashUtils::shift_mix(aHash) * aMul;
aHash = MurmurHashUtils::shift_mix(aHash);
return aHash;
}
//=======================================================================
//function : MurmurHash2A
//purpose :
//=======================================================================
inline uint32_t MurmurHash2A(const void* theKey, int theLen, uint32_t theSeed)
{
const uint32_t aMul = 0x5bd1e995;
uint32_t aHash = theSeed ^ theLen;
const char* aBuf = static_cast<const char*>(theKey);
// Mix 4 bytes at a time into the hash.
while (theLen >= 4)
{
uint32_t aKey = MurmurHashUtils::unaligned_load<uint32_t>(aBuf);
aKey *= aMul;
aKey ^= aKey >> 24;
aKey *= aMul;
aHash *= aMul;
aHash ^= aKey;
aBuf += 4;
theLen -= 4;
}
uint32_t aKey;
// Handle the last few bytes of the input array.
switch (theLen)
{
case 3:
aKey = static_cast<unsigned char>(aBuf[2]);
aHash ^= aKey << 16;
Standard_FALLTHROUGH
case 2:
aKey = static_cast<unsigned char>(aBuf[1]);
aHash ^= aKey << 8;
Standard_FALLTHROUGH
case 1:
aKey = static_cast<unsigned char>(aBuf[0]);
aHash ^= aKey;
aHash *= aMul;
};
// Do a few final mixes of the hash.
aHash ^= aHash >> 13;
aHash *= aMul;
aHash ^= aHash >> 15;
return aHash;
}
} // MurmurHash
namespace FNVHash
{
//=======================================================================
//function : FNVHash1A
//purpose :
//=======================================================================
inline uint32_t FNVHash1A(const void* theKey, int theLen, uint32_t theSeed)
{
const char* cptr = static_cast<const char*>(theKey);
for (; theLen; --theLen)
{
theSeed ^= static_cast<uint32_t>(*cptr++);
theSeed *= static_cast<uint32_t>(16777619UL);
}
return theSeed;
}
//=======================================================================
//function : FNVHash64A
//purpose :
//=======================================================================
inline uint64_t FNVHash64A(const void* theKey, int theLen, uint64_t theSeed)
{
const char* cptr = static_cast<const char*>(theKey);
for (; theLen; --theLen)
{
theSeed ^= static_cast<uint64_t>(*cptr++);
theSeed *= static_cast<uint64_t>(1099511628211ULL);
}
return theSeed;
}
} // FNVHash
} // opencascade

View File

@@ -17,7 +17,8 @@
#include <Standard_Std.hxx>
#include <Standard_TypeDef.hxx>
#include <Standard_values.h>
#include <climits>
// ===============
// Inline methods
@@ -78,102 +79,19 @@ inline Standard_Integer Square(const Standard_Integer Value)
// ------------------------------------------------------------------
// IntegerFirst : Returns the minimum value of an integer
// ------------------------------------------------------------------
inline Standard_Integer IntegerFirst()
constexpr Standard_Integer IntegerFirst()
{ return INT_MIN; }
// ------------------------------------------------------------------
// IntegerLast : Returns the maximum value of an integer
// ------------------------------------------------------------------
inline Standard_Integer IntegerLast()
constexpr Standard_Integer IntegerLast()
{ return INT_MAX; }
// ------------------------------------------------------------------
// IntegerSize : Returns the size in digits of an integer
// ------------------------------------------------------------------
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]
//! @param theValue the unsigned integer which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a hash value computed for the given unsigned integer, in range [1, theUpperBound]
inline Standard_Integer HashCode (const unsigned int 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 the range [1, theUpperBound]
//! @tparam TheUtf32Char the type of the given value (it is Standard_Utf32Char,
//! and must not be the same as "unsigned int", because the overload of the HashCode function
//! for "unsigned int" type is already presented in Standard_Integer.hxx)
//! @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 the range [1, theUpperBound]
template <typename TheUtf32Char>
typename opencascade::std::enable_if<!opencascade::std::is_same<Standard_Utf32Char, unsigned int>::value
&& opencascade::std::is_same<TheUtf32Char, Standard_Utf32Char>::value,
Standard_Integer>::type
HashCode (const TheUtf32Char 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
constexpr Standard_Integer IntegerSize()
{ return CHAR_BIT * sizeof(Standard_Integer); }
#endif

View File

@@ -1,75 +0,0 @@
// Created on: 2005-03-15
// Created by: Peter KURNEV
// Copyright (c) 2005-2014 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.
#include <Standard_MMgrRaw.hxx>
#include <Standard_OutOfMemory.hxx>
//=======================================================================
//function : Standard_MMgrRaw
//purpose :
//=======================================================================
Standard_MMgrRaw::Standard_MMgrRaw(const Standard_Boolean aClear)
{
myClear = aClear;
}
//=======================================================================
//function : Allocate
//purpose :
//=======================================================================
Standard_Address Standard_MMgrRaw::Allocate(const Standard_Size aSize)
{
// the size is rounded up to 4 since some OCC classes
// (e.g. TCollection_AsciiString) assume memory to be double word-aligned
const Standard_Size aRoundSize = (aSize + 3) & ~0x3;
// we use ?: operator instead of if() since it is faster :-)
Standard_Address aPtr = ( myClear ? calloc(aRoundSize, sizeof(char)) :
malloc(aRoundSize) );
if ( ! aPtr )
throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
return aPtr;
}
//=======================================================================
//function : Free
//purpose :
//=======================================================================
void Standard_MMgrRaw::Free(Standard_Address theStorage)
{
free(theStorage);
}
//=======================================================================
//function : Reallocate
//purpose :
//=======================================================================
Standard_Address Standard_MMgrRaw::Reallocate(Standard_Address theStorage,
const Standard_Size theSize)
{
// the size is rounded up to 4 since some OCC classes
// (e.g. TCollection_AsciiString) assume memory to be double word-aligned
const Standard_Size aRoundSize = (theSize + 3) & ~0x3;
Standard_Address newStorage = (Standard_Address)realloc(theStorage, aRoundSize);
if ( ! newStorage )
throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
// Note that it is not possible to ensure that additional memory
// allocated by realloc will be cleared (so as to satisfy myClear mode);
// in order to do that we would need using memset...
return newStorage;
}

View File

@@ -1,49 +0,0 @@
// Created on: 2005-03-15
// Created by: Peter KURNEV
// Copyright (c) 2005-2014 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_MMgrRaw_HeaderFile
#define _Standard_MMgrRaw_HeaderFile
#include <Standard_MMgrRoot.hxx>
/**
* Implementation of raw OCC memory manager which uses standard C
* functions: malloc (or calloc), free and realloc
* without any optimization
*/
class Standard_MMgrRaw : public Standard_MMgrRoot
{
public:
//! Constructor; if aClear is True, the memory will be nullified
//! upon allocation.
Standard_EXPORT Standard_MMgrRaw(const Standard_Boolean aClear=Standard_False);
//! Allocate aSize bytes
Standard_EXPORT virtual Standard_Address Allocate(const Standard_Size aSize);
//! Reallocate aPtr to the size aSize.
//! The new pointer is returned.
Standard_EXPORT virtual Standard_Address Reallocate(Standard_Address thePtr,
const Standard_Size theSize);
//! Free allocated memory. The pointer is nullified.
Standard_EXPORT virtual void Free (Standard_Address thePtr);
protected:
Standard_Boolean myClear; //! Option to nullify allocated memory
};
#endif

View File

@@ -1,87 +0,0 @@
// Created on: 2010-03-15
// Created by: Sergey KUUL
// Copyright (c) 2010-2014 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.
#include <Standard_MMgrTBBalloc.hxx>
#include <Standard_OutOfMemory.hxx>
// paralleling with Intel TBB
#ifdef HAVE_TBB
#pragma comment (lib, "tbbmalloc.lib")
#include <tbb/scalable_allocator.h>
using namespace tbb;
#else
#define scalable_malloc malloc
#define scalable_calloc calloc
#define scalable_realloc realloc
#define scalable_free free
#endif
//=======================================================================
//function : Standard_MMgrTBBalloc
//purpose :
//=======================================================================
Standard_MMgrTBBalloc::Standard_MMgrTBBalloc(const Standard_Boolean aClear)
{
myClear = aClear;
}
//=======================================================================
//function : Allocate
//purpose :
//=======================================================================
Standard_Address Standard_MMgrTBBalloc::Allocate(const Standard_Size aSize)
{
// the size is rounded up to 4 since some OCC classes
// (e.g. TCollection_AsciiString) assume memory to be double word-aligned
const Standard_Size aRoundSize = (aSize + 3) & ~0x3;
// we use ?: operator instead of if() since it is faster :-)
Standard_Address aPtr = ( myClear ? scalable_calloc(aRoundSize, sizeof(char)) :
scalable_malloc(aRoundSize) );
if ( ! aPtr )
throw Standard_OutOfMemory("Standard_MMgrTBBalloc::Allocate(): malloc failed");
return aPtr;
}
//=======================================================================
//function : Free
//purpose :
//=======================================================================
void Standard_MMgrTBBalloc::Free (Standard_Address theStorage)
{
scalable_free (theStorage);
}
//=======================================================================
//function : Reallocate
//purpose :
//=======================================================================
Standard_Address Standard_MMgrTBBalloc::Reallocate (Standard_Address theStorage,
const Standard_Size theSize)
{
// the size is rounded up to 4 since some OCC classes
// (e.g. TCollection_AsciiString) assume memory to be double word-aligned
const Standard_Size aRoundSize = (theSize + 3) & ~0x3;
Standard_Address newStorage = (Standard_Address)scalable_realloc(theStorage, aRoundSize);
if ( ! newStorage )
throw Standard_OutOfMemory("Standard_MMgrTBBalloc::Reallocate(): realloc failed");
// Note that it is not possible to ensure that additional memory
// allocated by realloc will be cleared (so as to satisfy myClear mode);
// in order to do that we would need using memset...
return newStorage;
}

View File

@@ -1,50 +0,0 @@
// Created on: 2010-03-15
// Created by: Sergey KUUL
// Copyright (c) 2010-2014 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_MMgrTBBalloc_HeaderFile
#define _Standard_MMgrTBBalloc_HeaderFile
#include <Standard_MMgrRoot.hxx>
//!
//! Implementation of OCC memory manager which uses Intel TBB
//! scalable allocator.
//!
//! On configurations where TBB is not available standard RTL functions
//! malloc() / free() are used.
class Standard_MMgrTBBalloc : public Standard_MMgrRoot
{
public:
//! Constructor; if aClear is True, the memory will be nullified
//! upon allocation.
Standard_EXPORT Standard_MMgrTBBalloc(const Standard_Boolean aClear=Standard_False);
//! Allocate aSize bytes
Standard_EXPORT virtual Standard_Address Allocate(const Standard_Size aSize);
//! Reallocate aPtr to the size aSize.
//! The new pointer is returned.
Standard_EXPORT virtual Standard_Address Reallocate (Standard_Address thePtr,
const Standard_Size theSize);
//! Free allocated memory
Standard_EXPORT virtual void Free (Standard_Address thePtr);
protected:
Standard_Boolean myClear; //! Option to nullify allocated memory
};
#endif

View File

@@ -0,0 +1,62 @@
// Copyright (c) 2023 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_MemoryUtils_HeaderFile
#define _Standard_MemoryUtils_HeaderFile
#include <NCollection_Allocator.hxx>
#include <NCollection_OccAllocator.hxx>
#include <memory>
namespace opencascade
{
template< class T, class... Args >
std::shared_ptr<T> make_shared(Args&&... theArgs)
{
return std::allocate_shared<T, NCollection_Allocator<T>, Args...>(NCollection_Allocator<T>(),
std::forward<Args>(theArgs)...);
}
template< class T, class... Args >
std::shared_ptr<T> make_oshared(const Handle(NCollection_BaseAllocator)& theAlloc,
Args&&... theArgs)
{
return std::allocate_shared<T, NCollection_OccAllocator<T>, Args...>(NCollection_OccAllocator<T>(theAlloc),
std::forward<Args>(theArgs)...);
}
template< class T, class... Args >
std::shared_ptr<T> make_oshared(const NCollection_OccAllocator<T>& theAlloc,
Args&&... theArgs)
{
return std::allocate_shared<T, NCollection_OccAllocator<T>, Args...>(theAlloc,
std::forward<Args>(theArgs)...);
}
template< class T, class... Args >
std::shared_ptr<T> make_oshared(NCollection_OccAllocator<T>&& theAlloc,
Args&&... theArgs)
{
return std::allocate_shared<T, NCollection_OccAllocator<T>, Args...>(std::forward<NCollection_OccAllocator<T>(>theAlloc),
std::forward<Args>(theArgs)...);
}
template <typename T, class... Args>
std::unique_ptr<T> make_unique(Args&&... theArgs)
{
return std::unique_ptr<T>(new T(std::forward<Args>(theArgs)...));
}
}
#endif

View File

@@ -26,7 +26,5 @@
#include <Standard_Character.hxx>
#include <Standard_ExtCharacter.hxx>
#include <Standard_CString.hxx>
#include <Standard_ExtString.hxx>
#include <Standard_Address.hxx>
#endif

View File

@@ -20,28 +20,6 @@
static const Standard_Real ACosLimit = 1. + Epsilon(1.);
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer HashCode (const Standard_Real theReal, const Standard_Integer theUpperBound)
{
if (theUpperBound < 1)
{
throw Standard_RangeError ("Try to apply HashCode method with negative or null argument.");
}
union
{
Standard_Real R;
Standard_Integer I[2];
} 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

@@ -16,9 +16,16 @@
#define _Standard_Real_HeaderFile
#include <cmath>
#include <climits>
#include <float.h>
#include <Standard_values.h>
#include <Standard_math.hxx>
#ifdef _MSC_VER
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#endif
#include <Standard_TypeDef.hxx>
// ===============================================
@@ -31,12 +38,6 @@
// Methods implemented in Standard_Real.cxx
// ==================================
//! 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 );
Standard_EXPORT Standard_Real ASin (const Standard_Real );
@@ -56,7 +57,7 @@ Standard_EXPORT Standard_Real Sqrt (const Standard_Real );
//-------------------------------------------------------------------
// RealSmall : Returns the smallest positive real
//-------------------------------------------------------------------
inline Standard_Real RealSmall()
constexpr Standard_Real RealSmall()
{ return DBL_MIN; }
//-------------------------------------------------------------------
@@ -84,60 +85,60 @@ inline Standard_Boolean IsEqual (const Standard_Real Value1,
//-------------------------------------------------------------------
// RealDigit : Returns the number of digits of precision in a real
//-------------------------------------------------------------------
inline Standard_Integer RealDigits()
constexpr Standard_Integer RealDigits()
{ return DBL_DIG; }
//-------------------------------------------------------------------
// RealEpsilon : Returns the minimum positive real such that
// 1.0 + x is not equal to 1.0
//-------------------------------------------------------------------
inline Standard_Real RealEpsilon()
constexpr Standard_Real RealEpsilon()
{ return DBL_EPSILON; }
//-------------------------------------------------------------------
// RealFirst : Returns the minimum negative value of a real
//-------------------------------------------------------------------
inline Standard_Real RealFirst()
constexpr Standard_Real RealFirst()
{ return -DBL_MAX; }
//-------------------------------------------------------------------
// RealFirst10Exp : Returns the minimum value of exponent(base 10) of
// a real.
//-------------------------------------------------------------------
inline Standard_Integer RealFirst10Exp()
constexpr Standard_Integer RealFirst10Exp()
{ return DBL_MIN_10_EXP; }
//-------------------------------------------------------------------
// RealLast : Returns the maximum value of a real
//-------------------------------------------------------------------
inline Standard_Real RealLast()
constexpr Standard_Real RealLast()
{ return DBL_MAX; }
//-------------------------------------------------------------------
// RealLast10Exp : Returns the maximum value of exponent(base 10) of
// a real.
//-------------------------------------------------------------------
inline Standard_Integer RealLast10Exp()
constexpr Standard_Integer RealLast10Exp()
{ return DBL_MAX_10_EXP; }
//-------------------------------------------------------------------
// RealMantissa : Returns the size in bits of the matissa part of a
// real.
//-------------------------------------------------------------------
inline Standard_Integer RealMantissa()
constexpr Standard_Integer RealMantissa()
{ return DBL_MANT_DIG; }
//-------------------------------------------------------------------
// RealRadix : Returns the radix of exponent representation
//-------------------------------------------------------------------
inline Standard_Integer RealRadix()
constexpr Standard_Integer RealRadix()
{ return FLT_RADIX; }
//-------------------------------------------------------------------
// RealSize : Returns the size in bits of an integer
//-------------------------------------------------------------------
inline Standard_Integer RealSize()
{ return BITS(Standard_Real); }
constexpr Standard_Integer RealSize()
{ return CHAR_BIT * sizeof(Standard_Real); }

View File

@@ -1,36 +0,0 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 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.
#include <Standard_ShortReal.hxx>
#include <Standard_NullValue.hxx>
//============================================================================
// function : HashCode
// purpose :
//============================================================================
Standard_Integer HashCode (const Standard_ShortReal theShortReal, const Standard_Integer theUpperBound)
{
if (theUpperBound < 1)
{
throw Standard_RangeError ("Try to apply HashCode method with negative or null argument.");
}
union
{
Standard_ShortReal R;
Standard_Integer I;
} U;
U.R = theShortReal;
return HashCode (U.I, theUpperBound);
}

View File

@@ -16,9 +16,9 @@
#define _Standard_ShortReal_HeaderFile
#include <cmath>
#include <climits>
#include <float.h>
#include <Standard_values.h>
#include <Standard_TypeDef.hxx>
// *********************************** //
@@ -31,7 +31,7 @@
//-------------------------------------------------------------------
// ShortRealSmall : Returns the smallest positive ShortReal
//-------------------------------------------------------------------
inline Standard_ShortReal ShortRealSmall()
constexpr Standard_ShortReal ShortRealSmall()
{ return FLT_MIN; }
//-------------------------------------------------------------------
@@ -47,14 +47,14 @@ inline Standard_ShortReal Abs(const Standard_ShortReal Value)
//-------------------------------------------------------------------
// ShortRealDigit : Returns the number of digits of precision in a ShortReal
//-------------------------------------------------------------------
inline Standard_Integer ShortRealDigits()
constexpr Standard_Integer ShortRealDigits()
{ return FLT_DIG; }
//-------------------------------------------------------------------
// ShortRealEpsilon : Returns the minimum positive ShortReal such that
// 1.0 + x is not equal to 1.0
//-------------------------------------------------------------------
inline Standard_ShortReal ShortRealEpsilon()
constexpr Standard_ShortReal ShortRealEpsilon()
{ return FLT_EPSILON; }
//-------------------------------------------------------------------
@@ -68,40 +68,40 @@ inline Standard_ShortReal ShortRealFirst()
// ShortRealFirst10Exp : Returns the minimum value of exponent(base 10) of
// a ShortReal.
//-------------------------------------------------------------------
inline Standard_Integer ShortRealFirst10Exp()
constexpr Standard_Integer ShortRealFirst10Exp()
{ return FLT_MIN_10_EXP; }
//-------------------------------------------------------------------
// ShortRealLast : Returns the maximum value of a ShortReal
//-------------------------------------------------------------------
inline Standard_ShortReal ShortRealLast()
constexpr Standard_ShortReal ShortRealLast()
{ return FLT_MAX; }
//-------------------------------------------------------------------
// ShortRealLast10Exp : Returns the maximum value of exponent(base 10) of
// a ShortReal.
//-------------------------------------------------------------------
inline Standard_Integer ShortRealLast10Exp()
constexpr Standard_Integer ShortRealLast10Exp()
{ return FLT_MAX_10_EXP; }
//-------------------------------------------------------------------
// ShortRealMantissa : Returns the size in bits of the matissa part of a
// ShortReal.
//-------------------------------------------------------------------
inline Standard_Integer ShortRealMantissa()
constexpr Standard_Integer ShortRealMantissa()
{ return FLT_MANT_DIG; }
//-------------------------------------------------------------------
// ShortRealRadix : Returns the radix of exponent representation
//-------------------------------------------------------------------
inline Standard_Integer ShortRealRadix()
constexpr Standard_Integer ShortRealRadix()
{ return FLT_RADIX; }
//-------------------------------------------------------------------
// ShortRealSize : Returns the size in bits of an integer
//-------------------------------------------------------------------
inline Standard_Integer ShortRealSize()
{ return BITS(Standard_ShortReal); }
constexpr Standard_Integer ShortRealSize()
{ return CHAR_BIT * sizeof(Standard_ShortReal); }
//-------------------------------------------------------------------
// Max : Returns the maximum value of two ShortReals
@@ -129,29 +129,6 @@ inline Standard_ShortReal Min (const Standard_ShortReal Val1,
}
}
// ===============================================
// Methods from Standard_Entity class which are redefined:
// - Hascode
// - IsEqual
// ===============================================
// ==================================
// Methods implemented in Standard_ShortReal.cxx
// ==================================
//! 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
//-------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_ShortReal Value1,
const Standard_ShortReal Value2)
{ return Abs((Value1 - Value2)) < ShortRealSmall(); }
#endif

View File

@@ -1,54 +0,0 @@
// Created on: 2006-08-22
// Created by: Alexander GRIGORIEV
// Copyright (c) 2006-2014 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_Size_HeaderFile
#define _Standard_Size_HeaderFile
#include <Standard_Integer.hxx>
// msv 26.05.2009: add HashCode and IsEqual functions
//! Computes a hash code for the given value of the Standard_Size type, in the range [1, theUpperBound]
//! @tparam TheSize the type of the given value (it is Standard_Size,
//! and must not be the same as "unsigned int", because the overload of the HashCode function
//! for "unsigned int" type is already presented in Standard_Integer.hxx)
//! @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]
template <typename TheSize>
typename opencascade::std::enable_if<!opencascade::std::is_same<Standard_Size, unsigned int>::value
&& opencascade::std::is_same<TheSize, Standard_Size>::value,
Standard_Integer>::type
HashCode (const TheSize theValue, const Standard_Integer theUpperBound)
{
Standard_Size aKey = ~theValue + (theValue << 18);
aKey ^= (aKey >> 31);
aKey *= 21;
aKey ^= (aKey >> 11);
aKey += (aKey << 6);
aKey ^= (aKey >> 22);
return IntegerHashCode(aKey, IntegerLast(), theUpperBound);
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two values are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual(const Standard_Size One,
const Standard_Size Two)
{
return One == Two;
}
#endif

View File

@@ -16,7 +16,6 @@
#ifndef Standard_ThreadId_HeaderFile
#define Standard_ThreadId_HeaderFile
#include <Standard_Size.hxx>
// Platform-independent definition of the thread identifier type
typedef Standard_Size Standard_ThreadId;

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
// Copyright (c) 1999-2023 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
@@ -12,17 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Standard_Type.hxx>
#include <Standard_Transient.hxx>
#include <Standard_Atomic.hxx>
#include <Standard_Type.hxx>
#include <Standard_CString.hxx>
#include <Standard_ProgramError.hxx>
void Standard_Transient::Delete() const
{
delete this;
}
const Handle(Standard_Type)& Standard_Transient::get_type_descriptor ()
{
return opencascade::type_instance<Standard_Transient>::get();
@@ -71,15 +66,3 @@ Standard_Transient* Standard_Transient::This() const
throw Standard_ProgramError("Attempt to create handle to object created in stack, not yet constructed, or destroyed");
return const_cast<Standard_Transient*> (this);
}
// Increment reference counter
void Standard_Transient::IncrementRefCounter() const
{
Standard_Atomic_Increment (&myRefCount_);
}
// Decrement reference counter
Standard_Integer Standard_Transient::DecrementRefCounter() const
{
return Standard_Atomic_Decrement(&myRefCount_);
}

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
// Copyright (c) 1999-2023 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
@@ -19,9 +19,12 @@
#include <Standard_DefineAlloc.hxx>
#include <Standard_PrimitiveTypes.hxx>
#include <atomic>
class Standard_Type;
namespace opencascade {
namespace opencascade
{
template <class T> class handle;
}
@@ -48,15 +51,12 @@ public:
//! Destructor must be virtual
virtual ~Standard_Transient() {}
//! Memory deallocator for transient classes
Standard_EXPORT virtual void Delete() const;
public:
//!@name Support of run-time type information (RTTI)
typedef void base_type;
static const char* get_type_name () { return "Standard_Transient"; }
static constexpr const char* get_type_name () { return "Standard_Transient"; }
//! Returns type descriptor of Standard_Transient class
Standard_EXPORT static const opencascade::handle<Standard_Type>& get_type_descriptor ();
@@ -90,34 +90,35 @@ public:
//!@name Reference counting, for use by handle<>
//! Get the reference counter of this object
Standard_Integer GetRefCount() const { return myRefCount_; }
inline Standard_Integer GetRefCount() const noexcept { return myRefCount_; }
//! Increments the reference counter of this object
Standard_EXPORT void IncrementRefCounter() const;
inline void IncrementRefCounter() noexcept
{
myRefCount_.operator++();
}
//! Decrements the reference counter of this object;
//! returns the decremented value
Standard_EXPORT Standard_Integer DecrementRefCounter() const;
inline Standard_Integer DecrementRefCounter() noexcept
{
return myRefCount_.operator--();
}
//! Memory deallocator for transient classes
virtual void Delete() const
{
delete this;
}
private:
//! Reference counter.
//! Note use of underscore, aimed to reduce probability
//! of conflict with names of members of derived classes.
mutable volatile Standard_Integer myRefCount_;
std::atomic_int myRefCount_;
};
//! 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 (static_cast<const void*> (theTransientObject), theUpperBound);
}
//! Definition of Handle_Standard_Transient as typedef for compatibility
typedef opencascade::handle<Standard_Transient> Handle_Standard_Transient;

View File

@@ -15,29 +15,20 @@
#include <Standard_Type.hxx>
#include <Standard_Mutex.hxx>
#include <Standard_Assert.hxx>
#include <NCollection_DataMap.hxx>
#include <unordered_map>
IMPLEMENT_STANDARD_RTTIEXT(Standard_Type,Standard_Transient)
//============================================================================
namespace {
static Standard_CString copy_string (const char* theString)
{
size_t aLength = strlen (theString);
char* aResult = static_cast<char*> (Standard::Allocate (aLength + 1));
strncpy (aResult, theString, aLength + 1); //including null-character
return aResult;
}
}
Standard_Type::Standard_Type (const char* theSystemName,
Standard_Type::Standard_Type (const std::type_info& theInfo,
const char* theName,
Standard_Size theSize,
const Handle(Standard_Type)& theParent) :
mySystemName(copy_string (theSystemName)),
myName(copy_string (theName)),
myInfo(theInfo),
myName(theName),
mySize(theSize),
myParent(theParent)
{
@@ -70,25 +61,8 @@ void Standard_Type::Print (Standard_OStream& AStream) const
//============================================================================
namespace {
// Value-based hasher for plain C string (char*)
struct CStringHasher
{
//! 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, theUpperBound);
}
static bool IsEqual (const Standard_CString& theKey1, const Standard_CString& theKey2)
{
return ! strcmp (theKey1, theKey2);
}
};
// Map of string to type
typedef NCollection_DataMap<Standard_CString, Standard_Type*, CStringHasher> registry_type;
typedef std::unordered_map<std::type_index, Standard_Type*> registry_type;
// Registry is made static in the function to ensure that it gets
// initialized by the time of first access
@@ -102,7 +76,7 @@ namespace {
Handle(Standard_Type) theType = STANDARD_TYPE(Standard_Transient);
}
Standard_Type* Standard_Type::Register (const char* theSystemName, const char* theName,
Standard_Type* Standard_Type::Register (const std::type_info& theInfo, const char* theName,
Standard_Size theSize, const Handle(Standard_Type)& theParent)
{
// Access to registry is protected by mutex; it should not happen often because
@@ -113,17 +87,15 @@ Standard_Type* Standard_Type::Register (const char* theSystemName, const char* t
// return existing descriptor if already in the registry
registry_type& aRegistry = GetRegistry();
Standard_Type* aType = 0;
if (aRegistry.Find (theSystemName, aType))
return aType;
auto anIter = aRegistry.find(theInfo);
if (anIter != aRegistry.end())
return anIter->second;
// else create a new descriptor
aType = new Standard_Type (theSystemName, theName, theSize, theParent);
aType = new Standard_Type (theInfo, theName, theSize, theParent);
// then add it to registry and return (the reference to the handle stored in the registry)
aRegistry.Bind (aType->mySystemName, aType);
// std::cout << "Registering " << theSystemName << ": " << aRegistry.Extent() << std::endl;
aRegistry.emplace(theInfo, aType);
return aType;
}
@@ -131,9 +103,5 @@ Standard_Type::~Standard_Type ()
{
// remove descriptor from the registry
registry_type& aRegistry = GetRegistry();
Standard_ASSERT(aRegistry.UnBind (mySystemName), "Standard_Type::~Standard_Type() cannot find itself in registry",);
// std::cout << "Unregistering " << mySystemName << ": " << aRegistry.Extent() << std::endl;
Standard::Free (mySystemName);
Standard::Free (myName);
Standard_ASSERT(aRegistry.erase(myInfo) > 0, "Standard_Type::~Standard_Type() cannot find itself in registry",);
}

View File

@@ -21,6 +21,7 @@
#include <Standard_OStream.hxx>
#include <typeinfo>
#include <typeindex>
// Auxiliary tools to check at compile time that class declared as base in
// DEFINE_STANDARD_RTTI* macro is actually a base class.
@@ -146,7 +147,7 @@ class Standard_Type : public Standard_Transient
public:
//! Returns the system type name of the class (typeinfo.name)
Standard_CString SystemName() const { return mySystemName; }
Standard_CString SystemName() const { return myInfo.name(); }
//! Returns the given name of the class type (get_type_name)
Standard_CString Name() const { return myName; }
@@ -181,14 +182,14 @@ public:
//! Register a type; returns either new or existing descriptor.
//!
//! @param theSystemName name of the class as returned by typeid(class).name()
//! @param theInfo object stores system name of the class
//! @param theName name of the class to be stored in Name field
//! @param theSize size of the class instance
//! @param theParent base class in the Transient hierarchy
//!
//! Note that this function is intended for use by opencascade::type_instance only.
Standard_EXPORT static
Standard_Type* Register (const char* theSystemName, const char* theName,
Standard_Type* Register (const std::type_info& theInfo, const char* theName,
Standard_Size theSize, const Handle(Standard_Type)& theParent);
//! Destructor removes the type from the registry
@@ -200,11 +201,11 @@ public:
private:
//! Constructor is private
Standard_Type (const char* theSystemName, const char* theName,
Standard_Type (const std::type_info& theInfo, const char* theName,
Standard_Size theSize, const Handle(Standard_Type)& theParent);
private:
Standard_CString mySystemName; //!< System name of the class (typeinfo.name)
std::type_index myInfo; //!< Object to store system name of the class
Standard_CString myName; //!< Given name of the class
Standard_Size mySize; //!< Size of the class instance, in bytes
Handle(Standard_Type) myParent; //!< Type descriptor of parent class
@@ -252,7 +253,7 @@ namespace opencascade {
// static variable inside function ensures that descriptors
// are initialized in correct sequence
static Handle(Standard_Type) anInstance =
Standard_Type::Register (typeid(T).name(), T::get_type_name(), sizeof(T),
Standard_Type::Register (typeid(T), T::get_type_name(), sizeof(T),
type_instance<typename T::base_type>::get());
return anInstance;
}

View File

@@ -1,46 +0,0 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 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.
#include <Standard_math.hxx>
// MSVC versions prior to 12 did not provided acosh, asinh, atanh functions in standard library
#if defined(_MSC_VER) && (_MSC_VER < 1800)
Standard_EXPORT double __cdecl acosh( double X)
{
double res;
res = log(X + sqrt(X * X - 1));
return res;
};
Standard_EXPORT double __cdecl asinh( double X)
{
double res;
// Modified by Sergey KHROMOV - Mon Nov 11 16:27:11 2002 Begin
// Correction of the formula to avoid numerical problems.
// res = log(X + sqrt(X * X + 1));
if (X > 0.)
res = log(X + sqrt(X * X + 1));
else
res = -log(sqrt(X * X + 1) - X);
// Modified by Sergey KHROMOV - Mon Nov 11 16:27:13 2002 End
return res;
};
Standard_EXPORT double __cdecl atanh( double X)
{
double res;
res = log((1 + X) / (1 - X)) / 2;
return res;
};
#endif

View File

@@ -1,40 +0,0 @@
// Copyright (c) 1991-1999 Matra Datavision
// Copyright (c) 1999-2014 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_math_HeaderFile
#define Standard_math_HeaderFile
#ifndef _Standard_Macro_HeaderFile
#include <Standard_Macro.hxx>
#endif
#ifdef _MSC_VER
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <math.h>
// MSVC versions prior to 12 did not provided acosh, asinh, atanh functions in standard library
#if _MSC_VER < 1800
Standard_EXPORT double __cdecl acosh ( double );
Standard_EXPORT double __cdecl asinh ( double );
Standard_EXPORT double __cdecl atanh ( double );
#endif
#endif /* _MSC_VER */
#endif

View File

@@ -1,40 +0,0 @@
/*
Copyright (c) 1991-1999 Matra Datavision
Copyright (c) 1999-2014 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_values_HeaderFile
# define _Standard_values_HeaderFile
#if defined(_MSC_VER)
# include <limits>
#else
# include <limits.h>
#endif
#if defined (__hpux) || defined (HPUX)
# ifdef MAXINT
# undef MAXINT
# endif
#endif
#ifndef BITSPERBYTE
# define BITSPERBYTE CHAR_BIT
#endif
#ifndef BITS
# define BITS(type) (BITSPERBYTE * sizeof(type))
#endif
#endif