Warning, file /include/opencascade/NCollection_SparseArrayBase.hxx was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef NCollection_SparseArrayBase_HeaderFile
0017 #define NCollection_SparseArrayBase_HeaderFile
0018
0019 #include <Standard.hxx>
0020 #include <Standard_TypeDef.hxx>
0021 #include <Standard_OutOfRange.hxx>
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 class NCollection_SparseArrayBase
0034 {
0035 public:
0036
0037
0038
0039
0040 using CreateItemFunc = void (*)(void* theAddress, void* theOther);
0041
0042 using DestroyItemFunc = void (*)(void* theAddress);
0043
0044 using CopyItemFunc = void (*)(void* theAddress, void* theOther);
0045
0046
0047
0048 public:
0049
0050
0051
0052
0053 size_t Size() const noexcept { return mySize; }
0054
0055
0056 Standard_EXPORT bool HasValue(const size_t theIndex) const;
0057
0058
0059
0060 private:
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 class Block
0074 {
0075 public:
0076 typedef unsigned char Cell;
0077
0078
0079 static constexpr size_t BitsPerCell() noexcept { return sizeof(Cell) * 8; }
0080
0081 public:
0082
0083 Block(void* const theAddr, const size_t theNbItems, const size_t theItemSize)
0084 : Count((size_t*)theAddr),
0085 Array((char*)theAddr + sizeof(size_t)),
0086 Bits((Cell*)((char*)theAddr + sizeof(size_t) + theNbItems * theItemSize))
0087 {
0088 }
0089
0090
0091 static constexpr size_t Size(const size_t theNbItems, const size_t theItemSize) noexcept
0092 {
0093 return sizeof(size_t) + sizeof(Cell) * ((theNbItems + BitsPerCell() - 1) / BitsPerCell())
0094 + theNbItems * theItemSize;
0095 }
0096
0097
0098 static char* ToArray(void* const theAddress,
0099 const size_t ,
0100 const size_t ) noexcept
0101 {
0102 return (char*)theAddress + sizeof(size_t);
0103 }
0104
0105 public:
0106
0107
0108 Cell Set(size_t i) noexcept
0109 {
0110 Cell* abyte = Bits + i / BitsPerCell();
0111 Cell amask = (Cell)('\1' << (i % BitsPerCell()));
0112 Cell anold = (Cell)(*abyte & amask);
0113 *abyte = (Cell)(*abyte | amask);
0114 return !anold;
0115 }
0116
0117
0118 Cell IsSet(size_t i) noexcept
0119 {
0120 Cell* abyte = Bits + i / BitsPerCell();
0121 Cell amask = (Cell)('\1' << (i % BitsPerCell()));
0122 return (Cell)(*abyte & amask);
0123 }
0124
0125
0126
0127 Cell Unset(size_t i) noexcept
0128 {
0129 Cell* abyte = Bits + i / BitsPerCell();
0130 Cell amask = (Cell)('\1' << (i % BitsPerCell()));
0131 Cell anold = (Cell)(*abyte & amask);
0132 *abyte = (Cell)(*abyte & ~amask);
0133 return anold;
0134 }
0135
0136 public:
0137 size_t* Count;
0138 void* Array;
0139 Cell* Bits;
0140 };
0141
0142 public:
0143
0144
0145
0146
0147 class Iterator
0148 {
0149 public:
0150
0151
0152
0153 void Restart() { init(myArr); }
0154
0155
0156 bool More() const noexcept { return myHasMore; }
0157
0158
0159 Standard_EXPORT void Next();
0160
0161
0162 size_t Index() const noexcept { return myIBlock * myArr->myBlockSize + myInd; }
0163
0164 protected:
0165
0166
0167
0168 Standard_EXPORT Iterator(const NCollection_SparseArrayBase* theArray = nullptr);
0169
0170
0171 Standard_EXPORT void init(const NCollection_SparseArrayBase* theArray);
0172
0173
0174 void* value() const noexcept { return myArr->getItem(myBlock, myInd); }
0175
0176 private:
0177 const NCollection_SparseArrayBase* myArr;
0178 bool myHasMore;
0179 size_t myIBlock;
0180 size_t myInd;
0181 Block myBlock;
0182 };
0183 friend class Iterator;
0184
0185 private:
0186
0187 NCollection_SparseArrayBase(const NCollection_SparseArrayBase&) = delete;
0188 NCollection_SparseArrayBase& operator=(const NCollection_SparseArrayBase&) = delete;
0189
0190 protected:
0191
0192
0193
0194
0195 NCollection_SparseArrayBase(size_t theItemSize,
0196 size_t theBlockSize,
0197 DestroyItemFunc theDestroyItem) noexcept
0198 : myItemSize(theItemSize),
0199 myBlockSize(theBlockSize),
0200 myNbBlocks(0),
0201 mySize(0),
0202 myData(nullptr),
0203 myDestroyItem(theDestroyItem)
0204 {
0205 }
0206
0207
0208
0209 ~NCollection_SparseArrayBase() { clearItems(myDestroyItem); }
0210
0211 protected:
0212
0213
0214
0215 Block getBlock(void* const theAddr) const noexcept
0216 {
0217 return Block(theAddr, myBlockSize, myItemSize);
0218 }
0219
0220
0221 void* getItem(const Block& theBlock, size_t theInd) const noexcept
0222 {
0223 return ((char*)theBlock.Array) + myItemSize * theInd;
0224 }
0225
0226
0227 void* getValue(const size_t theIndex) const
0228 {
0229 Standard_OutOfRange_Raise_if(
0230 !HasValue(theIndex),
0231 "NCollection_SparseArray::Value()") return Block::ToArray(myData[theIndex / myBlockSize],
0232 myBlockSize,
0233 myItemSize)
0234 + myItemSize * (theIndex % myBlockSize);
0235 }
0236
0237
0238
0239 Standard_EXPORT void clearItems(DestroyItemFunc theDestroyItem);
0240
0241
0242
0243
0244 Standard_EXPORT bool unsetValue(const size_t theIndex, DestroyItemFunc theDestroyItem);
0245
0246
0247
0248
0249 Standard_EXPORT void* setValue(const size_t theIndex,
0250 void* const theValue,
0251 CreateItemFunc theCreateItem,
0252 CopyItemFunc theCopyItem);
0253
0254
0255
0256
0257
0258
0259 Standard_EXPORT void assign(const NCollection_SparseArrayBase& theOther,
0260 CreateItemFunc theCreateItem,
0261 DestroyItemFunc theDestroyItem,
0262 CopyItemFunc theCopyItem);
0263
0264
0265
0266 Standard_EXPORT void exchange(NCollection_SparseArrayBase& theOther) noexcept;
0267
0268 private:
0269
0270
0271
0272 void allocData(const size_t iBlock);
0273
0274
0275 void freeBlock(const size_t iBlock, DestroyItemFunc theDestroyItem);
0276
0277 protected:
0278 size_t myItemSize;
0279 size_t myBlockSize;
0280 size_t myNbBlocks;
0281 size_t mySize;
0282 void** myData;
0283 DestroyItemFunc myDestroyItem;
0284 };
0285
0286 #endif