File indexing completed on 2026-09-28 09:21:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef NCollection_OrderedDataMap_HeaderFile
0015 #define NCollection_OrderedDataMap_HeaderFile
0016
0017 #include <NCollection_BaseMap.hxx>
0018 #include <NCollection_DefaultHasher.hxx>
0019 #include <NCollection_ItemsView.hxx>
0020 #include <NCollection_StlIterator.hxx>
0021 #include <NCollection_TListNode.hxx>
0022 #include <Standard_NoSuchObject.hxx>
0023 #include <Standard_OutOfRange.hxx>
0024
0025 #include <functional>
0026 #include <optional>
0027 #include <type_traits>
0028 #include <utility>
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
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 template <class TheKeyType, class TheItemType, class Hasher = NCollection_DefaultHasher<TheKeyType>>
0068 class NCollection_OrderedDataMap : public NCollection_BaseMap
0069 {
0070 public:
0071
0072 typedef TheKeyType key_type;
0073
0074 typedef TheItemType value_type;
0075
0076 public:
0077
0078
0079 class OrderedDataMapNode : public NCollection_TListNode<TheItemType>
0080 {
0081 public:
0082
0083 OrderedDataMapNode(const TheKeyType& theKey,
0084 const TheItemType& theItem,
0085 NCollection_ListNode* theNext)
0086 : NCollection_TListNode<TheItemType>(theItem, theNext),
0087 myOrderPrev(nullptr),
0088 myOrderNext(nullptr),
0089 myKey(theKey)
0090 {
0091 }
0092
0093
0094 OrderedDataMapNode(const TheKeyType& theKey,
0095 TheItemType&& theItem,
0096 NCollection_ListNode* theNext)
0097 : NCollection_TListNode<TheItemType>(std::forward<TheItemType>(theItem), theNext),
0098 myOrderPrev(nullptr),
0099 myOrderNext(nullptr),
0100 myKey(theKey)
0101 {
0102 }
0103
0104
0105 OrderedDataMapNode(TheKeyType&& theKey,
0106 const TheItemType& theItem,
0107 NCollection_ListNode* theNext)
0108 : NCollection_TListNode<TheItemType>(theItem, theNext),
0109 myOrderPrev(nullptr),
0110 myOrderNext(nullptr),
0111 myKey(std::forward<TheKeyType>(theKey))
0112 {
0113 }
0114
0115
0116 OrderedDataMapNode(TheKeyType&& theKey, TheItemType&& theItem, NCollection_ListNode* theNext)
0117 : NCollection_TListNode<TheItemType>(std::forward<TheItemType>(theItem), theNext),
0118 myOrderPrev(nullptr),
0119 myOrderNext(nullptr),
0120 myKey(std::forward<TheKeyType>(theKey))
0121 {
0122 }
0123
0124
0125 template <typename K, typename... Args>
0126 OrderedDataMapNode(K&& theKey,
0127 std::in_place_t,
0128 NCollection_ListNode* theNext,
0129 Args&&... theArgs)
0130 : NCollection_TListNode<TheItemType>(std::in_place,
0131 theNext,
0132 std::forward<Args>(theArgs)...),
0133 myOrderPrev(nullptr),
0134 myOrderNext(nullptr),
0135 myKey(std::forward<K>(theKey))
0136 {
0137 }
0138
0139
0140 const TheKeyType& Key() const noexcept { return myKey; }
0141
0142
0143 static void delNode(NCollection_ListNode* theNode,
0144 occ::handle<NCollection_BaseAllocator>& theAl) noexcept
0145 {
0146 ((OrderedDataMapNode*)theNode)->~OrderedDataMapNode();
0147 theAl->Free(theNode);
0148 }
0149
0150 OrderedDataMapNode* myOrderPrev;
0151 OrderedDataMapNode* myOrderNext;
0152
0153 private:
0154 TheKeyType myKey;
0155 };
0156
0157 public:
0158
0159
0160 class Iterator
0161 {
0162 public:
0163
0164 Iterator() noexcept
0165 : myNode(nullptr)
0166 {
0167 }
0168
0169
0170 Iterator(const NCollection_OrderedDataMap& theMap) noexcept
0171 : myNode(theMap.myFirst)
0172 {
0173 }
0174
0175
0176 bool More() const noexcept { return myNode != nullptr; }
0177
0178
0179 void Next() noexcept
0180 {
0181 if (myNode)
0182 myNode = myNode->myOrderNext;
0183 }
0184
0185
0186 const TheItemType& Value() const
0187 {
0188 Standard_NoSuchObject_Raise_if(!More(), "NCollection_OrderedDataMap::Iterator::Value");
0189 return myNode->Value();
0190 }
0191
0192
0193 TheItemType& ChangeValue() const
0194 {
0195 Standard_NoSuchObject_Raise_if(!More(), "NCollection_OrderedDataMap::Iterator::ChangeValue");
0196 return myNode->ChangeValue();
0197 }
0198
0199
0200 const TheKeyType& Key() const
0201 {
0202 Standard_NoSuchObject_Raise_if(!More(), "NCollection_OrderedDataMap::Iterator::Key");
0203 return myNode->Key();
0204 }
0205
0206
0207 bool IsEqual(const Iterator& theOther) const noexcept { return myNode == theOther.myNode; }
0208
0209
0210 void Initialize(const NCollection_OrderedDataMap& theMap) noexcept { myNode = theMap.myFirst; }
0211
0212
0213 void Reset() noexcept { myNode = nullptr; }
0214
0215 private:
0216 OrderedDataMapNode* myNode;
0217 };
0218
0219
0220 typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, false> iterator;
0221
0222
0223 typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, true>
0224 const_iterator;
0225
0226
0227 iterator begin() const noexcept { return Iterator(*this); }
0228
0229
0230 iterator end() const noexcept { return Iterator(); }
0231
0232
0233 const_iterator cbegin() const noexcept { return Iterator(*this); }
0234
0235
0236 const_iterator cend() const noexcept { return Iterator(); }
0237
0238 public:
0239
0240
0241
0242
0243 using KeyValueRef = NCollection_ItemsView::KeyValueRef<TheKeyType, TheItemType, false>;
0244
0245
0246 using ConstKeyValueRef = NCollection_ItemsView::KeyValueRef<TheKeyType, TheItemType, true>;
0247
0248 private:
0249
0250 struct ItemsExtractor
0251 {
0252 static KeyValueRef Extract(const Iterator& theIter)
0253 {
0254 return {theIter.Key(), theIter.ChangeValue()};
0255 }
0256 };
0257
0258
0259 struct ConstItemsExtractor
0260 {
0261 static ConstKeyValueRef Extract(const Iterator& theIter)
0262 {
0263 return {theIter.Key(), theIter.Value()};
0264 }
0265 };
0266
0267 public:
0268
0269 using ItemsView =
0270 NCollection_ItemsView::View<NCollection_OrderedDataMap, KeyValueRef, ItemsExtractor, false>;
0271
0272
0273 using ConstItemsView = NCollection_ItemsView::
0274 View<NCollection_OrderedDataMap, ConstKeyValueRef, ConstItemsExtractor, true>;
0275
0276
0277
0278 ItemsView Items() { return ItemsView(*this); }
0279
0280
0281
0282 ConstItemsView Items() const { return ConstItemsView(*this); }
0283
0284 public:
0285
0286
0287
0288 NCollection_OrderedDataMap()
0289 : NCollection_BaseMap(1, true, occ::handle<NCollection_BaseAllocator>()),
0290 myFirst(nullptr),
0291 myLast(nullptr)
0292 {
0293 }
0294
0295
0296 explicit NCollection_OrderedDataMap(
0297 const size_t theNbBuckets,
0298 const occ::handle<NCollection_BaseAllocator>& theAllocator = nullptr)
0299 : NCollection_BaseMap(theNbBuckets, true, theAllocator),
0300 myFirst(nullptr),
0301 myLast(nullptr)
0302 {
0303 }
0304
0305
0306 explicit NCollection_OrderedDataMap(
0307 const int theNbBuckets,
0308 const occ::handle<NCollection_BaseAllocator>& theAllocator = nullptr)
0309 : NCollection_OrderedDataMap(NCollection_BaseMap::NbBucketsFromInt(theNbBuckets),
0310 theAllocator)
0311 {
0312 }
0313
0314
0315
0316
0317
0318 explicit NCollection_OrderedDataMap(
0319 const Hasher& theHasher,
0320 const size_t theNbBuckets = 1,
0321 const occ::handle<NCollection_BaseAllocator>& theAllocator = nullptr)
0322 : NCollection_BaseMap(theNbBuckets, true, theAllocator),
0323 myHasher(theHasher),
0324 myFirst(nullptr),
0325 myLast(nullptr)
0326 {
0327 }
0328
0329
0330 explicit NCollection_OrderedDataMap(
0331 const Hasher& theHasher,
0332 const int theNbBuckets,
0333 const occ::handle<NCollection_BaseAllocator>& theAllocator = nullptr)
0334 : NCollection_OrderedDataMap(theHasher,
0335 NCollection_BaseMap::NbBucketsFromInt(theNbBuckets),
0336 theAllocator)
0337 {
0338 }
0339
0340
0341
0342
0343
0344 explicit NCollection_OrderedDataMap(
0345 Hasher&& theHasher,
0346 const size_t theNbBuckets = 1,
0347 const occ::handle<NCollection_BaseAllocator>& theAllocator = nullptr)
0348 : NCollection_BaseMap(theNbBuckets, true, theAllocator),
0349 myHasher(std::move(theHasher)),
0350 myFirst(nullptr),
0351 myLast(nullptr)
0352 {
0353 }
0354
0355
0356 explicit NCollection_OrderedDataMap(
0357 Hasher&& theHasher,
0358 const int theNbBuckets,
0359 const occ::handle<NCollection_BaseAllocator>& theAllocator = nullptr)
0360 : NCollection_OrderedDataMap(std::move(theHasher),
0361 NCollection_BaseMap::NbBucketsFromInt(theNbBuckets),
0362 theAllocator)
0363 {
0364 }
0365
0366
0367 NCollection_OrderedDataMap(const NCollection_OrderedDataMap& theOther)
0368 : NCollection_BaseMap(theOther.NbBuckets(), true, theOther.myAllocator),
0369 myHasher(theOther.myHasher),
0370 myFirst(nullptr),
0371 myLast(nullptr)
0372 {
0373 const int anExt = theOther.Extent();
0374 if (anExt <= 0)
0375 return;
0376 ReSize(anExt - 1);
0377 for (Iterator anIter(theOther); anIter.More(); anIter.Next())
0378 Bind(anIter.Key(), anIter.Value());
0379 }
0380
0381
0382 NCollection_OrderedDataMap(NCollection_OrderedDataMap&& theOther) noexcept
0383 : NCollection_BaseMap(std::forward<NCollection_BaseMap>(theOther)),
0384 myHasher(std::move(theOther.myHasher)),
0385 myFirst(theOther.myFirst),
0386 myLast(theOther.myLast)
0387 {
0388 theOther.myFirst = nullptr;
0389 theOther.myLast = nullptr;
0390 }
0391
0392
0393
0394 void Exchange(NCollection_OrderedDataMap& theOther) noexcept
0395 {
0396 this->exchangeMapsData(theOther);
0397 std::swap(myFirst, theOther.myFirst);
0398 std::swap(myLast, theOther.myLast);
0399 std::swap(myHasher, theOther.myHasher);
0400 }
0401
0402
0403 const Hasher& GetHasher() const noexcept { return myHasher; }
0404
0405
0406
0407 NCollection_OrderedDataMap& Assign(const NCollection_OrderedDataMap& theOther)
0408 {
0409 if (this == &theOther)
0410 return *this;
0411
0412 Clear();
0413 int anExt = theOther.Extent();
0414 if (anExt)
0415 {
0416 ReSize(anExt - 1);
0417 Iterator anIter(theOther);
0418 for (; anIter.More(); anIter.Next())
0419 Bind(anIter.Key(), anIter.Value());
0420 }
0421 return *this;
0422 }
0423
0424
0425 NCollection_OrderedDataMap& operator=(const NCollection_OrderedDataMap& theOther)
0426 {
0427 return Assign(theOther);
0428 }
0429
0430
0431 NCollection_OrderedDataMap& operator=(NCollection_OrderedDataMap&& theOther) noexcept
0432 {
0433 if (this == &theOther)
0434 return *this;
0435 exchangeMapsData(theOther);
0436 std::swap(myFirst, theOther.myFirst);
0437 std::swap(myLast, theOther.myLast);
0438 return *this;
0439 }
0440
0441
0442 void ReSize(const size_t N)
0443 {
0444 NCollection_ListNode** newdata = nullptr;
0445 NCollection_ListNode** dummy = nullptr;
0446 size_t newBuck;
0447 if (BeginResize(N, newBuck, newdata, dummy))
0448 {
0449 if (myData1)
0450 {
0451 OrderedDataMapNode** olddata = (OrderedDataMapNode**)myData1;
0452 OrderedDataMapNode * p, *q;
0453 for (size_t i = 0; i <= NbBuckets(); ++i)
0454 {
0455 if (olddata[i])
0456 {
0457 p = olddata[i];
0458 while (p)
0459 {
0460 const size_t k = HashCode(p->Key(), newBuck);
0461 q = (OrderedDataMapNode*)p->Next();
0462 p->Next() = newdata[k];
0463 newdata[k] = p;
0464 p = q;
0465 }
0466 }
0467 }
0468 }
0469 EndResize(N, newBuck, newdata, dummy);
0470 }
0471 }
0472
0473 void ReSize(const int N)
0474 {
0475 Standard_OutOfRange_Raise_if(N < 0, "NCollection_OrderedDataMap::ReSize: negative size");
0476 ReSize(static_cast<size_t>(N));
0477 }
0478
0479
0480
0481
0482
0483 bool Bind(const TheKeyType& theKey, const TheItemType& theItem)
0484 {
0485 return emplaceImpl(theKey, std::false_type{}, std::false_type{}, theItem);
0486 }
0487
0488
0489 bool Bind(TheKeyType&& theKey, const TheItemType& theItem)
0490 {
0491 return emplaceImpl(std::move(theKey), std::false_type{}, std::false_type{}, theItem);
0492 }
0493
0494
0495 bool Bind(const TheKeyType& theKey, TheItemType&& theItem)
0496 {
0497 return emplaceImpl(theKey, std::false_type{}, std::false_type{}, std::move(theItem));
0498 }
0499
0500
0501 bool Bind(TheKeyType&& theKey, TheItemType&& theItem)
0502 {
0503 return emplaceImpl(std::move(theKey), std::false_type{}, std::false_type{}, std::move(theItem));
0504 }
0505
0506
0507
0508 TheItemType* Bound(const TheKeyType& theKey, const TheItemType& theItem)
0509 {
0510 return &emplaceImpl(theKey, std::false_type{}, std::true_type{}, theItem);
0511 }
0512
0513
0514 TheItemType* Bound(TheKeyType&& theKey, const TheItemType& theItem)
0515 {
0516 return &emplaceImpl(std::move(theKey), std::false_type{}, std::true_type{}, theItem);
0517 }
0518
0519
0520 TheItemType* Bound(const TheKeyType& theKey, TheItemType&& theItem)
0521 {
0522 return &emplaceImpl(theKey, std::false_type{}, std::true_type{}, std::move(theItem));
0523 }
0524
0525
0526 TheItemType* Bound(TheKeyType&& theKey, TheItemType&& theItem)
0527 {
0528 return &emplaceImpl(std::move(theKey), std::false_type{}, std::true_type{}, std::move(theItem));
0529 }
0530
0531
0532
0533 bool TryBind(const TheKeyType& theKey, const TheItemType& theItem)
0534 {
0535 return emplaceImpl(theKey, std::true_type{}, std::false_type{}, theItem);
0536 }
0537
0538
0539 bool TryBind(TheKeyType&& theKey, const TheItemType& theItem)
0540 {
0541 return emplaceImpl(std::move(theKey), std::true_type{}, std::false_type{}, theItem);
0542 }
0543
0544
0545 bool TryBind(const TheKeyType& theKey, TheItemType&& theItem)
0546 {
0547 return emplaceImpl(theKey, std::true_type{}, std::false_type{}, std::move(theItem));
0548 }
0549
0550
0551 bool TryBind(TheKeyType&& theKey, TheItemType&& theItem)
0552 {
0553 return emplaceImpl(std::move(theKey), std::true_type{}, std::false_type{}, std::move(theItem));
0554 }
0555
0556
0557
0558 TheItemType& TryBound(const TheKeyType& theKey, const TheItemType& theItem)
0559 {
0560 return emplaceImpl(theKey, std::true_type{}, std::true_type{}, theItem);
0561 }
0562
0563
0564 TheItemType& TryBound(TheKeyType&& theKey, const TheItemType& theItem)
0565 {
0566 return emplaceImpl(std::move(theKey), std::true_type{}, std::true_type{}, theItem);
0567 }
0568
0569
0570 TheItemType& TryBound(const TheKeyType& theKey, TheItemType&& theItem)
0571 {
0572 return emplaceImpl(theKey, std::true_type{}, std::true_type{}, std::move(theItem));
0573 }
0574
0575
0576 TheItemType& TryBound(TheKeyType&& theKey, TheItemType&& theItem)
0577 {
0578 return emplaceImpl(std::move(theKey), std::true_type{}, std::true_type{}, std::move(theItem));
0579 }
0580
0581
0582
0583
0584
0585
0586 template <typename K, typename... Args>
0587 bool Emplace(K&& theKey, Args&&... theArgs)
0588 {
0589 return emplaceImpl(std::forward<K>(theKey),
0590 std::false_type{},
0591 std::false_type{},
0592 std::forward<Args>(theArgs)...);
0593 }
0594
0595
0596
0597
0598
0599 template <typename K, typename... Args>
0600 TheItemType& Emplaced(K&& theKey, Args&&... theArgs)
0601 {
0602 return emplaceImpl(std::forward<K>(theKey),
0603 std::false_type{},
0604 std::true_type{},
0605 std::forward<Args>(theArgs)...);
0606 }
0607
0608
0609
0610
0611
0612 template <typename K, typename... Args>
0613 bool TryEmplace(K&& theKey, Args&&... theArgs)
0614 {
0615 return emplaceImpl(std::forward<K>(theKey),
0616 std::true_type{},
0617 std::false_type{},
0618 std::forward<Args>(theArgs)...);
0619 }
0620
0621
0622
0623
0624
0625 template <typename K, typename... Args>
0626 TheItemType& TryEmplaced(K&& theKey, Args&&... theArgs)
0627 {
0628 return emplaceImpl(std::forward<K>(theKey),
0629 std::true_type{},
0630 std::true_type{},
0631 std::forward<Args>(theArgs)...);
0632 }
0633
0634
0635 bool IsBound(const TheKeyType& theKey) const
0636 {
0637 OrderedDataMapNode* p;
0638 return lookup(theKey, p);
0639 }
0640
0641
0642
0643 std::optional<
0644 std::pair<std::reference_wrapper<const TheKeyType>, std::reference_wrapper<const TheItemType>>>
0645 Contained(const TheKeyType& theKey) const
0646 {
0647 OrderedDataMapNode* p = nullptr;
0648 if (!lookup(theKey, p))
0649 return std::nullopt;
0650 return std::make_pair(std::cref(p->Key()), std::cref(p->Value()));
0651 }
0652
0653
0654
0655 std::optional<
0656 std::pair<std::reference_wrapper<const TheKeyType>, std::reference_wrapper<TheItemType>>>
0657 Contained(const TheKeyType& theKey)
0658 {
0659 OrderedDataMapNode* p = nullptr;
0660 if (!lookup(theKey, p))
0661 return std::nullopt;
0662 return std::make_pair(std::cref(p->Key()), std::ref(p->ChangeValue()));
0663 }
0664
0665
0666 bool UnBind(const TheKeyType& theKey)
0667 {
0668 if (IsEmpty())
0669 return false;
0670 OrderedDataMapNode** data = (OrderedDataMapNode**)myData1;
0671 const size_t k = HashCode(theKey, NbBuckets());
0672 OrderedDataMapNode* p = data[k];
0673 OrderedDataMapNode* q = nullptr;
0674 while (p)
0675 {
0676 if (IsEqual(p->Key(), theKey))
0677 {
0678 Decrement();
0679 if (q)
0680 q->Next() = p->Next();
0681 else
0682 data[k] = (OrderedDataMapNode*)p->Next();
0683 unlinkFromList(p);
0684 p->~OrderedDataMapNode();
0685 this->myAllocator->Free(p);
0686 return true;
0687 }
0688 q = p;
0689 p = (OrderedDataMapNode*)p->Next();
0690 }
0691 return false;
0692 }
0693
0694
0695
0696 const TheItemType* Seek(const TheKeyType& theKey) const
0697 {
0698 OrderedDataMapNode* p = nullptr;
0699 if (!lookup(theKey, p))
0700 return nullptr;
0701 return &p->Value();
0702 }
0703
0704
0705 const TheItemType& Find(const TheKeyType& theKey) const
0706 {
0707 OrderedDataMapNode* p = nullptr;
0708 if (!lookup(theKey, p))
0709 throw Standard_NoSuchObject("NCollection_OrderedDataMap::Find");
0710 return p->Value();
0711 }
0712
0713
0714
0715 bool Find(const TheKeyType& theKey, TheItemType& theValue) const
0716 {
0717 OrderedDataMapNode* p = nullptr;
0718 if (!lookup(theKey, p))
0719 return false;
0720
0721 theValue = p->Value();
0722 return true;
0723 }
0724
0725
0726 const TheItemType& operator()(const TheKeyType& theKey) const { return Find(theKey); }
0727
0728
0729
0730 TheItemType* ChangeSeek(const TheKeyType& theKey)
0731 {
0732 OrderedDataMapNode* p = nullptr;
0733 if (!lookup(theKey, p))
0734 return nullptr;
0735 return &p->ChangeValue();
0736 }
0737
0738
0739 TheItemType& ChangeFind(const TheKeyType& theKey)
0740 {
0741 OrderedDataMapNode* p = nullptr;
0742 if (!lookup(theKey, p))
0743 throw Standard_NoSuchObject("NCollection_OrderedDataMap::Find");
0744 return p->ChangeValue();
0745 }
0746
0747
0748 TheItemType& operator()(const TheKeyType& theKey) { return ChangeFind(theKey); }
0749
0750
0751
0752 void Clear(const bool doReleaseMemory = false)
0753 {
0754 Destroy(OrderedDataMapNode::delNode, doReleaseMemory);
0755 myFirst = nullptr;
0756 myLast = nullptr;
0757 }
0758
0759
0760 void Clear(const occ::handle<NCollection_BaseAllocator>& theAllocator)
0761 {
0762 Clear(theAllocator != this->myAllocator);
0763 this->myAllocator =
0764 (!theAllocator.IsNull() ? theAllocator : NCollection_BaseAllocator::CommonBaseAllocator());
0765 }
0766
0767
0768 ~NCollection_OrderedDataMap() override { Clear(true); }
0769
0770
0771
0772 const TheKeyType& First() const
0773 {
0774 if (IsEmpty())
0775 throw Standard_NoSuchObject("NCollection_OrderedDataMap::First");
0776 return myFirst->Key();
0777 }
0778
0779
0780
0781 const TheKeyType& Last() const
0782 {
0783 if (IsEmpty())
0784 throw Standard_NoSuchObject("NCollection_OrderedDataMap::Last");
0785 return myLast->Key();
0786 }
0787
0788
0789
0790 const TheItemType& FirstValue() const
0791 {
0792 if (IsEmpty())
0793 throw Standard_NoSuchObject("NCollection_OrderedDataMap::FirstValue");
0794 return myFirst->Value();
0795 }
0796
0797
0798
0799 const TheItemType& LastValue() const
0800 {
0801 if (IsEmpty())
0802 throw Standard_NoSuchObject("NCollection_OrderedDataMap::LastValue");
0803 return myLast->Value();
0804 }
0805
0806
0807
0808 TheItemType& ChangeFirstValue()
0809 {
0810 if (IsEmpty())
0811 throw Standard_NoSuchObject("NCollection_OrderedDataMap::ChangeFirstValue");
0812 return myFirst->ChangeValue();
0813 }
0814
0815
0816
0817 TheItemType& ChangeLastValue()
0818 {
0819 if (IsEmpty())
0820 throw Standard_NoSuchObject("NCollection_OrderedDataMap::ChangeLastValue");
0821 return myLast->ChangeValue();
0822 }
0823
0824 protected:
0825
0826
0827
0828
0829 bool lookup(const TheKeyType& theKey, OrderedDataMapNode*& theNode) const
0830 {
0831 if (IsEmpty())
0832 return false;
0833 for (theNode = (OrderedDataMapNode*)myData1[HashCode(theKey, NbBuckets())]; theNode;
0834 theNode = (OrderedDataMapNode*)theNode->Next())
0835 {
0836 if (IsEqual(theNode->Key(), theKey))
0837 return true;
0838 }
0839 return false;
0840 }
0841
0842
0843
0844
0845
0846
0847 bool lookup(const TheKeyType& theKey, OrderedDataMapNode*& theNode, size_t& theHash) const
0848 {
0849 theHash = HashCode(theKey, NbBuckets());
0850 if (IsEmpty())
0851 return false;
0852 for (theNode = (OrderedDataMapNode*)myData1[theHash]; theNode;
0853 theNode = (OrderedDataMapNode*)theNode->Next())
0854 {
0855 if (IsEqual(theNode->Key(), theKey))
0856 {
0857 return true;
0858 }
0859 }
0860 return false;
0861 }
0862
0863 bool IsEqual(const TheKeyType& theKey1, const TheKeyType& theKey2) const
0864 {
0865 return myHasher(theKey1, theKey2);
0866 }
0867
0868 size_t HashCode(const TheKeyType& theKey, const size_t theUpperBound) const
0869 {
0870 return myHasher(theKey) % theUpperBound + 1;
0871 }
0872
0873
0874 void appendToList(OrderedDataMapNode* theNode)
0875 {
0876 theNode->myOrderPrev = myLast;
0877 theNode->myOrderNext = nullptr;
0878 if (myLast)
0879 myLast->myOrderNext = theNode;
0880 else
0881 myFirst = theNode;
0882 myLast = theNode;
0883 }
0884
0885
0886 void unlinkFromList(OrderedDataMapNode* theNode)
0887 {
0888 OrderedDataMapNode* aPrev = theNode->myOrderPrev;
0889 OrderedDataMapNode* aNext = theNode->myOrderNext;
0890 if (aPrev)
0891 aPrev->myOrderNext = aNext;
0892 else
0893 myFirst = aNext;
0894 if (aNext)
0895 aNext->myOrderPrev = aPrev;
0896 else
0897 myLast = aPrev;
0898 }
0899
0900
0901
0902
0903
0904
0905
0906
0907 template <typename K, bool IsTry, bool ReturnRef, typename... Args>
0908 auto emplaceImpl(K&& theKey,
0909 std::bool_constant<IsTry>,
0910 std::bool_constant<ReturnRef>,
0911 Args&&... theArgs) -> std::conditional_t<ReturnRef, TheItemType&, bool>
0912 {
0913 if (Resizable())
0914 ReSize(Extent());
0915 size_t aHash;
0916 OrderedDataMapNode* aNode;
0917 if (lookup(theKey, aNode, aHash))
0918 {
0919 if constexpr (!IsTry)
0920 {
0921 aNode->ChangeValue() = TheItemType(std::forward<Args>(theArgs)...);
0922 }
0923 if constexpr (ReturnRef)
0924 return aNode->ChangeValue();
0925 else
0926 return false;
0927 }
0928 OrderedDataMapNode** data = (OrderedDataMapNode**)myData1;
0929 data[aHash] = new (this->myAllocator) OrderedDataMapNode(std::forward<K>(theKey),
0930 std::in_place,
0931 data[aHash],
0932 std::forward<Args>(theArgs)...);
0933 appendToList(data[aHash]);
0934 Increment();
0935 if constexpr (ReturnRef)
0936 return data[aHash]->ChangeValue();
0937 else
0938 return true;
0939 }
0940
0941 private:
0942 Hasher myHasher;
0943 OrderedDataMapNode* myFirst;
0944 OrderedDataMapNode* myLast;
0945 };
0946
0947 #endif