0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / Interface / Interface_IntList.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //szv#4 S4163
15
16 #include <Interface_IntList.hxx>
17
18 //   Organisation des donnees :
19 //   theents vaut : 0 pas de reference
20 //    > 0 : une reference, dont voici la valeur; pas de liste
21 //    < 0 : une liste de references; on stocke <rank>, elle debute a <rank>+1
22 //   la liste est dans therefs et est ainsi constitue :
23 //   liste de valeurs negatives, se terminant pas une valeur positive :
24 //   de <rank>+1 a <rank>+nb , <rank>+1 a <rank>+nb-1 sont negatifs et
25 //    <rank>+nb est negatif
26 //   un zero signifie : place libre
27 //   Pre-reservation : <rank> note le nombre courant, en positif strict
28 //   Il faut alors l incrementer a chaque ajout
29 //   Usage contextuel, il faut demander SetNumber(num < 0) pour exploiter cette
30 //   info et Add(ref < 0) pour la gerer.
31 //   Si elle n est pas presente, on bascule en mode courant
32 Interface_IntList::Interface_IntList ()
33 {
34   thenbe = thenbr = thenum = thecount = therank = 0;
35 }
36  Interface_IntList::Interface_IntList (const Standard_Integer nbe)
37 {
38   Initialize (nbe);
39 }
40
41   Interface_IntList::Interface_IntList (const Interface_IntList& other, const Standard_Boolean copied)
42 {
43   thenbe = other.NbEntities();
44   thenum = thecount = therank = 0; //szv#4:S4163:12Mar99 initialization needed
45   other.Internals (thenbr, theents, therefs);
46   if (copied) {
47     Standard_Integer i;
48     Handle(TColStd_HArray1OfInteger) ents = new TColStd_HArray1OfInteger (0,thenbe); ents->Init(0);
49     for (i = 1; i <= thenbe; i ++)  ents->SetValue (i,theents->Value(i));
50     Handle(TColStd_HArray1OfInteger) refs = new TColStd_HArray1OfInteger (0,thenbr); refs->Init(0);
51     for (i = 1; i <= thenbr; i ++)  refs->SetValue (i,therefs->Value(i));
52     theents = ents;
53     therefs = refs;
54   }
55   SetNumber (other.Number());
56 }
57 void Interface_IntList::Initialize (const Standard_Integer nbe)
58 {
59   thenbe = nbe;  thenbr = thenum = thecount = therank = 0;
60   theents = new TColStd_HArray1OfInteger (0,nbe); theents->Init(0);
61 }
62
63 void  Interface_IntList::Internals (Standard_Integer& nbrefs,
64                                     Handle(TColStd_HArray1OfInteger)& ents,
65                                     Handle(TColStd_HArray1OfInteger)& refs) const
66 {
67   nbrefs = thenbr;  ents = theents;  refs = therefs;
68 }
69
70 Standard_Integer  Interface_IntList::NbEntities () const
71 {
72   return thenbe;
73 }
74
75 void  Interface_IntList::SetNbEntities (const Standard_Integer nbe)
76 {
77   if (nbe <= theents->Upper()) return;
78   Standard_Integer i;
79   Handle(TColStd_HArray1OfInteger) ents = new TColStd_HArray1OfInteger (0,nbe); ents->Init(0);
80   for (i = 1; i <= thenbe; i ++)  ents->SetValue (i,theents->Value(i));
81   theents = ents;
82   thenbe  = nbe;
83 }
84
85 void  Interface_IntList::SetNumber (const Standard_Integer number)
86 {
87   //  Usage en pre-reservation : a demander specifiquement ! -> optimisation
88   //   <preres> verifie que la pre-reservation est valide
89   if (number < 0) {
90     if (thenum == -number || number < - thenbe) return;
91     Standard_Boolean preres = Standard_True;
92     thenum   = -number;
93     Standard_Integer val = theents->Value (thenum);
94     if      (val ==  0)  {  thecount = 0;  therank =  0;  }
95     else if (val > 0)    {  thecount = 1;  therank = -1;  }
96     if (val < -1) {
97       therank  = -val;
98       thecount = therefs->Value(therank);
99       if (thecount <= 0) preres = Standard_False;
100     }
101     if (preres) return;
102   }
103   //  Usage courant. La suite en usage courant ou si pas de pre-reservation
104   else if (number > 0) {
105     if (thenum == number || number > thenbe) return;
106     thenum = number;
107   }
108   else return;
109
110   Standard_Integer val = theents->Value(thenum);
111   if      (val ==  0)  {  thecount = 0;  therank =  0;  }
112   else if (val > 0)    {  thecount = 1;  therank = -1;  }
113   else if (val < -1) {
114     therank = - val;  thecount = 0;
115     if (therefs->Value(therank+1) == 0) thecount = - therefs->Value(therank);
116     else {
117       for (Standard_Integer j = 1; ; j ++) {
118         val = therefs->Value (therank+j);
119         if (val >= 0) break;
120         thecount ++;
121       }
122       if (val > 0) thecount ++;
123     }
124   }
125   else {  thecount = 0;  therank = -1;  }  // val == -1 reste
126 }
127
128 Standard_Integer  Interface_IntList::Number () const
129 {
130   return thenum;
131 }
132
133 Interface_IntList  Interface_IntList::List (const Standard_Integer number,
134                                             const Standard_Boolean copied) const
135 {
136   Interface_IntList alist (*this,copied);
137   alist.SetNumber (number);
138   return alist;
139 }
140
141 void  Interface_IntList::SetRedefined (const Standard_Boolean mode)
142 {
143   if (!NbEntities() || thenum == 0) return;
144  
145   Standard_Integer val = theents->Value(thenum);
146   if (val < -1) return;
147   else if (mode) {
148     if (val == 0) theents->SetValue (thenum,-1);
149     else if (val > 0) {
150       Reservate (2);
151       theents->SetValue (thenum, -thenbr);
152       therefs->SetValue (thenbr+1, val);
153       thenbr ++;
154     }
155   } else if (!mode) {
156     if (val == -1) theents->SetValue (thenum,0);
157     else if (therefs->Value (therank+1) >= 0) {
158       theents->SetValue (thenum, therefs->Value(therank+1));
159       if (thenbr == therank+1) thenbr --;
160     }
161   }
162 }
163
164 void  Interface_IntList::Reservate (const Standard_Integer count)
165 {
166   //  Reservate (-count) = Reservate (count) + allocation sur entite courante + 1
167   if (count < 0) {
168     Reservate(-count-1);
169     if (thenum == 0) return;
170     thenbr ++;
171     therefs->SetValue (thenbr,0);  // contiendra le nombre ...
172     therank = thenbr;
173     theents->SetValue(thenum, -thenbr);
174     thenbr -= count;
175     return;
176   }
177   Standard_Integer up, oldup = 0;
178   if (thenbr == 0) {    //  c-a-d pas encore allouee ...
179     up = thenbe/2+1;  if (up < 2) up = 2;
180     if (up < count) up = count*3/2;
181     therefs = new TColStd_HArray1OfInteger (0,up); therefs->Init(0);
182     thenbr  = 2;        // on commence apres (commodite d adressage)
183   }
184   oldup = therefs->Upper();
185   if (thenbr + count < oldup) return;  // OK
186   up = oldup*3/2+count;  if (up < 2) up = 2;
187   Handle(TColStd_HArray1OfInteger) refs = new TColStd_HArray1OfInteger (0,up); refs->Init(0);
188   for (Standard_Integer i = 1; i <= oldup; i ++)  refs->SetValue (i,therefs->Value(i));
189   therefs = refs;
190 }
191
192     void  Interface_IntList::Add (const Standard_Integer ref)
193 {
194   if (thenum == 0) return;
195   //   ref < 0 : pre-reservation
196   if (ref < 0) {
197     Add(-ref);
198     if (therank <= 0) return;
199     if (therefs->Value(therank) >= 0) therefs->SetValue (therank, thecount);
200     return;
201   }
202
203   if (therank == 0)
204     {   theents->SetValue (thenum,ref); thecount = 1; therank = -1; }
205   else if (therank < 0) {
206     Reservate (2);
207     therank = thenbr;
208     Standard_Integer val = theents->Value(thenum);
209     theents->SetValue (thenum, -thenbr);
210     if (thecount == 1)
211       {  therefs->SetValue (thenbr+1, -val);  thenbr ++;  }
212     therefs->SetValue (thenbr+1, ref);  thenbr ++;
213     thecount ++;
214   } else if (thenbr == therank+thecount) {  // place libre en fin
215     therefs->SetValue (thenbr, -therefs->Value(thenbr));
216     therefs->SetValue (thenbr+1, ref);  thenbr ++;
217     thecount ++;
218   } else if (therefs->Value(therank+thecount+1) == 0) {  // place libre apres
219     therefs->SetValue (therank+thecount, -therefs->Value(therank+thecount));
220     therefs->SetValue (therank+thecount+1, ref);
221     thecount ++;
222   } else {       // recopier plus loin !
223     Reservate (thecount+2);
224     Standard_Integer rank = therank;
225     therank = thenbr;
226     theents->SetValue (thenum,-therank);
227     for (Standard_Integer i = 1; i < thecount; i ++) {
228       therefs->SetValue (therank+i, therefs->Value(rank+i));
229       therefs->SetValue (rank+i,0);
230     }
231     therefs->SetValue (therank+thecount, -therefs->Value(rank+thecount));
232     therefs->SetValue (rank+thecount,0);
233     therefs->SetValue (therank+thecount+1,ref);
234     thecount ++;  thenbr = therank + thecount + 1;
235   }
236 }
237
238
239 Standard_Integer  Interface_IntList::Length () const
240 {
241   return thecount;
242 }
243
244 Standard_Boolean  Interface_IntList::IsRedefined (const Standard_Integer num) const
245 {
246   Standard_Integer n = (num == 0 ? thenum : num);
247   if (!NbEntities() || n == 0) return Standard_False;
248   if (theents->Value(n) < 0) return Standard_True;
249   return Standard_False;
250 }
251
252 Standard_Integer  Interface_IntList::Value (const Standard_Integer num) const
253 {
254   if (thenum == 0) return 0;
255   if (num <= 0 || num > thecount) return 0;
256   if (thecount == 0) return 0;
257   if (therank <= 0) return theents->Value(thenum);
258   Standard_Integer val = therefs->Value (therank+num);
259   if (val < 0) return -val;
260   return val;
261 }
262
263 Standard_Boolean  Interface_IntList::Remove (const Standard_Integer)
264 {
265   return Standard_False;    // not yet implemented
266 }
267
268 void  Interface_IntList::Clear ()
269 {
270   if (thenbr == 0) return;  // deja clear
271   Standard_Integer i,low,up;
272   low = theents->Lower();  up = theents->Upper();
273   for (i = low; i <= up; i ++)  theents->SetValue (i,0);
274   thenbr = 0;
275   if (therefs.IsNull()) return;
276   low = therefs->Lower();  up = therefs->Upper();
277   for (i = low; i <= up; i ++)  therefs->SetValue (i,0);
278 }
279
280 void  Interface_IntList::AdjustSize (const Standard_Integer margin)
281 {
282   Standard_Integer i, up = theents->Upper();
283   if (up > thenbe) {
284     Handle(TColStd_HArray1OfInteger) ents = new TColStd_HArray1OfInteger (0,thenbe); ents->Init(0);
285     for (i = 1; i <= thenbe; i ++)  ents->SetValue (i,theents->Value(i));
286     theents = ents;
287   }
288   if (thenbr == 0) Reservate (margin);
289   else {
290     up = therefs->Upper();
291     if (up >= thenbr && up <= thenbr + margin) return;
292     Handle(TColStd_HArray1OfInteger) refs = new TColStd_HArray1OfInteger (0,thenbr+margin); refs->Init(0);
293     for (i = 1; i <= thenbr; i ++)  refs->SetValue (i,therefs->Value(i));
294     therefs = refs;
295   }
296 }