File indexing completed on 2024-11-15 09:47:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef NCollection_DataMap_HeaderFile
0017 #define NCollection_DataMap_HeaderFile
0018
0019 #include <NCollection_BaseMap.hxx>
0020 #include <NCollection_TListNode.hxx>
0021 #include <NCollection_StlIterator.hxx>
0022 #include <NCollection_DefaultHasher.hxx>
0023
0024 #include <Standard_TypeMismatch.hxx>
0025 #include <Standard_NoSuchObject.hxx>
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 template < class TheKeyType,
0046 class TheItemType,
0047 class Hasher = NCollection_DefaultHasher<TheKeyType> >
0048 class NCollection_DataMap : public NCollection_BaseMap
0049 {
0050 public:
0051
0052 typedef TheKeyType key_type;
0053
0054 typedef TheItemType value_type;
0055
0056 public:
0057
0058 class DataMapNode : public NCollection_TListNode<TheItemType>
0059 {
0060 public:
0061
0062 DataMapNode (const TheKeyType& theKey,
0063 const TheItemType& theItem,
0064 NCollection_ListNode* theNext) :
0065 NCollection_TListNode<TheItemType> (theItem, theNext),
0066 myKey(theKey)
0067 {}
0068
0069
0070 const TheKeyType& Key (void) const
0071 { return myKey; }
0072
0073
0074 static void delNode (NCollection_ListNode * theNode,
0075 Handle(NCollection_BaseAllocator)& theAl)
0076 {
0077 ((DataMapNode *) theNode)->~DataMapNode();
0078 theAl->Free(theNode);
0079 }
0080
0081 private:
0082 TheKeyType myKey;
0083 };
0084
0085 public:
0086
0087 class Iterator : public NCollection_BaseMap::Iterator
0088 {
0089 public:
0090
0091 Iterator (void) :
0092 NCollection_BaseMap::Iterator() {}
0093
0094 Iterator (const NCollection_DataMap& theMap) :
0095 NCollection_BaseMap::Iterator(theMap) {}
0096
0097 Standard_Boolean More(void) const
0098 { return PMore(); }
0099
0100 void Next(void)
0101 { PNext(); }
0102
0103 const TheItemType& Value(void) const
0104 {
0105 Standard_NoSuchObject_Raise_if(!More(), "NCollection_DataMap::Iterator::Value");
0106 return ((DataMapNode *) myNode)->Value();
0107 }
0108
0109 TheItemType& ChangeValue(void) const
0110 {
0111 Standard_NoSuchObject_Raise_if(!More(), "NCollection_DataMap::Iterator::ChangeValue");
0112 return ((DataMapNode *) myNode)->ChangeValue();
0113 }
0114
0115 const TheKeyType& Key (void) const
0116 {
0117 Standard_NoSuchObject_Raise_if(!More(), "NCollection_DataMap::Iterator::Key");
0118 return ((DataMapNode *) myNode)->Key();
0119 }
0120 };
0121
0122
0123 typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, false> iterator;
0124
0125
0126 typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, true> const_iterator;
0127
0128
0129 iterator begin() const { return Iterator (*this); }
0130
0131
0132 iterator end() const { return Iterator(); }
0133
0134
0135 const_iterator cbegin() const { return Iterator (*this); }
0136
0137
0138 const_iterator cend() const { return Iterator(); }
0139
0140 public:
0141
0142
0143
0144 NCollection_DataMap() : NCollection_BaseMap (1, Standard_True, Handle(NCollection_BaseAllocator)()) {}
0145
0146
0147 explicit NCollection_DataMap (const Standard_Integer theNbBuckets,
0148 const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
0149 : NCollection_BaseMap (theNbBuckets, Standard_True, theAllocator) {}
0150
0151
0152 NCollection_DataMap (const NCollection_DataMap& theOther)
0153 : NCollection_BaseMap (theOther.NbBuckets(), Standard_True, theOther.myAllocator)
0154 { *this = theOther; }
0155
0156
0157
0158 void Exchange (NCollection_DataMap& theOther)
0159 {
0160 this->exchangeMapsData (theOther);
0161 }
0162
0163
0164
0165 NCollection_DataMap& Assign (const NCollection_DataMap& theOther)
0166 {
0167 if (this == &theOther)
0168 return *this;
0169
0170 Clear();
0171 Standard_Integer anExt = theOther.Extent();
0172 if (anExt)
0173 {
0174 ReSize (anExt-1);
0175 Iterator anIter(theOther);
0176 for (; anIter.More(); anIter.Next())
0177 Bind (anIter.Key(), anIter.Value());
0178 }
0179 return *this;
0180 }
0181
0182
0183 NCollection_DataMap& operator= (const NCollection_DataMap& theOther)
0184 {
0185 return Assign (theOther);
0186 }
0187
0188
0189 void ReSize (const Standard_Integer N)
0190 {
0191 NCollection_ListNode** newdata = NULL;
0192 NCollection_ListNode** dummy = NULL;
0193 Standard_Integer newBuck;
0194 if (BeginResize (N, newBuck, newdata, dummy))
0195 {
0196 if (myData1)
0197 {
0198 DataMapNode** olddata = (DataMapNode**) myData1;
0199 DataMapNode *p, *q;
0200 Standard_Integer i,k;
0201 for (i = 0; i <= NbBuckets(); i++)
0202 {
0203 if (olddata[i])
0204 {
0205 p = olddata[i];
0206 while (p)
0207 {
0208 k = Hasher::HashCode(p->Key(),newBuck);
0209 q = (DataMapNode*) p->Next();
0210 p->Next() = newdata[k];
0211 newdata[k] = p;
0212 p = q;
0213 }
0214 }
0215 }
0216 }
0217 EndResize (N, newBuck, newdata, dummy);
0218 }
0219 }
0220
0221
0222
0223
0224
0225 Standard_Boolean Bind (const TheKeyType& theKey, const TheItemType& theItem)
0226 {
0227 if (Resizable())
0228 ReSize(Extent());
0229 DataMapNode** data = (DataMapNode**)myData1;
0230 Standard_Integer k = Hasher::HashCode (theKey, NbBuckets());
0231 DataMapNode* p = data[k];
0232 while (p)
0233 {
0234 if (Hasher::IsEqual(p->Key(), theKey))
0235 {
0236 p->ChangeValue() = theItem;
0237 return Standard_False;
0238 }
0239 p = (DataMapNode *) p->Next();
0240 }
0241 data[k] = new (this->myAllocator) DataMapNode (theKey, theItem, data[k]);
0242 Increment();
0243 return Standard_True;
0244 }
0245
0246
0247 TheItemType* Bound (const TheKeyType& theKey, const TheItemType& theItem)
0248 {
0249 if (Resizable())
0250 ReSize(Extent());
0251 DataMapNode** data = (DataMapNode**)myData1;
0252 Standard_Integer k = Hasher::HashCode (theKey, NbBuckets());
0253 DataMapNode* p = data[k];
0254 while (p)
0255 {
0256 if (Hasher::IsEqual(p->Key(), theKey))
0257 {
0258 p->ChangeValue() = theItem;
0259 return &p->ChangeValue();
0260 }
0261 p = (DataMapNode*)p->Next();
0262 }
0263 data[k] = new (this->myAllocator) DataMapNode (theKey, theItem, data[k]);
0264 Increment();
0265 return &data[k]->ChangeValue();
0266 }
0267
0268
0269 Standard_Boolean IsBound(const TheKeyType& theKey) const
0270 {
0271 DataMapNode* p;
0272 return lookup(theKey, p);
0273 }
0274
0275
0276 Standard_Boolean UnBind(const TheKeyType& theKey)
0277 {
0278 if (IsEmpty())
0279 return Standard_False;
0280 DataMapNode** data = (DataMapNode**) myData1;
0281 Standard_Integer k = Hasher::HashCode(theKey,NbBuckets());
0282 DataMapNode* p = data[k];
0283 DataMapNode* q = NULL;
0284 while (p)
0285 {
0286 if (Hasher::IsEqual(p->Key(), theKey))
0287 {
0288 Decrement();
0289 if (q)
0290 q->Next() = p->Next();
0291 else
0292 data[k] = (DataMapNode*) p->Next();
0293 p->~DataMapNode();
0294 this->myAllocator->Free(p);
0295 return Standard_True;
0296 }
0297 q = p;
0298 p = (DataMapNode*) p->Next();
0299 }
0300 return Standard_False;
0301 }
0302
0303
0304
0305 const TheItemType* Seek(const TheKeyType& theKey) const
0306 {
0307 DataMapNode* p = 0;
0308 if (!lookup(theKey, p))
0309 return 0L;
0310 return &p->Value();
0311 }
0312
0313
0314 const TheItemType& Find(const TheKeyType& theKey) const
0315 {
0316 DataMapNode* p = 0;
0317 if (!lookup(theKey, p))
0318 throw Standard_NoSuchObject("NCollection_DataMap::Find");
0319 return p->Value();
0320 }
0321
0322
0323
0324 Standard_Boolean Find (const TheKeyType& theKey,
0325 TheItemType& theValue) const
0326 {
0327 DataMapNode* p = 0;
0328 if (!lookup(theKey, p))
0329 return Standard_False;
0330
0331 theValue = p->Value();
0332 return Standard_True;
0333 }
0334
0335
0336 const TheItemType& operator() (const TheKeyType& theKey) const
0337 { return Find(theKey); }
0338
0339
0340
0341 TheItemType* ChangeSeek(const TheKeyType& theKey)
0342 {
0343 DataMapNode* p = 0;
0344 if (!lookup(theKey, p))
0345 return 0L;
0346 return &p->ChangeValue();
0347 }
0348
0349
0350 TheItemType& ChangeFind (const TheKeyType& theKey)
0351 {
0352 DataMapNode* p = 0;
0353 if (!lookup(theKey, p))
0354 throw Standard_NoSuchObject("NCollection_DataMap::Find");
0355 return p->ChangeValue();
0356 }
0357
0358
0359 TheItemType& operator() (const TheKeyType& theKey)
0360 { return ChangeFind(theKey); }
0361
0362
0363
0364 void Clear(const Standard_Boolean doReleaseMemory = Standard_True)
0365 { Destroy (DataMapNode::delNode, doReleaseMemory); }
0366
0367
0368 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator)
0369 {
0370 Clear();
0371 this->myAllocator = ( ! theAllocator.IsNull() ? theAllocator :
0372 NCollection_BaseAllocator::CommonBaseAllocator() );
0373 }
0374
0375
0376 virtual ~NCollection_DataMap (void)
0377 { Clear(); }
0378
0379
0380 Standard_Integer Size(void) const
0381 { return Extent(); }
0382
0383
0384 protected:
0385
0386
0387
0388
0389 Standard_Boolean lookup(const TheKeyType& theKey,DataMapNode*& thepNode) const
0390 {
0391 if (IsEmpty())
0392 return Standard_False;
0393 for (thepNode = (DataMapNode*)myData1[Hasher::HashCode(theKey, NbBuckets())];
0394 thepNode; thepNode = (DataMapNode*)thepNode->Next())
0395 {
0396 if (Hasher::IsEqual(thepNode->Key(), theKey))
0397 return Standard_True;
0398 }
0399 return Standard_False;
0400 }
0401
0402 };
0403
0404 #endif
0405