#include <NCollection_SparseArrayBase.hxx>
#include <Standard_ProgramError.hxx>
+#include <Standard.hxx>
+
+#include <algorithm>
//=================================================================================================
while (iBlock >= newNbBlocks)
newNbBlocks *= 2;
- Standard_Address* newData = (Standard_Address*)malloc(newNbBlocks * sizeof(Standard_Address));
+ Standard_Address* newData =
+ (Standard_Address*)Standard::AllocateOptimal(newNbBlocks * sizeof(Standard_Address));
if (myNbBlocks > 0)
memcpy(newData, myData, myNbBlocks * sizeof(Standard_Address));
memset(newData + myNbBlocks, 0, (newNbBlocks - myNbBlocks) * sizeof(Standard_Address));
- free(myData);
+ Standard::Free(myData);
myData = newData;
myNbBlocks = newNbBlocks;
}
void NCollection_SparseArrayBase::freeBlock(const Standard_Size iBlock)
{
Standard_Address& anAddr = myData[iBlock];
- Block aBlock = getBlock(anAddr);
+ if (!anAddr)
+ return;
+
+ Block aBlock = getBlock(anAddr);
+ // Destroy all items in the block
for (Standard_Size anInd = 0; anInd < myBlockSize; anInd++)
+ {
if (aBlock.IsSet(anInd))
{
destroyItem(getItem(aBlock, anInd));
mySize--;
}
- free(anAddr);
- anAddr = 0;
+ }
+ Standard::Free(anAddr);
+ anAddr = nullptr;
}
//=================================================================================================
{
// free block data
for (Standard_Size iBlock = 0; iBlock < myNbBlocks; iBlock++)
+ {
if (myData[iBlock])
+ {
freeBlock(iBlock);
+ }
+ }
- // free blocks and reset counters
- free(myData);
- myData = 0;
+ // free blocks array and reset counters
+ Standard::Free(myData);
+ myData = nullptr;
myNbBlocks = 0;
+ mySize = 0;
// consistency check
Standard_ProgramError_Raise_if(
Standard_Address& anAddr = myData[iBlock];
if (!anAddr)
{
- anAddr = calloc(Block::Size(myBlockSize, myItemSize), sizeof(char));
+ const Standard_Size aBlockSize = Block::Size(myBlockSize, myItemSize);
+ anAddr = Standard::AllocateOptimal(aBlockSize);
+ memset(anAddr, 0, aBlockSize);
Block aBlock(getBlock(anAddr));
for (Standard_Size anInd = 0; anInd < myBlockSize; anInd++)
if (anOtherBlock.IsSet(anInd))
//=================================================================================================
-template <class T>
-static inline void sswap(T& a, T& b)
-{
- T c = a;
- a = b;
- b = c;
-}
-
-void NCollection_SparseArrayBase::exchange(NCollection_SparseArrayBase& theOther)
+void NCollection_SparseArrayBase::exchange(NCollection_SparseArrayBase& theOther) noexcept
{
if (this == &theOther)
return;
- // swap fields of this and theOther
- sswap(myItemSize, theOther.myItemSize);
- sswap(myBlockSize, theOther.myBlockSize);
- sswap(myNbBlocks, theOther.myNbBlocks);
- sswap(mySize, theOther.mySize);
- sswap(myData, theOther.myData);
+ // swap fields of this and theOther using std::swap for better optimization
+ std::swap(myItemSize, theOther.myItemSize);
+ std::swap(myBlockSize, theOther.myBlockSize);
+ std::swap(myNbBlocks, theOther.myNbBlocks);
+ std::swap(mySize, theOther.mySize);
+ std::swap(myData, theOther.myData);
}
//=================================================================================================
// allocate block if necessary
Standard_Address& anAddr = myData[iBlock];
if (!anAddr)
- anAddr = calloc(Block::Size(myBlockSize, myItemSize), sizeof(char));
-
- // get a block
- Block aBlock(getBlock(anAddr));
+ {
+ const Standard_Size aBlockSize = Block::Size(myBlockSize, myItemSize);
+ anAddr = Standard::AllocateOptimal(aBlockSize);
+ memset(anAddr, 0, aBlockSize);
+ }
- // mark item as defined
+ // get a block and calculate item index
+ Block aBlock(getBlock(anAddr));
Standard_Size anInd = theIndex % myBlockSize;
Standard_Address anItem = getItem(aBlock, anInd);
// either create an item by copy constructor if it is new, or assign it
+ // Optimize: Set() returns non-zero if bit was not set previously
if (aBlock.Set(anInd))
{
(*aBlock.Count)++;
createItem(anItem, theValue);
}
else
+ {
+ // Item already exists, just copy the value
copyItem(anItem, theValue);
+ }
return anItem;
}
// Methods for descendant
//! Empty constructor
- Standard_EXPORT Iterator(const NCollection_SparseArrayBase* theArray = 0);
+ Standard_EXPORT Iterator(const NCollection_SparseArrayBase* theArray = nullptr);
//! Initialize by the specified array
Standard_EXPORT void init(const NCollection_SparseArrayBase* theArray);
friend class Iterator;
private:
- // Copy constructor and assignment operator are private thus not accessible
- NCollection_SparseArrayBase(const NCollection_SparseArrayBase&);
- void operator=(const NCollection_SparseArrayBase&);
+ // Copy constructor and assignment operator are deleted
+ NCollection_SparseArrayBase(const NCollection_SparseArrayBase&) = delete;
+ NCollection_SparseArrayBase& operator=(const NCollection_SparseArrayBase&) = delete;
protected:
// Object life
myBlockSize(theBlockSize),
myNbBlocks(0),
mySize(0),
- myData(0)
+ myData(nullptr)
{
}
//! Exchange contents of theOther and this;
//! assumes that this and theOther have exactly the same type of arguments
- Standard_EXPORT void exchange(NCollection_SparseArrayBase& theOther);
+ Standard_EXPORT void exchange(NCollection_SparseArrayBase& theOther) noexcept;
protected:
// Methods to be provided by descendant