File indexing completed on 2026-09-21 09:17:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef NCollection_PackedMap_HeaderFile
0015 #define NCollection_PackedMap_HeaderFile
0016
0017 #include <Standard.hxx>
0018 #include <Standard_DefineAlloc.hxx>
0019 #include <Standard_NoSuchObject.hxx>
0020 #include <Standard_OStream.hxx>
0021 #include <NCollection_Array1.hxx>
0022 #include <NCollection_Primes.hxx>
0023
0024 #include <cstdint>
0025 #include <cstring>
0026 #include <type_traits>
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 template <typename IntType>
0037 class NCollection_PackedMap
0038 {
0039 static_assert(std::is_integral<IntType>::value,
0040 "NCollection_PackedMap requires an integral type");
0041
0042 public:
0043 DEFINE_STANDARD_ALLOC
0044
0045
0046 static constexpr bool Is64Bit = sizeof(IntType) > 4;
0047
0048
0049 using BlockType = typename std::conditional<Is64Bit, uint64_t, uint32_t>::type;
0050
0051
0052 using IndexType = typename std::conditional<sizeof(IntType) <= 4, uint32_t, uint64_t>::type;
0053
0054
0055 static constexpr int BitsPerBlock = Is64Bit ? 64 : 32;
0056
0057 private:
0058
0059 static constexpr int MaskLowBits = Is64Bit ? 6 : 5;
0060
0061
0062 static constexpr IndexType MASK_LOW = (IndexType(1) << MaskLowBits) - 1;
0063
0064
0065 static constexpr IndexType MASK_HIGH = ~MASK_LOW;
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 class PackedMapNode
0076 {
0077 public:
0078 PackedMapNode(PackedMapNode* thePtr = nullptr)
0079 : myNext(thePtr),
0080 myMask(0),
0081 myData(0)
0082 {
0083 }
0084
0085 PackedMapNode(IntType theValue, PackedMapNode*& thePtr)
0086 : myNext(thePtr),
0087 myMask(static_cast<IndexType>(theValue) & MASK_HIGH),
0088 myData(BlockType(1) << (static_cast<IndexType>(theValue) & MASK_LOW))
0089 {
0090 }
0091
0092 PackedMapNode(IndexType theMask, BlockType theData, PackedMapNode* thePtr)
0093 : myNext(thePtr),
0094 myMask(theMask),
0095 myData(theData)
0096 {
0097 }
0098
0099 IndexType Mask() const { return myMask; }
0100
0101 BlockType Data() const { return myData; }
0102
0103 IndexType& ChangeMask() { return myMask; }
0104
0105 BlockType& ChangeData() { return myData; }
0106
0107
0108 IntType Key() const { return static_cast<IntType>(myMask & MASK_HIGH); }
0109
0110
0111 size_t NbValues() const { return size_t(myMask & MASK_LOW) + 1; }
0112
0113
0114 bool HasValues() const { return (myData != 0); }
0115
0116
0117 bool HasValue(IntType theValue) const
0118 {
0119 return (myData & (BlockType(1) << (static_cast<IndexType>(theValue) & MASK_LOW))) != 0;
0120 }
0121
0122
0123
0124 bool AddValue(IntType theValue)
0125 {
0126 const BlockType aValBit = BlockType(1) << (static_cast<IndexType>(theValue) & MASK_LOW);
0127 if ((myData & aValBit) == 0)
0128 {
0129 myData ^= aValBit;
0130 ++myMask;
0131 return true;
0132 }
0133 return false;
0134 }
0135
0136
0137
0138 bool DelValue(IntType theValue)
0139 {
0140 const BlockType aValBit = BlockType(1) << (static_cast<IndexType>(theValue) & MASK_LOW);
0141 if ((myData & aValBit) != 0)
0142 {
0143 myData ^= aValBit;
0144 myMask--;
0145 return true;
0146 }
0147 return false;
0148 }
0149
0150
0151 PackedMapNode* Next() const { return myNext; }
0152
0153
0154 void SetNext(PackedMapNode* theNext) { myNext = theNext; }
0155
0156 public:
0157
0158 size_t HashCode(size_t theUpper) const
0159 {
0160 return static_cast<size_t>(myMask >> MaskLowBits) % theUpper + 1;
0161 }
0162
0163
0164 bool IsEqual(IndexType theOther) const
0165 {
0166 return (myMask >> MaskLowBits) == (static_cast<IndexType>(theOther));
0167 }
0168
0169 private:
0170 PackedMapNode* myNext;
0171 IndexType myMask;
0172 BlockType myData;
0173 };
0174
0175 public:
0176
0177 class Iterator
0178 {
0179 public:
0180
0181 Iterator()
0182 : myBuckets(nullptr),
0183 myNode(nullptr),
0184 myNbBuckets(0),
0185 myBucket(0),
0186 myIntMask(~BlockType(0)),
0187 myKey(0)
0188 {
0189 }
0190
0191
0192 Iterator(const NCollection_PackedMap& theMap)
0193 : myBuckets(theMap.myData1),
0194 myNode(nullptr),
0195 myNbBuckets(theMap.myData1 != nullptr ? theMap.myNbBuckets : 0),
0196 myBucket(0),
0197 myIntMask(~BlockType(0))
0198 {
0199 findFirst();
0200 myKey = myNode != nullptr ? NCollection_PackedMap::findNext(myNode, myIntMask) : 0;
0201 }
0202
0203
0204 void Initialize(const NCollection_PackedMap& theMap)
0205 {
0206 myBuckets = theMap.myData1;
0207 myBucket = 0;
0208 myNode = nullptr;
0209 myNbBuckets = theMap.myData1 != nullptr ? theMap.myNbBuckets : 0;
0210 findFirst();
0211
0212 myIntMask = ~BlockType(0);
0213 myKey = myNode != nullptr ? findNext(myNode, myIntMask) : 0;
0214 }
0215
0216
0217 void Reset()
0218 {
0219 myBucket = 0;
0220 myNode = nullptr;
0221 findFirst();
0222
0223 myIntMask = ~BlockType(0);
0224 myKey = myNode != nullptr ? findNext(myNode, myIntMask) : 0;
0225 }
0226
0227
0228 IntType Key() const
0229 {
0230 Standard_NoSuchObject_Raise_if((myIntMask == ~BlockType(0)),
0231 "NCollection_PackedMap::Iterator::Key");
0232 return myKey;
0233 }
0234
0235
0236 bool More() const { return myNode != nullptr; }
0237
0238
0239 void Next()
0240 {
0241 for (; myNode != nullptr; next())
0242 {
0243 myKey = NCollection_PackedMap::findNext(myNode, myIntMask);
0244 if (myIntMask != ~BlockType(0))
0245 {
0246 break;
0247 }
0248 }
0249 }
0250
0251 private:
0252
0253 void findFirst()
0254 {
0255 if (myBuckets == nullptr)
0256 {
0257 return;
0258 }
0259 for (; myBucket <= myNbBuckets; ++myBucket)
0260 {
0261 myNode = myBuckets[myBucket];
0262 if (myNode != nullptr)
0263 {
0264 return;
0265 }
0266 }
0267 }
0268
0269
0270 void next()
0271 {
0272 if (myBuckets == nullptr)
0273 {
0274 return;
0275 }
0276 if (myNode != nullptr)
0277 {
0278 myNode = myNode->Next();
0279 if (myNode != nullptr)
0280 {
0281 return;
0282 }
0283 }
0284 ++myBucket;
0285 while (myBucket <= myNbBuckets)
0286 {
0287 myNode = myBuckets[myBucket];
0288 if (myNode != nullptr)
0289 {
0290 return;
0291 }
0292 ++myBucket;
0293 }
0294 }
0295
0296 private:
0297 PackedMapNode** myBuckets;
0298 PackedMapNode* myNode;
0299 size_t myNbBuckets;
0300 size_t myBucket;
0301
0302 BlockType myIntMask;
0303 IntType myKey;
0304 };
0305
0306 public:
0307
0308 NCollection_PackedMap(const size_t theNbBuckets = 1)
0309 : myData1(nullptr),
0310 myNbBuckets(theNbBuckets),
0311 myNbPackedMapNodes(0),
0312 myExtent(0)
0313 {
0314 }
0315
0316
0317 NCollection_PackedMap(const int theNbBuckets)
0318 : myData1(nullptr),
0319 myNbBuckets(theNbBuckets < 1 ? 1 : static_cast<size_t>(theNbBuckets)),
0320 myNbPackedMapNodes(0),
0321 myExtent(0)
0322 {
0323 }
0324
0325
0326 NCollection_PackedMap(const NCollection_PackedMap& theOther)
0327 : myData1(nullptr),
0328 myNbBuckets(1),
0329 myNbPackedMapNodes(0),
0330 myExtent(0)
0331 {
0332 Assign(theOther);
0333 }
0334
0335 NCollection_PackedMap& operator=(const NCollection_PackedMap& theOther)
0336 {
0337 return Assign(theOther);
0338 }
0339
0340
0341 NCollection_PackedMap(NCollection_PackedMap&& theOther) noexcept
0342 : myData1(theOther.myData1),
0343 myNbBuckets(theOther.myNbBuckets),
0344 myNbPackedMapNodes(theOther.myNbPackedMapNodes),
0345 myExtent(theOther.myExtent)
0346 {
0347 theOther.myData1 = nullptr;
0348 theOther.myNbBuckets = 1;
0349 theOther.myNbPackedMapNodes = 0;
0350 theOther.myExtent = 0;
0351 }
0352
0353
0354 NCollection_PackedMap& operator=(NCollection_PackedMap&& theOther) noexcept
0355 {
0356 if (this != &theOther)
0357 {
0358 Clear();
0359 myData1 = theOther.myData1;
0360 myNbBuckets = theOther.myNbBuckets;
0361 myNbPackedMapNodes = theOther.myNbPackedMapNodes;
0362 myExtent = theOther.myExtent;
0363 theOther.myData1 = nullptr;
0364 theOther.myNbBuckets = 1;
0365 theOther.myNbPackedMapNodes = 0;
0366 theOther.myExtent = 0;
0367 }
0368 return *this;
0369 }
0370
0371
0372 NCollection_PackedMap& Assign(const NCollection_PackedMap& theOther)
0373 {
0374 if (this != &theOther)
0375 {
0376 Clear();
0377 if (!theOther.IsEmpty())
0378 {
0379 ReSize(theOther.myNbPackedMapNodes);
0380 const size_t nBucketsSrc = theOther.myNbBuckets;
0381 const size_t nBuckets = myNbBuckets;
0382 for (size_t i = 0; i <= nBucketsSrc; ++i)
0383 {
0384 for (const PackedMapNode* p = theOther.myData1[i]; p != nullptr;)
0385 {
0386 const size_t aHashCode = p->HashCode(nBuckets);
0387 myData1[aHashCode] = new PackedMapNode(p->Mask(), p->Data(), myData1[aHashCode]);
0388 ++myNbPackedMapNodes;
0389 p = p->Next();
0390 }
0391 }
0392 }
0393 myExtent = theOther.myExtent;
0394 }
0395 return *this;
0396 }
0397
0398
0399 void ReSize(const size_t theNbBuckets)
0400 {
0401 size_t aNewBuck = NCollection_Primes::NextPrimeForMap(theNbBuckets);
0402 if (aNewBuck <= myNbBuckets)
0403 {
0404 if (!IsEmpty())
0405 {
0406 return;
0407 }
0408 aNewBuck = myNbBuckets;
0409 }
0410
0411 PackedMapNode** aNewData = reinterpret_cast<PackedMapNode**>(
0412 Standard::AllocateOptimal((aNewBuck + 1) * sizeof(PackedMapNode*)));
0413 memset(aNewData, 0, (aNewBuck + 1) * sizeof(PackedMapNode*));
0414 if (myData1 != nullptr)
0415 {
0416 PackedMapNode** anOldData = myData1;
0417 for (size_t i = 0; i <= myNbBuckets; ++i)
0418 {
0419 for (PackedMapNode* p = anOldData[i]; p != nullptr;)
0420 {
0421 size_t k = p->HashCode(aNewBuck);
0422 PackedMapNode* q = p->Next();
0423 p->SetNext(aNewData[k]);
0424 aNewData[k] = p;
0425 p = q;
0426 }
0427 }
0428 }
0429
0430 Standard::Free(myData1);
0431 myNbBuckets = aNewBuck;
0432 myData1 = aNewData;
0433 }
0434
0435
0436 void ReSize(const int theNbBuckets)
0437 {
0438 ReSize(static_cast<size_t>(theNbBuckets < 0 ? 0 : theNbBuckets));
0439 }
0440
0441
0442 void Clear()
0443 {
0444 if (!IsEmpty())
0445 {
0446 for (size_t aBucketIter = 0; aBucketIter <= myNbBuckets; ++aBucketIter)
0447 {
0448 if (myData1[aBucketIter])
0449 {
0450 for (PackedMapNode* aSubNodeIter = myData1[aBucketIter]; aSubNodeIter != nullptr;)
0451 {
0452 PackedMapNode* q = aSubNodeIter->Next();
0453 delete aSubNodeIter;
0454 aSubNodeIter = q;
0455 }
0456 }
0457 }
0458 }
0459
0460 myNbPackedMapNodes = 0;
0461 Standard::Free(myData1);
0462 myData1 = nullptr;
0463 myExtent = 0;
0464 }
0465
0466 ~NCollection_PackedMap() { Clear(); }
0467
0468
0469
0470
0471 bool Add(const IntType theKey)
0472 {
0473 if (Resizable())
0474 {
0475 ReSize(myNbPackedMapNodes);
0476 }
0477
0478 const IndexType aKeyInt = packedKeyIndex(theKey);
0479 const size_t aHashCode = hashCode(aKeyInt, myNbBuckets);
0480 PackedMapNode* aBucketHead = myData1[aHashCode];
0481 for (PackedMapNode* p = aBucketHead; p != nullptr; p = p->Next())
0482 {
0483 if (p->IsEqual(aKeyInt))
0484 {
0485 if (p->AddValue(theKey))
0486 {
0487 ++myExtent;
0488 return true;
0489 }
0490 return false;
0491 }
0492 }
0493
0494 myData1[aHashCode] = new PackedMapNode(theKey, aBucketHead);
0495 ++myNbPackedMapNodes;
0496 ++myExtent;
0497 return true;
0498 }
0499
0500
0501
0502
0503 bool Contains(const IntType theKey) const
0504 {
0505 if (IsEmpty())
0506 {
0507 return false;
0508 }
0509
0510 const IndexType aKeyInt = packedKeyIndex(theKey);
0511 for (PackedMapNode* p = myData1[hashCode(aKeyInt, myNbBuckets)]; p != nullptr;)
0512 {
0513 if (p->IsEqual(aKeyInt))
0514 {
0515 return p->HasValue(theKey);
0516 }
0517 p = p->Next();
0518 }
0519 return false;
0520 }
0521
0522
0523
0524
0525 bool Remove(const IntType theKey)
0526 {
0527 if (IsEmpty())
0528 {
0529 return false;
0530 }
0531
0532 const IndexType aKeyInt = packedKeyIndex(theKey);
0533 PackedMapNode*& aBucketHead = myData1[hashCode(aKeyInt, myNbBuckets)];
0534 PackedMapNode* p = aBucketHead;
0535 PackedMapNode* q = nullptr;
0536 while (p)
0537 {
0538 if (p->IsEqual(aKeyInt))
0539 {
0540 bool aResult = p->DelValue(theKey);
0541 if (aResult)
0542 {
0543 --myExtent;
0544 if (!p->HasValues())
0545 {
0546 --myNbPackedMapNodes;
0547 if (q != nullptr)
0548 {
0549 q->SetNext(p->Next());
0550 }
0551 else
0552 {
0553 aBucketHead = p->Next();
0554 }
0555 delete p;
0556 }
0557 }
0558 return aResult;
0559 }
0560 q = p;
0561 p = p->Next();
0562 }
0563 return false;
0564 }
0565
0566
0567 size_t NbBuckets() const { return myNbBuckets; }
0568
0569
0570 int Extent() const { return static_cast<int>(myExtent); }
0571
0572
0573 int Length() const { return static_cast<int>(myExtent); }
0574
0575
0576 size_t Size() const { return myExtent; }
0577
0578
0579 bool IsEmpty() const { return myNbPackedMapNodes == 0; }
0580
0581
0582 IntType GetMinimalMapped() const
0583 {
0584 if (IsEmpty())
0585 {
0586 return std::numeric_limits<IntType>::max();
0587 }
0588
0589 IntType aResult = std::numeric_limits<IntType>::max();
0590 const PackedMapNode* pFoundNode = nullptr;
0591 for (size_t i = 0; i <= myNbBuckets; ++i)
0592 {
0593 for (const PackedMapNode* p = myData1[i]; p != nullptr; p = p->Next())
0594 {
0595 const IntType aKey = p->Key();
0596 if (aResult > aKey)
0597 {
0598 aResult = aKey;
0599 pFoundNode = p;
0600 }
0601 }
0602 }
0603 if (pFoundNode)
0604 {
0605 BlockType aFullMask = ~BlockType(0);
0606 aResult = findNext(pFoundNode, aFullMask);
0607 }
0608 return aResult;
0609 }
0610
0611
0612 IntType GetMaximalMapped() const
0613 {
0614 if (IsEmpty())
0615 {
0616 return std::numeric_limits<IntType>::lowest();
0617 }
0618
0619 IntType aResult = std::numeric_limits<IntType>::lowest();
0620 const PackedMapNode* pFoundNode = nullptr;
0621 for (size_t i = 0; i <= myNbBuckets; ++i)
0622 {
0623 for (const PackedMapNode* p = myData1[i]; p != nullptr; p = p->Next())
0624 {
0625 const IntType aKey = p->Key();
0626 if (aResult < aKey)
0627 {
0628 aResult = aKey;
0629 pFoundNode = p;
0630 }
0631 }
0632 }
0633 if (pFoundNode)
0634 {
0635 BlockType aFullMask = ~BlockType(0);
0636 aResult = findPrev(pFoundNode, aFullMask);
0637 }
0638 return aResult;
0639 }
0640
0641 public:
0642
0643
0644
0645 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0646 "NCollection_PackedMapAlgo.hxx instead.")
0647 void Union(const NCollection_PackedMap& theLeft, const NCollection_PackedMap& theRight);
0648
0649
0650 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0651 "NCollection_PackedMapAlgo.hxx instead.")
0652 bool Unite(const NCollection_PackedMap& theOther);
0653
0654
0655 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0656 "NCollection_PackedMapAlgo.hxx instead.")
0657 void Intersection(const NCollection_PackedMap& theLeft, const NCollection_PackedMap& theRight);
0658
0659
0660 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0661 "NCollection_PackedMapAlgo.hxx instead.")
0662 bool Intersect(const NCollection_PackedMap& theOther);
0663
0664
0665 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0666 "NCollection_PackedMapAlgo.hxx instead.")
0667 void Subtraction(const NCollection_PackedMap& theLeft, const NCollection_PackedMap& theRight);
0668
0669
0670 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0671 "NCollection_PackedMapAlgo.hxx instead.")
0672 bool Subtract(const NCollection_PackedMap& theOther);
0673
0674
0675 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0676 "NCollection_PackedMapAlgo.hxx instead.")
0677 void Difference(const NCollection_PackedMap& theLeft, const NCollection_PackedMap& theRight);
0678
0679
0680 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0681 "NCollection_PackedMapAlgo.hxx instead.")
0682 bool Differ(const NCollection_PackedMap& theOther);
0683
0684
0685 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0686 "NCollection_PackedMapAlgo.hxx instead.")
0687 bool IsEqual(const NCollection_PackedMap& theOther) const;
0688
0689
0690 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0691 "NCollection_PackedMapAlgo.hxx instead.")
0692 bool IsSubset(const NCollection_PackedMap& theOther) const;
0693
0694
0695 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0696 "NCollection_PackedMapAlgo.hxx instead.")
0697 bool HasIntersection(const NCollection_PackedMap& theOther) const;
0698
0699
0700 Standard_DEPRECATED("This method will be removed after OCCT 7.9 release. Use methods from "
0701 "NCollection_PackedMapAlgo.hxx instead.")
0702 bool Contains(const NCollection_PackedMap& theOther) const;
0703
0704 protected:
0705
0706 bool Resizable() const { return IsEmpty() || (myNbPackedMapNodes > myNbBuckets); }
0707
0708
0709 static IndexType packedKeyIndex(IntType theKey)
0710 {
0711 return static_cast<IndexType>(theKey) >> MaskLowBits;
0712 }
0713
0714
0715 static size_t hashCode(IndexType theKeyIndex, size_t theNbBuckets)
0716 {
0717 return static_cast<size_t>(theKeyIndex) % theNbBuckets + 1;
0718 }
0719
0720
0721
0722 static size_t population(IndexType& theMask, BlockType theData)
0723 {
0724 if constexpr (Is64Bit)
0725 {
0726
0727 uint64_t aRes = theData - ((theData >> 1) & 0x5555555555555555ULL);
0728 aRes = (aRes & 0x3333333333333333ULL) + ((aRes >> 2) & 0x3333333333333333ULL);
0729 aRes = (aRes + (aRes >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
0730 aRes = aRes + (aRes >> 8);
0731 aRes = aRes + (aRes >> 16);
0732 aRes = aRes + (aRes >> 32);
0733 theMask = (theMask & MASK_HIGH) | ((static_cast<IndexType>(aRes) - 1) & MASK_LOW);
0734 return size_t(aRes & 0x7f);
0735 }
0736 else
0737 {
0738
0739 uint32_t aRes =
0740 static_cast<uint32_t>(theData) - ((static_cast<uint32_t>(theData) >> 1) & 0x55555555);
0741 aRes = (aRes & 0x33333333) + ((aRes >> 2) & 0x33333333);
0742 aRes = (aRes + (aRes >> 4)) & 0x0f0f0f0f;
0743 aRes = aRes + (aRes >> 8);
0744 aRes = aRes + (aRes >> 16);
0745 theMask = (theMask & MASK_HIGH) | ((aRes - 1) & MASK_LOW);
0746 return size_t(aRes & 0x3f);
0747 }
0748 }
0749
0750
0751
0752 static IntType findNext(const PackedMapNode* theNode, BlockType& theMask)
0753 {
0754 BlockType val = theNode->Data() & theMask;
0755 int nZeros = 0;
0756 if (val == 0)
0757 {
0758 theMask = ~BlockType(0);
0759 }
0760 else
0761 {
0762 BlockType aMask = ~BlockType(0);
0763 if constexpr (Is64Bit)
0764 {
0765 if ((val & 0x00000000ffffffffULL) == 0)
0766 {
0767 aMask = 0xffffffff00000000ULL;
0768 nZeros = 32;
0769 val >>= 32;
0770 }
0771 }
0772 if ((val & 0x0000ffff) == 0)
0773 {
0774 aMask <<= 16;
0775 nZeros += 16;
0776 val >>= 16;
0777 }
0778 if ((val & 0x000000ff) == 0)
0779 {
0780 aMask <<= 8;
0781 nZeros += 8;
0782 val >>= 8;
0783 }
0784 if ((val & 0x0000000f) == 0)
0785 {
0786 aMask <<= 4;
0787 nZeros += 4;
0788 val >>= 4;
0789 }
0790 if ((val & 0x00000003) == 0)
0791 {
0792 aMask <<= 2;
0793 nZeros += 2;
0794 val >>= 2;
0795 }
0796 if ((val & 0x00000001) == 0)
0797 {
0798 aMask <<= 1;
0799 nZeros++;
0800 }
0801 theMask = (aMask << 1);
0802 }
0803 return static_cast<IntType>(nZeros) + theNode->Key();
0804 }
0805
0806
0807
0808 static IntType findPrev(const PackedMapNode* theNode, BlockType& theMask)
0809 {
0810 BlockType val = theNode->Data() & theMask;
0811 int nZeros = 0;
0812 if (val == 0)
0813 {
0814 theMask = ~BlockType(0);
0815 }
0816 else
0817 {
0818 BlockType aMask = ~BlockType(0);
0819 if constexpr (Is64Bit)
0820 {
0821 if ((val & 0xffffffff00000000ULL) == 0)
0822 {
0823 aMask = 0x00000000ffffffffULL;
0824 nZeros = 32;
0825 val <<= 32;
0826 }
0827 }
0828 if ((val & BlockType(0xffff0000) << (Is64Bit ? 32 : 0)) == 0)
0829 {
0830 aMask >>= 16;
0831 nZeros += 16;
0832 val <<= 16;
0833 }
0834 if ((val & BlockType(0xff000000) << (Is64Bit ? 32 : 0)) == 0)
0835 {
0836 aMask >>= 8;
0837 nZeros += 8;
0838 val <<= 8;
0839 }
0840 if ((val & BlockType(0xf0000000) << (Is64Bit ? 32 : 0)) == 0)
0841 {
0842 aMask >>= 4;
0843 nZeros += 4;
0844 val <<= 4;
0845 }
0846 if ((val & BlockType(0xc0000000) << (Is64Bit ? 32 : 0)) == 0)
0847 {
0848 aMask >>= 2;
0849 nZeros += 2;
0850 val <<= 2;
0851 }
0852 if ((val & BlockType(0x80000000) << (Is64Bit ? 32 : 0)) == 0)
0853 {
0854 aMask >>= 1;
0855 nZeros++;
0856 }
0857 theMask = (aMask >> 1);
0858 }
0859 return static_cast<IntType>((BitsPerBlock - 1) - nZeros) + theNode->Key();
0860 }
0861
0862 private:
0863 PackedMapNode** myData1;
0864 size_t myNbBuckets;
0865 size_t myNbPackedMapNodes;
0866 size_t myExtent;
0867 };
0868
0869
0870 #include <NCollection_PackedMapAlgo.hxx>
0871
0872
0873 template <typename IntType>
0874 void NCollection_PackedMap<IntType>::Union(const NCollection_PackedMap& theLeft,
0875 const NCollection_PackedMap& theRight)
0876 {
0877 NCollection_PackedMapAlgo::Union(*this, theLeft, theRight);
0878 }
0879
0880 template <typename IntType>
0881 bool NCollection_PackedMap<IntType>::Unite(const NCollection_PackedMap& theOther)
0882 {
0883 return NCollection_PackedMapAlgo::Unite(*this, theOther);
0884 }
0885
0886 template <typename IntType>
0887 void NCollection_PackedMap<IntType>::Intersection(const NCollection_PackedMap& theLeft,
0888 const NCollection_PackedMap& theRight)
0889 {
0890 NCollection_PackedMapAlgo::Intersection(*this, theLeft, theRight);
0891 }
0892
0893 template <typename IntType>
0894 bool NCollection_PackedMap<IntType>::Intersect(const NCollection_PackedMap& theOther)
0895 {
0896 return NCollection_PackedMapAlgo::Intersect(*this, theOther);
0897 }
0898
0899 template <typename IntType>
0900 void NCollection_PackedMap<IntType>::Subtraction(const NCollection_PackedMap& theLeft,
0901 const NCollection_PackedMap& theRight)
0902 {
0903 NCollection_PackedMapAlgo::Subtraction(*this, theLeft, theRight);
0904 }
0905
0906 template <typename IntType>
0907 bool NCollection_PackedMap<IntType>::Subtract(const NCollection_PackedMap& theOther)
0908 {
0909 return NCollection_PackedMapAlgo::Subtract(*this, theOther);
0910 }
0911
0912 template <typename IntType>
0913 void NCollection_PackedMap<IntType>::Difference(const NCollection_PackedMap& theLeft,
0914 const NCollection_PackedMap& theRight)
0915 {
0916 NCollection_PackedMapAlgo::Difference(*this, theLeft, theRight);
0917 }
0918
0919 template <typename IntType>
0920 bool NCollection_PackedMap<IntType>::Differ(const NCollection_PackedMap& theOther)
0921 {
0922 return NCollection_PackedMapAlgo::Differ(*this, theOther);
0923 }
0924
0925 template <typename IntType>
0926 bool NCollection_PackedMap<IntType>::IsEqual(const NCollection_PackedMap& theOther) const
0927 {
0928 return NCollection_PackedMapAlgo::IsEqual(*this, theOther);
0929 }
0930
0931 template <typename IntType>
0932 bool NCollection_PackedMap<IntType>::IsSubset(const NCollection_PackedMap& theOther) const
0933 {
0934 return NCollection_PackedMapAlgo::IsSubset(*this, theOther);
0935 }
0936
0937 template <typename IntType>
0938 bool NCollection_PackedMap<IntType>::HasIntersection(const NCollection_PackedMap& theOther) const
0939 {
0940 return NCollection_PackedMapAlgo::HasIntersection(*this, theOther);
0941 }
0942
0943 template <typename IntType>
0944 bool NCollection_PackedMap<IntType>::Contains(const NCollection_PackedMap& theOther) const
0945 {
0946 return NCollection_PackedMapAlgo::Contains(*this, theOther);
0947 }
0948
0949 #endif