Warning, file /include/opencascade/NCollection_Map.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_Map_HeaderFile
0017 #define NCollection_Map_HeaderFile
0018
0019 #include <NCollection_DataMap.hxx>
0020 #include <NCollection_TListNode.hxx>
0021 #include <NCollection_StlIterator.hxx>
0022 #include <NCollection_DefaultHasher.hxx>
0023
0024 #include <Standard_NoSuchObject.hxx>
0025 #include <utility>
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 template < class TheKeyType,
0056 class Hasher = NCollection_DefaultHasher<TheKeyType> >
0057 class NCollection_Map : public NCollection_BaseMap
0058 {
0059 public:
0060
0061 typedef TheKeyType key_type;
0062 typedef Hasher hasher;
0063
0064 public:
0065
0066 class MapNode : public NCollection_TListNode<TheKeyType>
0067 {
0068 public:
0069
0070 MapNode (const TheKeyType& theKey,
0071 NCollection_ListNode* theNext) :
0072 NCollection_TListNode<TheKeyType> (theKey, theNext) {}
0073
0074 MapNode (TheKeyType&& theKey,
0075 NCollection_ListNode* theNext) :
0076 NCollection_TListNode<TheKeyType> (std::forward<TheKeyType>(theKey), theNext) {}
0077
0078 const TheKeyType& Key (void)
0079 { return this->Value(); }
0080
0081 };
0082
0083 public:
0084
0085 class Iterator : public NCollection_BaseMap::Iterator
0086 {
0087 public:
0088
0089 Iterator (void) :
0090 NCollection_BaseMap::Iterator() {}
0091
0092 Iterator (const NCollection_Map& theMap) :
0093 NCollection_BaseMap::Iterator(theMap) {}
0094
0095 Standard_Boolean More(void) const
0096 { return PMore(); }
0097
0098 void Next(void)
0099 { PNext(); }
0100
0101 const TheKeyType& Value(void) const
0102 {
0103 Standard_NoSuchObject_Raise_if (!More(), "NCollection_Map::Iterator::Value");
0104 return ((MapNode *) myNode)->Value();
0105 }
0106
0107
0108 const TheKeyType& Key (void) const
0109 {
0110 Standard_NoSuchObject_Raise_if (!More(), "NCollection_Map::Iterator::Key");
0111 return ((MapNode *) myNode)->Value();
0112 }
0113 };
0114
0115
0116 typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheKeyType, true> const_iterator;
0117
0118
0119 const_iterator cbegin() const { return Iterator (*this); }
0120
0121
0122 const_iterator cend() const { return Iterator(); }
0123
0124 public:
0125
0126
0127
0128 NCollection_Map() : NCollection_BaseMap (1, Standard_True, Handle(NCollection_BaseAllocator)()) {}
0129
0130
0131 explicit NCollection_Map (const Standard_Integer theNbBuckets,
0132 const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
0133 : NCollection_BaseMap (theNbBuckets, Standard_True, theAllocator) {}
0134
0135
0136 NCollection_Map(const NCollection_Map& theOther) :
0137 NCollection_BaseMap(theOther.NbBuckets(), Standard_True, theOther.myAllocator)
0138 {
0139 const int anExt = theOther.Extent();
0140 if (anExt <= 0)
0141 return;
0142 ReSize(anExt - 1);
0143 for (Iterator anIter(theOther); anIter.More(); anIter.Next())
0144 Add(anIter.Key());
0145 }
0146
0147
0148 NCollection_Map (NCollection_Map&& theOther) noexcept :
0149 NCollection_BaseMap (std::forward<NCollection_BaseMap>(theOther))
0150 {}
0151
0152
0153
0154 void Exchange (NCollection_Map& theOther)
0155 {
0156 this->exchangeMapsData (theOther);
0157 }
0158
0159
0160
0161 NCollection_Map& Assign (const NCollection_Map& theOther)
0162 {
0163 if (this == &theOther)
0164 return *this;
0165
0166 Clear();
0167 int anExt = theOther.Extent();
0168 if (anExt)
0169 {
0170 ReSize (anExt-1);
0171 Iterator anIter(theOther);
0172 for (; anIter.More(); anIter.Next())
0173 Add (anIter.Key());
0174 }
0175 return *this;
0176 }
0177
0178
0179 NCollection_Map& operator= (const NCollection_Map& theOther)
0180 {
0181 return Assign(theOther);
0182 }
0183
0184
0185 NCollection_Map& operator= (NCollection_Map&& theOther) noexcept
0186 {
0187 if (this == &theOther)
0188 return *this;
0189 exchangeMapsData(theOther);
0190 return *this;
0191 }
0192
0193
0194 void ReSize (const Standard_Integer N)
0195 {
0196 NCollection_ListNode** newdata = 0L;
0197 NCollection_ListNode** dummy = 0L;
0198 Standard_Integer newBuck;
0199 if (BeginResize (N, newBuck, newdata, dummy))
0200 {
0201 if (myData1)
0202 {
0203 MapNode** olddata = (MapNode**) myData1;
0204 MapNode *p, *q;
0205 for (int i = 0; i <= NbBuckets(); i++)
0206 {
0207 if (olddata[i])
0208 {
0209 p = olddata[i];
0210 while (p)
0211 {
0212 const size_t k = HashCode(p->Key(),newBuck);
0213 q = (MapNode*) p->Next();
0214 p->Next() = newdata[k];
0215 newdata[k] = p;
0216 p = q;
0217 }
0218 }
0219 }
0220 }
0221 EndResize (N, newBuck, newdata, dummy);
0222 }
0223 }
0224
0225
0226 Standard_Boolean Add(const TheKeyType& theKey)
0227 {
0228 if (Resizable())
0229 ReSize(Extent());
0230 MapNode* aNode;
0231 size_t aHash;
0232 if (lookup(theKey, aNode, aHash))
0233 {
0234 return Standard_False;
0235 }
0236 MapNode** data = (MapNode**)myData1;
0237 data[aHash] = new (this->myAllocator) MapNode(theKey,data[aHash]);
0238 Increment();
0239 return Standard_True;
0240 }
0241
0242
0243 Standard_Boolean Add(TheKeyType&& theKey)
0244 {
0245 if (Resizable())
0246 ReSize(Extent());
0247 MapNode* aNode;
0248 size_t aHash;
0249 if (lookup(theKey, aNode, aHash))
0250 {
0251 return Standard_False;
0252 }
0253 MapNode** data = (MapNode**)myData1;
0254 data[aHash] = new (this->myAllocator) MapNode(std::forward<TheKeyType>(theKey),data[aHash]);
0255 Increment();
0256 return Standard_True;
0257 }
0258
0259
0260
0261 const TheKeyType& Added(const TheKeyType& theKey)
0262 {
0263 if (Resizable())
0264 ReSize(Extent());
0265 MapNode* aNode;
0266 size_t aHash;
0267 if (lookup(theKey, aNode, aHash))
0268 {
0269 return aNode->Key();
0270 }
0271 MapNode** data = (MapNode**)myData1;
0272 data[aHash] = new (this->myAllocator) MapNode(theKey,data[aHash]);
0273 Increment();
0274 return data[aHash]->Key();
0275 }
0276
0277
0278
0279 const TheKeyType& Added(TheKeyType&& theKey)
0280 {
0281 if (Resizable())
0282 ReSize(Extent());
0283 MapNode* aNode;
0284 size_t aHash;
0285 if (lookup(theKey, aNode, aHash))
0286 {
0287 return aNode->Key();
0288 }
0289 MapNode** data = (MapNode**)myData1;
0290 data[aHash] = new (this->myAllocator) MapNode(std::forward<TheKeyType>(theKey),data[aHash]);
0291 Increment();
0292 return data[aHash]->Key();
0293 }
0294
0295
0296 Standard_Boolean Contains(const TheKeyType& theKey) const
0297 {
0298 MapNode* p;
0299 return lookup(theKey, p);
0300 }
0301
0302
0303 Standard_Boolean Remove(const TheKeyType& K)
0304 {
0305 if (IsEmpty())
0306 return Standard_False;
0307 MapNode** data = (MapNode**) myData1;
0308 const size_t k = HashCode(K,NbBuckets());
0309 MapNode* p = data[k];
0310 MapNode* q = NULL;
0311 while (p)
0312 {
0313 if (IsEqual(p->Key(),K))
0314 {
0315 Decrement();
0316 if (q)
0317 q->Next() = p->Next();
0318 else
0319 data[k] = (MapNode*) p->Next();
0320 p->~MapNode();
0321 this->myAllocator->Free(p);
0322 return Standard_True;
0323 }
0324 q = p;
0325 p = (MapNode*) p->Next();
0326 }
0327 return Standard_False;
0328 }
0329
0330
0331
0332 void Clear(const Standard_Boolean doReleaseMemory = Standard_False)
0333 { Destroy (MapNode::delNode, doReleaseMemory); }
0334
0335
0336 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator)
0337 {
0338 Clear(theAllocator != this->myAllocator);
0339 this->myAllocator = ( ! theAllocator.IsNull() ? theAllocator :
0340 NCollection_BaseAllocator::CommonBaseAllocator() );
0341 }
0342
0343
0344 virtual ~NCollection_Map (void)
0345 { Clear(true); }
0346
0347
0348 Standard_Integer Size(void) const
0349 { return Extent(); }
0350
0351 public:
0352
0353
0354
0355
0356 Standard_Boolean IsEqual (const NCollection_Map& theOther) const
0357 {
0358 return Extent() == theOther.Extent()
0359 && Contains (theOther);
0360 }
0361
0362
0363 Standard_Boolean Contains (const NCollection_Map& theOther) const
0364 {
0365 if (this == &theOther
0366 || theOther.IsEmpty())
0367 {
0368 return Standard_True;
0369 }
0370 else if (Extent() < theOther.Extent())
0371 {
0372 return Standard_False;
0373 }
0374
0375 for (Iterator anIter (theOther); anIter.More(); anIter.Next())
0376 {
0377 if (!Contains (anIter.Key()))
0378 {
0379 return Standard_False;
0380 }
0381 }
0382
0383 return Standard_True;
0384 }
0385
0386
0387
0388
0389
0390 void Union (const NCollection_Map& theLeft,
0391 const NCollection_Map& theRight)
0392 {
0393 if (&theLeft == &theRight)
0394 {
0395 Assign (theLeft);
0396 return;
0397 }
0398
0399 if (this != &theLeft
0400 && this != &theRight)
0401 {
0402 Clear();
0403 }
0404
0405 if (this != &theLeft)
0406 {
0407 for (Iterator anIter (theLeft); anIter.More(); anIter.Next())
0408 {
0409 Add (anIter.Key());
0410 }
0411 }
0412 if (this != &theRight)
0413 {
0414 for (Iterator anIter (theRight); anIter.More(); anIter.Next())
0415 {
0416 Add (anIter.Key());
0417 }
0418 }
0419 }
0420
0421
0422
0423
0424
0425 Standard_Boolean Unite (const NCollection_Map& theOther)
0426 {
0427 if (this == &theOther)
0428 {
0429 return Standard_False;
0430 }
0431
0432 const Standard_Integer anOldExtent = Extent();
0433 Union (*this, theOther);
0434 return anOldExtent != Extent();
0435 }
0436
0437
0438 Standard_Boolean HasIntersection (const NCollection_Map& theMap) const
0439 {
0440 const NCollection_Map* aMap1 = this;
0441 const NCollection_Map* aMap2 = &theMap;
0442 if (theMap.Size() < Size())
0443 {
0444 aMap1 = &theMap;
0445 aMap2 = this;
0446 }
0447
0448 for (NCollection_Map::Iterator aIt(*aMap1); aIt.More(); aIt.Next())
0449 {
0450 if (aMap2->Contains(aIt.Value()))
0451 {
0452 return Standard_True;
0453 }
0454 }
0455
0456 return Standard_False;
0457 }
0458
0459
0460
0461
0462
0463 void Intersection (const NCollection_Map& theLeft,
0464 const NCollection_Map& theRight)
0465 {
0466 if (&theLeft == &theRight)
0467 {
0468 Assign (theLeft);
0469 return;
0470 }
0471
0472 if (this == &theLeft)
0473 {
0474 NCollection_Map aCopy (1, this->myAllocator);
0475 Exchange (aCopy);
0476 Intersection (aCopy, theRight);
0477 return;
0478 }
0479 else if (this == &theRight)
0480 {
0481 NCollection_Map aCopy (1, this->myAllocator);
0482 Exchange (aCopy);
0483 Intersection (theLeft, aCopy);
0484 return;
0485 }
0486
0487 Clear();
0488 if (theLeft.Extent() < theRight.Extent())
0489 {
0490 for (Iterator anIter (theLeft); anIter.More(); anIter.Next())
0491 {
0492 if (theRight.Contains (anIter.Key()))
0493 {
0494 Add (anIter.Key());
0495 }
0496 }
0497 }
0498 else
0499 {
0500 for (Iterator anIter (theRight); anIter.More(); anIter.Next())
0501 {
0502 if (theLeft.Contains (anIter.Key()))
0503 {
0504 Add (anIter.Key());
0505 }
0506 }
0507 }
0508 }
0509
0510
0511
0512
0513
0514 Standard_Boolean Intersect (const NCollection_Map& theOther)
0515 {
0516 if (this == &theOther
0517 || IsEmpty())
0518 {
0519 return Standard_False;
0520 }
0521
0522 const Standard_Integer anOldExtent = Extent();
0523 Intersection (*this, theOther);
0524 return anOldExtent != Extent();
0525 }
0526
0527
0528
0529
0530
0531 void Subtraction (const NCollection_Map& theLeft,
0532 const NCollection_Map& theRight)
0533 {
0534 if (this == &theLeft)
0535 {
0536 Subtract (theRight);
0537 return;
0538 }
0539 else if (this == &theRight)
0540 {
0541 NCollection_Map aCopy (1, this->myAllocator);
0542 Exchange (aCopy);
0543 Subtraction (theLeft, aCopy);
0544 return;
0545 }
0546
0547 Assign (theLeft);
0548 Subtract (theRight);
0549 }
0550
0551
0552
0553
0554
0555
0556 Standard_Boolean Subtract (const NCollection_Map& theOther)
0557 {
0558 if (this == &theOther)
0559 {
0560 if (IsEmpty())
0561 {
0562 return Standard_False;
0563 }
0564
0565 Clear();
0566 return Standard_True;
0567 }
0568
0569 const Standard_Integer anOldExtent = Extent();
0570 for (Iterator anIter (theOther); anIter.More(); anIter.Next())
0571 {
0572 Remove (anIter.Key());
0573 }
0574 return anOldExtent != Extent();
0575 }
0576
0577
0578
0579
0580 void Difference (const NCollection_Map& theLeft,
0581 const NCollection_Map& theRight)
0582 {
0583 if (&theLeft == &theRight)
0584 {
0585 Clear();
0586 return;
0587 }
0588 else if (this == &theLeft)
0589 {
0590 NCollection_Map aCopy (1, this->myAllocator);
0591 Exchange (aCopy);
0592 Difference (aCopy, theRight);
0593 return;
0594 }
0595 else if (this == &theRight)
0596 {
0597 NCollection_Map aCopy (1, this->myAllocator);
0598 Exchange (aCopy);
0599 Difference (theLeft, aCopy);
0600 return;
0601 }
0602
0603 Clear();
0604 for (Iterator anIter (theLeft); anIter.More(); anIter.Next())
0605 {
0606 if (!theRight.Contains (anIter.Key()))
0607 {
0608 Add (anIter.Key());
0609 }
0610 }
0611 for (Iterator anIter (theRight); anIter.More(); anIter.Next())
0612 {
0613 if (!theLeft.Contains (anIter.Key()))
0614 {
0615 Add (anIter.Key());
0616 }
0617 }
0618 }
0619
0620
0621
0622
0623
0624 Standard_Boolean Differ (const NCollection_Map& theOther)
0625 {
0626 if (this == &theOther)
0627 {
0628 if (IsEmpty())
0629 {
0630 return Standard_False;
0631 }
0632 Clear();
0633 return Standard_True;
0634 }
0635
0636 const Standard_Integer anOldExtent = Extent();
0637 Difference (*this, theOther);
0638 return anOldExtent != Extent();
0639 }
0640
0641 protected:
0642
0643
0644
0645
0646
0647
0648 Standard_Boolean lookup(const TheKeyType& theKey, MapNode*& theNode, size_t& theHash) const
0649 {
0650 theHash = HashCode(theKey, NbBuckets());
0651 if (IsEmpty())
0652 return Standard_False;
0653 for (theNode = (MapNode*)myData1[theHash];
0654 theNode; theNode = (MapNode*)theNode->Next())
0655 {
0656 if (IsEqual(theNode->Key(), theKey))
0657 return Standard_True;
0658 }
0659 return Standard_False;
0660 }
0661
0662
0663
0664
0665
0666 Standard_Boolean lookup(const TheKeyType& theKey, MapNode*& theNode) const
0667 {
0668 if (IsEmpty())
0669 return Standard_False;
0670 for (theNode = (MapNode*)myData1[HashCode(theKey, NbBuckets())];
0671 theNode; theNode = (MapNode*)theNode->Next())
0672 {
0673 if (IsEqual(theNode->Key(), theKey))
0674 {
0675 return Standard_True;
0676 }
0677 }
0678 return Standard_False;
0679 }
0680
0681 bool IsEqual(const TheKeyType& theKey1,
0682 const TheKeyType& theKey2) const
0683 {
0684 return myHasher(theKey1, theKey2);
0685 }
0686
0687 size_t HashCode(const TheKeyType& theKey,
0688 const int theUpperBound) const
0689 {
0690 return myHasher(theKey) % theUpperBound + 1;
0691 }
0692 protected:
0693
0694 Hasher myHasher;
0695 };
0696
0697 #endif