0024645: Pointer to the last is wrong for a tree node
[occt.git] / src / PCollection / PCollection_HSet.gxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <Standard_NoSuchObject.hxx>
16 #include <Standard_NoMoreObject.hxx>
17 #include <Standard_NotImplemented.hxx>
18
19 // ------------
20 // constructor
21 // -----------
22
23 PCollection_HSet::PCollection_HSet() 
24 {
25     TheExtent   = 0;
26     TheLast     = new PCollection_SetNode;
27 }
28
29 // -----------------------------
30 // IsEmpty : is the Set empty ? 
31 // -----------------------------
32 Standard_Boolean PCollection_HSet::IsEmpty() const 
33 {
34     return TheLast->IsEmpty();
35
36
37 // ----------------
38 // Contains an item 
39 // ----------------
40 Standard_Boolean PCollection_HSet::Contains(const Item& T) const
41 {
42     Standard_Boolean Ilela;
43     Handle(PCollection_SetNode) TheCurrent;
44     TheCurrent = TheLast; 
45     Ilela      = Standard_False;
46     while (!Ilela && !TheCurrent->IsEmpty())
47       { 
48        if (TheCurrent->Value() == T) 
49           Ilela      = Standard_True;
50        else
51           TheCurrent = TheCurrent->Tail();       
52       };     
53     return Ilela;
54 }    
55
56 // ---------------------------------
57 // The Set S IsASubset of the set me
58 // ---------------------------------
59 Standard_Boolean PCollection_HSet::IsASubset(const Handle(PCollection_HSet)& S) const 
60 {
61     Standard_Boolean Ilela,Ilsonla;
62     Handle(PCollection_SetNode) TheCurrent1,TheCurrent2;
63     TheCurrent1 = TheLast;
64     TheCurrent2 = S->Last(); 
65     Ilela       = Standard_False;
66     Ilsonla     = Standard_True;
67     while (Ilsonla && !TheCurrent2->IsEmpty())
68     { 
69       while (!Ilela && !TheCurrent1->IsEmpty())
70       { 
71        if (TheCurrent1->Value() == TheCurrent2->Value()) 
72           Ilela = Standard_True;
73        else
74           TheCurrent1 = TheCurrent1->Tail();       
75       };     
76     if (!Ilela)
77        Ilsonla = Standard_False;
78     else
79       {
80        TheCurrent2 = TheCurrent2->Tail();
81        TheCurrent1 = TheLast;
82       };
83     };    
84     return Ilsonla;
85
86 }
87
88  
89 // ----------------------------------------
90 // The Set S IsAProperSubset of the set me
91 // ----------------------------------------
92 Standard_Boolean PCollection_HSet::IsAProperSubset(const Handle(PCollection_HSet)& S) const 
93 {
94     Standard_Boolean Ilela,Ilsonla;
95     Handle(PCollection_SetNode) TheCurrent1,TheCurrent2;
96     TheCurrent1 = TheLast;
97     TheCurrent2 = S->Last(); 
98     Ilela       = Standard_False;
99     Ilsonla     = Standard_True;
100     if (S->Extent() >= TheExtent) Ilsonla = Standard_False; 
101     while (Ilsonla && !TheCurrent2->IsEmpty())
102     { 
103       while (!Ilela && !TheCurrent1->IsEmpty())
104       { 
105        if (TheCurrent1->Value() == TheCurrent2->Value()) 
106           Ilela      = Standard_True;
107        else
108           TheCurrent1 = TheCurrent1->Tail();       
109       };     
110      if (!Ilela)
111         Ilsonla = Standard_False;
112      else
113        {
114         TheCurrent2 = TheCurrent2->Tail();
115         TheCurrent1 = TheLast;
116        };
117     };    
118     return Ilsonla;
119
120
121
122 // ------------------------------------
123 // Clear : remove all items
124 // ------------------------------------
125 void PCollection_HSet::Clear() 
126 {   
127    Handle(PCollection_SetNode) temp; 
128    while (TheExtent != 0) {
129       temp = TheLast;
130       TheLast = TheLast->Tail();
131 #ifndef CSFDB 
132       temp.Delete();
133 #endif
134       --TheExtent;
135    }  
136 }
137
138 // -------------------------------------------
139 // Add : insert an item 
140 // returns Standard_True if the item has been inserted, 
141 // Standard_False otherwise
142 // ------------------------------------------- 
143 Standard_Boolean PCollection_HSet::Add(const Item& T)
144 {   
145     Standard_Boolean Dejala;
146     Handle(PCollection_SetNode) TheCurrent;
147     TheCurrent = TheLast; 
148     Dejala = Standard_False;
149     while (!Dejala && !TheCurrent->IsEmpty())
150       { if (TheCurrent->Value() == T) Dejala = Standard_True;
151         TheCurrent = TheCurrent->Tail();       
152       };     
153     if (!Dejala)
154       {
155        TheLast = TheLast->Construct(T);
156        TheExtent = TheExtent + 1;
157       };     
158     return !Dejala;
159 }
160
161 // ------------------------
162 // Remove : remove an item 
163 // from the set me.
164 // Raises Standard_NoSuchObject
165 // ------------------------
166 void PCollection_HSet::Remove(const Item& T)
167 {   
168    Standard_Boolean Nepala;
169    Handle(PCollection_SetNode) TheCurrent,ThePrevious;
170    TheCurrent  = TheLast; 
171    ThePrevious = TheLast;
172    Nepala      = Standard_True;
173    while (Nepala && !TheCurrent->IsEmpty()) { 
174       if (TheCurrent->Value() == T) 
175         Nepala      = Standard_False;
176       else {
177         ThePrevious = TheCurrent;
178         TheCurrent  = TheCurrent->Tail();
179       }       
180    }     
181    if (Nepala)
182      Standard_NoSuchObject::Raise();     
183    else {
184      if (TheCurrent == ThePrevious)
185        TheLast = TheLast->Tail();
186      else 
187        ThePrevious->ChangeForwardPointer(TheCurrent->Tail());
188      TheExtent = TheExtent - 1;
189 #ifndef CSFDB
190      TheCurrent.Delete();
191 #endif
192    }
193 }
194
195 // ------------------------------------
196 // Union with the set S
197 // returns a set containing all the 
198 // items of the set me and all the items 
199 // of the set B which are not in me
200 // ------------------------------------
201 Handle(PCollection_HSet) PCollection_HSet::Union(const Handle(PCollection_HSet)& S) 
202 const 
203 {   
204     Standard_Boolean Insere;
205     Handle(PCollection_SetNode) TheCurrent;
206     Handle(PCollection_HSet) Lunion;
207     Lunion = new PCollection_HSet;
208 // copier this dans Lunion 
209     TheCurrent = TheLast;
210     while (!TheCurrent->IsEmpty())
211       { 
212        Insere = Lunion->Add(TheCurrent->Value());
213        TheCurrent = TheCurrent->Tail();
214       };
215 // Inserer dans Lunion les items de S    
216     TheCurrent = S->Last();
217     while (!TheCurrent->IsEmpty())
218       { 
219        Insere = Lunion->Add(TheCurrent->Value());
220        TheCurrent = TheCurrent->Tail();
221       };
222     return Lunion;
223 }
224
225 // -----------------------------
226 // Intersection with the set S 
227 // -----------------------------
228 Handle(PCollection_HSet) PCollection_HSet::
229                           Intersection(const Handle(PCollection_HSet)& S)  
230 const
231 {
232     Item Litem;
233     Standard_Boolean Insere;
234     Handle(PCollection_SetNode) TheCurrent1,TheCurrent2;
235     Handle(PCollection_HSet) Linter;
236     Linter = new PCollection_HSet;
237     TheCurrent1 = TheLast;
238     while (!TheCurrent1->IsEmpty())
239       { 
240        Litem = TheCurrent1->Value();
241        TheCurrent2 = S->Last();
242        while (!TheCurrent2->IsEmpty())
243          {
244           if (TheCurrent2->Value() == Litem) 
245              Insere = Linter->Add(Litem);
246           TheCurrent2 = TheCurrent2->Tail();           
247          };
248        TheCurrent1 = TheCurrent1->Tail();  
249       };
250     return Linter;
251 }    
252
253
254 // -----------------------------
255 // Difference with the set S 
256 // returns a set containing the 
257 // items which are in the set me
258 // and not in the set B 
259 // -----------------------------
260 Handle(PCollection_HSet) PCollection_HSet::
261                          Difference(const Handle(PCollection_HSet)& S) 
262 const
263 {    
264     Item Litem;
265     Standard_Boolean Insere,Ilela;
266     Handle(PCollection_SetNode) TheCurrent1,TheCurrent2;
267     Handle(PCollection_HSet) Ladif;
268     Ladif = new PCollection_HSet;
269     TheCurrent1 = TheLast;
270     while (!TheCurrent1->IsEmpty())
271       { 
272        Litem = TheCurrent1->Value();
273        TheCurrent2 = S->Last();
274        Ilela = Standard_False;
275        while (!TheCurrent2->IsEmpty() && !Ilela)
276          {
277           if (TheCurrent2->Value() == Litem)
278              Ilela = Standard_True;
279           else
280              TheCurrent2 = TheCurrent2->Tail();
281          };
282        if (!Ilela)
283        Insere = Ladif->Add(Litem);           
284        TheCurrent1 = TheCurrent1->Tail();  
285       };
286     return Ladif;
287 }
288
289
290 //---------------------------------------------------------------------
291 // ShallowCopy
292 //---------------------------------------------------------------------
293 Handle(Standard_Persistent) PCollection_HSet::ShallowCopy() const
294 {
295
296   PCollection_HSet* TheCopy = new PCollection_HSet (*this);
297   TheCopy->TheLast = 
298       Handle(PCollection_SetNode)::DownCast(::ShallowCopy(TheLast));
299   return TheCopy;
300
301 }
302
303 //---------------------------------------------------------------------
304 // ShallowDump
305 //---------------------------------------------------------------------
306 void PCollection_HSet::ShallowDump(Standard_OStream& S) const
307 {
308
309   S << "begin class Set "<<endl;
310   S << "extent of Set : "<< TheExtent << endl;
311   TheLast->ShallowDump(S);
312   S << "end of class Set." << endl;
313
314 }
315
316
317
318
319
320 // -----------------------------
321 // Extent : numbers of items 
322 // -----------------------------
323 Standard_Integer PCollection_HSet::Extent() const {
324     return TheExtent;
325
326
327 // -----------------------------
328 // Last : last enterred item  
329 // -----------------------------
330 Handle(PCollection_SetNode) PCollection_HSet::Last() const {
331     return TheLast;
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403