Integration of OCCT 6.5.0 from SVN
[occt.git] / src / TCollection / TCollection_DoubleMap.gxx
1 // Lastly modified by :
2 // +---------------------------------------------------------------------------+
3 // !       szy ! Modified Assign method                  ! 7-05-2003! 3.0-00-3!
4 // +---------------------------------------------------------------------------+
5 // File:        TCollection_DoubleMap.gxx
6 // Created:     Fri Jan  8 18:15:52 1993
7 // Author:      Remi LEQUETTE
8 //              <rle@phylox>
9
10
11 #include <Standard_DomainError.hxx>
12 #include <Standard_MultiplyDefined.hxx>
13 #include <Standard_NoSuchObject.hxx>
14
15
16 //=======================================================================
17 //function : TCollection_DoubleMap
18 //purpose  : 
19 //=======================================================================
20
21 TCollection_DoubleMap::TCollection_DoubleMap(const Standard_Integer NbBuckets):
22        TCollection_BasicMap(NbBuckets,Standard_False)
23 {
24 }
25
26 //=======================================================================
27 //function : TCollection_DoubleMap
28 //purpose  : 
29 //=======================================================================
30
31 TCollection_DoubleMap::TCollection_DoubleMap
32   (const TCollection_DoubleMap& Other) :
33        TCollection_BasicMap(Other.NbBuckets(),Standard_False)
34 {
35   if (Other.Extent() != 0)
36     Standard_DomainError::Raise("TCollection:Copy of DoubleMap");
37 }
38
39 //=======================================================================
40 //function : Assign
41 //purpose  : 
42 //=======================================================================
43
44 TCollection_DoubleMap& TCollection_DoubleMap::Assign
45   (const TCollection_DoubleMap& Other)
46 {
47   if (this == &Other) return *this;
48   Clear();
49 //  ReSize(Other.NbBuckets());
50   if  (!Other.IsEmpty()) { 
51     ReSize(Other.Extent());
52     for (TCollection_DoubleMapIterator It(Other); It.More(); It.Next()) {
53       Bind(It.Key1(),It.Key2());
54     }
55   }
56   return *this;
57 }
58
59
60 //=======================================================================
61 //function : ReSize
62 //purpose  : 
63 //=======================================================================
64
65 void TCollection_DoubleMap::ReSize(const Standard_Integer N)
66 {
67   Standard_Integer newBuck;
68   Standard_Address newData1=NULL, newData2=NULL;
69   if (BeginResize(N,newBuck,newData1,newData2)) {
70     if (myData1) {
71       TCollection_DoubleMapNode** newdata1 = (TCollection_DoubleMapNode**) newData1;
72       TCollection_DoubleMapNode** newdata2 = (TCollection_DoubleMapNode**) newData2;
73       TCollection_DoubleMapNode** olddata1 = (TCollection_DoubleMapNode**) myData1;
74       TCollection_DoubleMapNode *p, *q;
75       Standard_Integer i,k1,k2;
76       for (i = 0; i <= NbBuckets(); i++) {
77         if (olddata1[i]) {
78           p = olddata1[i];
79           while (p) {
80             k1 = Hasher1::HashCode(p->Key1(),newBuck);
81             k2 = Hasher2::HashCode(p->Key2(),newBuck);
82             q = (TCollection_DoubleMapNode*) p->Next();
83             p->Next() = newdata1[k1];
84             p->Next2() = newdata2[k2];
85             newdata1[k1] = p;
86             newdata2[k2] = p;
87             p = q;
88           }
89         }
90       }
91     }
92     EndResize(N,newBuck,newData1,newData2);
93   }
94 }
95
96 //=======================================================================
97 //function : Clear
98 //purpose  : 
99 //=======================================================================
100
101 void TCollection_DoubleMap::Clear()
102 {
103   if (!IsEmpty()) {
104     Standard_Integer i;
105     TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**) myData1;
106 //    TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**) myData2;
107     TCollection_DoubleMapNode *p,*q;
108     for (i = 0; i <= NbBuckets(); i++) {
109       p = data1[i];
110       while (p) {
111         q = (TCollection_DoubleMapNode*) p->Next();
112         delete p;
113         p = q;
114       }
115     }
116   }
117   TCollection_BasicMap::Destroy();
118 }
119
120 //=======================================================================
121 //function : Bind
122 //purpose  : 
123 //=======================================================================
124
125 void TCollection_DoubleMap::Bind(const TheKey1& K1, const TheKey2& K2)
126 {
127   if (Resizable()) ReSize(Extent());
128   TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
129   TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
130   Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
131   Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
132   TCollection_DoubleMapNode* p;
133   p = data1[k1];
134   while (p) {
135     if (Hasher1::IsEqual(p->Key1(),K1)) 
136       Standard_MultiplyDefined::Raise("DoubleMap:Bind");
137     p = (TCollection_DoubleMapNode*) p->Next();
138   }
139   p = data2[k2];
140   while (p) {
141     if (Hasher2::IsEqual(p->Key2(),K2)) 
142       Standard_MultiplyDefined::Raise("DoubleMap:Bind");
143     p = (TCollection_DoubleMapNode*)p->Next2();
144   }
145   p = new TCollection_DoubleMapNode(K1,K2,data1[k1],data2[k2]);
146   data1[k1] = p;
147   data2[k2] = p;
148   Increment();
149 }
150
151 //=======================================================================
152 //function : AreBound
153 //purpose  : 
154 //=======================================================================
155
156 Standard_Boolean TCollection_DoubleMap::AreBound(const TheKey1& K1, 
157                                                  const TheKey2& K2) const
158 {
159   if (IsEmpty()) return Standard_False;
160   TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
161   TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
162   Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
163   Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
164   TCollection_DoubleMapNode *p1, *p2;
165   p1 = data1[k1];
166   while (p1) {
167     if (Hasher1::IsEqual(p1->Key1(),K1)) break;
168     p1 = (TCollection_DoubleMapNode*) p1->Next();
169   }
170   if (p1 == NULL) return Standard_False;
171   p2 = data2[k2];
172   while (p2) {
173     if (Hasher2::IsEqual(p2->Key2(),K2)) 
174       break;
175     p2 = (TCollection_DoubleMapNode*)p2->Next2();
176   }
177   if (p2 == NULL) return Standard_False;
178   return p1 == p2;
179 }
180
181 //=======================================================================
182 //function : IsBound1
183 //purpose  : 
184 //=======================================================================
185
186 Standard_Boolean TCollection_DoubleMap::IsBound1(const TheKey1& K1) const
187 {
188   if (IsEmpty()) return Standard_False;
189   TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
190   Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
191   TCollection_DoubleMapNode *p1;
192   p1 = data1[k1];
193   while (p1) {
194     if (Hasher1::IsEqual(p1->Key1(),K1)) return Standard_True;
195     p1 = (TCollection_DoubleMapNode*)  p1->Next();
196   }
197   return Standard_False;
198 }
199
200 //=======================================================================
201 //function : IsBound2
202 //purpose  : 
203 //=======================================================================
204
205 Standard_Boolean TCollection_DoubleMap::IsBound2(const TheKey2& K2) const
206 {
207   if (IsEmpty()) return Standard_False;
208   TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
209   Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
210   TCollection_DoubleMapNode *p2;
211   p2 = data2[k2];
212   while (p2) {
213     if (Hasher2::IsEqual(p2->Key2(),K2)) return Standard_True;
214     p2 = (TCollection_DoubleMapNode*)p2->Next2();
215   }
216   return Standard_False;
217 }
218
219 //=======================================================================
220 //function : Find1
221 //purpose  : 
222 //=======================================================================
223
224 const TheKey2& TCollection_DoubleMap::Find1(const TheKey1& K1) const
225 {
226   Standard_NoSuchObject_Raise_if(IsEmpty(),"TCollection_DoubleMap::Find1");  
227   TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
228   Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
229   TCollection_DoubleMapNode *p1;
230   p1 = data1[k1];
231   while (p1) {
232     if (Hasher1::IsEqual(p1->Key1(),K1)) return p1->Key2();
233     p1 = (TCollection_DoubleMapNode*) p1->Next();
234   }
235   Standard_NoSuchObject::Raise("TCollection_DoubleMap::Find1");
236   return p1->Key2();
237 }
238
239 //=======================================================================
240 //function : Find2
241 //purpose  : 
242 //=======================================================================
243
244 const TheKey1& TCollection_DoubleMap::Find2(const TheKey2& K2) const
245 {
246   Standard_NoSuchObject_Raise_if(IsEmpty(),"TCollection_DoubleMap::Find2");  
247   TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
248   Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
249   TCollection_DoubleMapNode *p2;
250   p2 = data2[k2];
251   while (p2) {
252     if (Hasher2::IsEqual(p2->Key2(),K2)) return p2->Key1();
253     p2 = (TCollection_DoubleMapNode*)p2->Next2();
254   }
255   Standard_NoSuchObject::Raise("TCollection_DoubleMap::Find2");
256   return p2->Key1();
257 }
258
259 //=======================================================================
260 //function : UnBind1
261 //purpose  : 
262 //=======================================================================
263
264 Standard_Boolean TCollection_DoubleMap::UnBind1(const TheKey1& K1)
265 {
266   if (IsEmpty()) return Standard_False;
267   TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
268   TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
269   Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
270   Standard_Integer k2;
271   TCollection_DoubleMapNode *p1, *p2, *q1, *q2;
272   q1 = q2 = NULL;
273   p1 = data1[k1];
274   while (p1) {
275     if (Hasher1::IsEqual(p1->Key1(),K1)) {
276       // remove from the first
277       if (q1)
278         q1->Next() = p1->Next();
279       else
280         data1[k1] = (TCollection_DoubleMapNode*) p1->Next();
281       // remove from the second
282       k2 = Hasher2::HashCode(p1->Key2(),NbBuckets());
283       p2 = data2[k2];
284       while (p2) {
285         if (p2 == p1) {
286           if (q2)
287             q2->Next2() = p2->Next2();
288           else
289             data2[k2] = (TCollection_DoubleMapNode*)p2->Next2();
290           break;
291         }
292         q2 = p2;
293         p2 = (TCollection_DoubleMapNode*)p2->Next2();
294       }
295       delete p1;
296       Decrement();
297       return Standard_True;
298     }
299     q1 = p1;
300     p1 = (TCollection_DoubleMapNode*) p1->Next();
301   }
302   return Standard_False;
303 }
304
305 //=======================================================================
306 //function : UnBind2
307 //purpose  : 
308 //=======================================================================
309
310 Standard_Boolean TCollection_DoubleMap::UnBind2(const TheKey2& K2)
311 {
312   if (IsEmpty()) return Standard_False;
313   TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
314   TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
315   Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
316   Standard_Integer k1;
317   TCollection_DoubleMapNode *p1, *p2, *q1, *q2;
318   q1 = q2 = NULL;
319   p2 = data2[k2];
320   while (p2) {
321     if (Hasher2::IsEqual(p2->Key2(),K2)) {
322       // remove from the second
323       if (q2)
324         q2->Next2() = p2->Next2();
325       else
326         data2[k2] = (TCollection_DoubleMapNode*)p2->Next2();
327       // remove from the first
328       k1 = Hasher1::HashCode(p2->Key1(),NbBuckets());
329       p1 = data1[k1];
330       while (p1) {
331         if (p2 == p1) {
332           if (q1)
333             q1->Next() = p1->Next();
334           else
335             data1[k1] = (TCollection_DoubleMapNode*) p1->Next();
336           break;
337         }
338         q1 = p1;
339         p1 = (TCollection_DoubleMapNode*)  p1->Next();
340       }
341       delete p2;
342       Decrement();
343       return Standard_True;
344     }
345     q2 = p2;
346     p2 = (TCollection_DoubleMapNode*)p2->Next2();
347   }
348   return Standard_False;
349 }
350
351 // method of the iterator
352
353 //=======================================================================
354 //function : Key1
355 //purpose  : 
356 //=======================================================================
357
358 const TheKey1& TCollection_DoubleMapIterator::Key1() const
359 {
360   Standard_NoSuchObject_Raise_if(!More(),"TCollection_DoubleMapIterator::Key1");  
361   return ((TCollection_DoubleMapNode*) myNode)->Key1();
362 }
363
364 //=======================================================================
365 //function : Key2
366 //purpose  : 
367 //=======================================================================
368
369 const TheKey2& TCollection_DoubleMapIterator::Key2() const
370 {
371   Standard_NoSuchObject_Raise_if(!More(),"TCollection_DoubleMapIterator::Key2");  
372   return ((TCollection_DoubleMapNode*) myNode)->Key2();
373 }
374
375
376 // @@SDM: begin
377
378 // Copyright Open CasCade......................................Version    5.0-00
379 // Lastly modified by : szy                                    Date :  7-05-2003
380
381 // File history synopsis (creation,modification,correction)
382 // +---------------------------------------------------------------------------+
383 // ! Developer !              Comments                   !   Date   ! Version  !
384 // +-----------!-----------------------------------------!----------!----------+
385 // !       rle ! Creation                                ! 8-01-1993! 5.0-00-3!
386 // !       szy ! Modified Assign method                  ! 7-05-2003! 5.0-00-3!
387 // +---------------------------------------------------------------------------+
388
389 // @@SDM: end