1 // Created on: 1993-01-08
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Standard_DomainError.hxx>
18 #include <Standard_MultiplyDefined.hxx>
19 #include <Standard_NoSuchObject.hxx>
22 //=======================================================================
23 //function : TCollection_DoubleMap
25 //=======================================================================
27 TCollection_DoubleMap::TCollection_DoubleMap(const Standard_Integer NbBuckets):
28 TCollection_BasicMap(NbBuckets,Standard_False)
32 //=======================================================================
33 //function : TCollection_DoubleMap
35 //=======================================================================
37 TCollection_DoubleMap::TCollection_DoubleMap
38 (const TCollection_DoubleMap& Other) :
39 TCollection_BasicMap(Other.NbBuckets(),Standard_False)
41 if (Other.Extent() != 0)
42 throw Standard_DomainError("TCollection:Copy of DoubleMap");
45 //=======================================================================
48 //=======================================================================
50 TCollection_DoubleMap& TCollection_DoubleMap::Assign
51 (const TCollection_DoubleMap& Other)
53 if (this == &Other) return *this;
55 // ReSize(Other.NbBuckets());
56 if (!Other.IsEmpty()) {
57 ReSize(Other.Extent());
58 for (TCollection_DoubleMapIterator It(Other); It.More(); It.Next()) {
59 Bind(It.Key1(),It.Key2());
66 //=======================================================================
69 //=======================================================================
71 void TCollection_DoubleMap::ReSize(const Standard_Integer N)
73 Standard_Integer newBuck;
74 Standard_Address newData1=NULL, newData2=NULL;
75 if (BeginResize(N,newBuck,newData1,newData2)) {
77 TCollection_DoubleMapNode** newdata1 = (TCollection_DoubleMapNode**) newData1;
78 TCollection_DoubleMapNode** newdata2 = (TCollection_DoubleMapNode**) newData2;
79 TCollection_DoubleMapNode** olddata1 = (TCollection_DoubleMapNode**) myData1;
80 TCollection_DoubleMapNode *p, *q;
81 Standard_Integer i,k1,k2;
82 for (i = 0; i <= NbBuckets(); i++) {
86 k1 = Hasher1::HashCode(p->Key1(),newBuck);
87 k2 = Hasher2::HashCode(p->Key2(),newBuck);
88 q = (TCollection_DoubleMapNode*) p->Next();
89 p->Next() = newdata1[k1];
90 p->Next2() = newdata2[k2];
98 EndResize(N,newBuck,newData1,newData2);
102 //=======================================================================
105 //=======================================================================
107 void TCollection_DoubleMap::Clear()
111 TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**) myData1;
112 // TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**) myData2;
113 TCollection_DoubleMapNode *p,*q;
114 for (i = 0; i <= NbBuckets(); i++) {
117 q = (TCollection_DoubleMapNode*) p->Next();
123 TCollection_BasicMap::Destroy();
126 //=======================================================================
129 //=======================================================================
131 void TCollection_DoubleMap::Bind(const TheKey1& K1, const TheKey2& K2)
133 if (Resizable()) ReSize(Extent());
134 TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
135 TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
136 Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
137 Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
138 TCollection_DoubleMapNode* p;
141 if (Hasher1::IsEqual(p->Key1(),K1))
142 throw Standard_MultiplyDefined("DoubleMap:Bind");
143 p = (TCollection_DoubleMapNode*) p->Next();
147 if (Hasher2::IsEqual(p->Key2(),K2))
148 throw Standard_MultiplyDefined("DoubleMap:Bind");
149 p = (TCollection_DoubleMapNode*)p->Next2();
151 p = new TCollection_DoubleMapNode(K1,K2,data1[k1],data2[k2]);
157 //=======================================================================
158 //function : AreBound
160 //=======================================================================
162 Standard_Boolean TCollection_DoubleMap::AreBound(const TheKey1& K1,
163 const TheKey2& K2) const
165 if (IsEmpty()) return Standard_False;
166 TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
167 TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
168 Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
169 Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
170 TCollection_DoubleMapNode *p1, *p2;
173 if (Hasher1::IsEqual(p1->Key1(),K1)) break;
174 p1 = (TCollection_DoubleMapNode*) p1->Next();
176 if (p1 == NULL) return Standard_False;
179 if (Hasher2::IsEqual(p2->Key2(),K2))
181 p2 = (TCollection_DoubleMapNode*)p2->Next2();
183 if (p2 == NULL) return Standard_False;
187 //=======================================================================
188 //function : IsBound1
190 //=======================================================================
192 Standard_Boolean TCollection_DoubleMap::IsBound1(const TheKey1& K1) const
194 if (IsEmpty()) return Standard_False;
195 TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
196 Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
197 TCollection_DoubleMapNode *p1;
200 if (Hasher1::IsEqual(p1->Key1(),K1)) return Standard_True;
201 p1 = (TCollection_DoubleMapNode*) p1->Next();
203 return Standard_False;
206 //=======================================================================
207 //function : IsBound2
209 //=======================================================================
211 Standard_Boolean TCollection_DoubleMap::IsBound2(const TheKey2& K2) const
213 if (IsEmpty()) return Standard_False;
214 TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
215 Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
216 TCollection_DoubleMapNode *p2;
219 if (Hasher2::IsEqual(p2->Key2(),K2)) return Standard_True;
220 p2 = (TCollection_DoubleMapNode*)p2->Next2();
222 return Standard_False;
225 //=======================================================================
228 //=======================================================================
230 const TheKey2& TCollection_DoubleMap::Find1(const TheKey1& K1) const
232 Standard_NoSuchObject_Raise_if(IsEmpty(),"TCollection_DoubleMap::Find1");
233 TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
234 Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
235 TCollection_DoubleMapNode *p1;
238 if (Hasher1::IsEqual(p1->Key1(),K1)) return p1->Key2();
239 p1 = (TCollection_DoubleMapNode*) p1->Next();
241 throw Standard_NoSuchObject("TCollection_DoubleMap::Find1");
245 //=======================================================================
248 //=======================================================================
250 const TheKey1& TCollection_DoubleMap::Find2(const TheKey2& K2) const
252 Standard_NoSuchObject_Raise_if(IsEmpty(),"TCollection_DoubleMap::Find2");
253 TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
254 Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
255 TCollection_DoubleMapNode *p2;
258 if (Hasher2::IsEqual(p2->Key2(),K2)) return p2->Key1();
259 p2 = (TCollection_DoubleMapNode*)p2->Next2();
261 throw Standard_NoSuchObject("TCollection_DoubleMap::Find2");
265 //=======================================================================
268 //=======================================================================
270 Standard_Boolean TCollection_DoubleMap::UnBind1(const TheKey1& K1)
272 if (IsEmpty()) return Standard_False;
273 TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
274 TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
275 Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets());
277 TCollection_DoubleMapNode *p1, *p2, *q1, *q2;
281 if (Hasher1::IsEqual(p1->Key1(),K1)) {
282 // remove from the first
284 q1->Next() = p1->Next();
286 data1[k1] = (TCollection_DoubleMapNode*) p1->Next();
287 // remove from the second
288 k2 = Hasher2::HashCode(p1->Key2(),NbBuckets());
293 q2->Next2() = p2->Next2();
295 data2[k2] = (TCollection_DoubleMapNode*)p2->Next2();
299 p2 = (TCollection_DoubleMapNode*)p2->Next2();
303 return Standard_True;
306 p1 = (TCollection_DoubleMapNode*) p1->Next();
308 return Standard_False;
311 //=======================================================================
314 //=======================================================================
316 Standard_Boolean TCollection_DoubleMap::UnBind2(const TheKey2& K2)
318 if (IsEmpty()) return Standard_False;
319 TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1;
320 TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2;
321 Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets());
323 TCollection_DoubleMapNode *p1, *p2, *q1, *q2;
327 if (Hasher2::IsEqual(p2->Key2(),K2)) {
328 // remove from the second
330 q2->Next2() = p2->Next2();
332 data2[k2] = (TCollection_DoubleMapNode*)p2->Next2();
333 // remove from the first
334 k1 = Hasher1::HashCode(p2->Key1(),NbBuckets());
339 q1->Next() = p1->Next();
341 data1[k1] = (TCollection_DoubleMapNode*) p1->Next();
345 p1 = (TCollection_DoubleMapNode*) p1->Next();
349 return Standard_True;
352 p2 = (TCollection_DoubleMapNode*)p2->Next2();
354 return Standard_False;
357 // method of the iterator
359 //=======================================================================
362 //=======================================================================
364 const TheKey1& TCollection_DoubleMapIterator::Key1() const
366 Standard_NoSuchObject_Raise_if(!More(),"TCollection_DoubleMapIterator::Key1");
367 return ((TCollection_DoubleMapNode*) myNode)->Key1();
370 //=======================================================================
373 //=======================================================================
375 const TheKey2& TCollection_DoubleMapIterator::Key2() const
377 Standard_NoSuchObject_Raise_if(!More(),"TCollection_DoubleMapIterator::Key2");
378 return ((TCollection_DoubleMapNode*) myNode)->Key2();