0024927: Getting rid of "Persistent" functionality -- Code
[occt.git] / src / PCollection / PCollection_HSequence.gxx
1 // Created on: 1992-09-24
2 // Created by: Mireille MERCIEN
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Standard_NoSuchObject.hxx>
18 #include <Standard_OutOfRange.hxx>
19 #include <Standard_NotImplemented.hxx>
20 #include <Standard_ProgramError.hxx>
21 #include <Standard_OStream.hxx>
22
23 // ----------------------------------------------------------------------
24 // ----------------------------------------------------------------------
25
26 // -----------
27 // constructor :
28 // -----------
29 PCollection_HSequence::PCollection_HSequence()
30 {
31    Size = 0;
32    FirstItem.Nullify();
33    LastItem.Nullify();
34 }
35
36 // ----------------------------------
37 // Clear : Clear the Current Sequence
38 // ----------------------------------
39 void PCollection_HSequence::Clear()
40 {
41    Handle(PCollection_SeqNode) cell;
42    Handle(PCollection_SeqNode) pnul;
43    pnul.Nullify(); 
44    if (Size != 0) {
45       while (Size != 1) {
46          cell = FirstItem;
47          FirstItem = FirstItem->Next();
48          FirstItem->SetPrevious(pnul);
49 #ifndef CSFDB
50          cell.Delete();
51 #endif
52          --Size;
53       }
54       FirstItem.Nullify();
55 #ifndef CSFDB
56       LastItem.Delete();          // free memory
57 #endif
58       Size = 0;
59    } 
60 }
61
62 // -------------------------------------------------
63 // Append : Push an item  at the end of the sequence
64 // -------------------------------------------------
65 void PCollection_HSequence::Append(const Item& T)
66 {
67    Handle(PCollection_SeqNode) newcell;
68 #ifndef OBJS
69    newcell = new PCollection_SeqNode(LastItem,T);
70 #else
71    newcell = new (os_segment::of(this)) PCollection_SeqNode(LastItem,T);
72 #endif
73    if (Size == 0) FirstItem = newcell;   
74    if (!LastItem.IsNull()) LastItem->SetNext(newcell);
75    LastItem = newcell;   
76    ++Size;                        
77    
78 }
79
80 // ---------------------------------------------------
81 // Append : Push a sequence at the end of the sequence
82 // ---------------------------------------------------
83 void PCollection_HSequence::Append(const Handle(PCollection_HSequence)& S)
84 {
85    for (Standard_Integer i = 1; i <= S->Length(); i++)
86       Append (S->Value(i));
87 }
88
89 // ---------------------------------------------------------
90 // Prepend : Push an element at the begining of the sequence
91 // ---------------------------------------------------------
92 void PCollection_HSequence::Prepend(const Item& T)
93 {
94    Handle(PCollection_SeqNode) newcell;
95 #ifndef OBJS
96    newcell = new PCollection_SeqNode(T,FirstItem);
97 #else
98    newcell = new (os_segment::of(this)) PCollection_SeqNode(T,FirstItem);
99 #endif
100    if (Size == 0) LastItem = newcell;   
101    if (!FirstItem.IsNull()) FirstItem->SetPrevious(newcell);
102    FirstItem = newcell;
103    ++Size;   
104 }
105
106 // ---------------------------------------------------------
107 // Prepend : Push a sequence at the begining of the sequence
108 // ---------------------------------------------------------
109 void PCollection_HSequence::Prepend(const Handle (PCollection_HSequence)& S)
110 {
111    for (Standard_Integer i = S->Length(); i >= 1; i--)
112       Prepend (S->Value(i));
113
114 }
115
116 // ---------------------------------------------------------
117 // Reverse : Reverse the order of a given sequence
118 // ---------------------------------------------------------
119 void PCollection_HSequence::Reverse()
120 {
121    if (Size == 0 || Size == 1) return;
122    Handle(PCollection_SeqNode) back,next,temp;
123    temp = LastItem;
124    while (!temp.IsNull())
125    {
126       back = temp->Previous();
127       next = temp->Next();
128       temp->SetNext(back);
129       temp->SetPrevious(next);
130       temp = temp->Next(); 
131    }
132    temp      = FirstItem;
133    FirstItem = LastItem;
134    LastItem  = temp;
135 }
136
137 // -------------------------------------------------------------------
138 // InsertBefore : Insert an item before a given index in the sequence
139 // --------------------------------------------------------------------
140 void PCollection_HSequence::InsertBefore(const Standard_Integer Index, 
141                                        const Item& T)
142 {
143    if ( Index <= 0 || Index > Length() ) Standard_OutOfRange::Raise();
144    if ( Index == 1 )  { 
145      Prepend (T);
146      return; 
147    }
148
149 //Index research
150    Standard_Integer i = 1;
151    Handle(PCollection_SeqNode) cell = FirstItem;
152    while (i != Index)  {
153      cell = cell->Next();             
154      ++i;
155    }
156
157 // Insertion before Index
158    Handle(PCollection_SeqNode) previous = cell->Previous();
159 #ifndef OBJS
160    Handle(PCollection_SeqNode) temp = new PCollection_SeqNode(previous,cell,T);
161 #else
162    Handle(PCollection_SeqNode) temp = new (os_segment::of(this)) PCollection_SeqNode(previous,cell,T);
163 #endif
164    previous->SetNext(temp);
165    cell->SetPrevious(temp);
166    ++Size;      
167 }
168
169 // ----------------------------------------------------------------------
170 // InsertBefore : Insert a sequence before a specific index in a sequence
171 // ----------------------------------------------------------------------
172 void PCollection_HSequence::InsertBefore(const Standard_Integer Index , 
173                                        const Handle(PCollection_HSequence)& S)
174 {
175    if ( Index <= 0 || Index > Size ) Standard_OutOfRange::Raise();
176    for (Standard_Integer i = 1, j = Index ; i <= S->Length(); i++,j++)
177        InsertBefore(j,S->Value(i));
178 }
179
180 // -----------------------------------------------------------------
181 // InsertAfter : Insert an element after a given index in a sequence
182 // -----------------------------------------------------------------
183 void PCollection_HSequence::InsertAfter(const Standard_Integer Index, 
184                                       const Item& T)
185 {
186    if ( Index <= 0 || Index > Length() ) Standard_OutOfRange::Raise();
187    if ( Index == Size ) 
188       Append (T);
189    else 
190       InsertBefore (Index+1,T);
191 }
192
193 // -------------------------------------------------------------------
194 // InsertAfter : Insert a sequence after a given index in the sequence
195 // -------------------------------------------------------------------
196 void PCollection_HSequence::InsertAfter(const Standard_Integer Index, 
197                                       const Handle(PCollection_HSequence)&S)
198 {
199    if ( Index <= 0 || Index > Length() ) Standard_OutOfRange::Raise();
200    for (Standard_Integer i = 1, j = Index ; i <= S->Length(); i++,j++)
201       InsertAfter (j,S->Value(i));
202 }
203
204 // ----------------------------------------
205 // Exchange : Exchange two elements in the sequence
206 // ----------------------------------------
207 void PCollection_HSequence::Exchange(const Standard_Integer I, 
208                                    const Standard_Integer J)
209 {
210    if ( I <= 0 || J <= 0 || I > Length() || J > Length() ) 
211                                            Standard_OutOfRange::Raise();
212    Item T = Value(J);
213    SetValue(J,Value(I));
214    SetValue(I,T);
215 }
216
217 // ----------------------------------------------------
218 // SubSequence : Returns a sub-sequence from a sequence
219 // ----------------------------------------------------
220 Handle(PCollection_HSequence) PCollection_HSequence::SubSequence
221       (const Standard_Integer From,const Standard_Integer To) const 
222 {
223    if ( From <= 0 || From > Length() || 
224         To <= 0 || To > Length() || To < From ) Standard_OutOfRange::Raise();
225 #ifndef OBJS
226    Handle (PCollection_HSequence) SubSeq = new PCollection_HSequence;
227 #else
228    Handle (PCollection_HSequence) SubSeq = new (os_segment::of(this)) PCollection_HSequence;
229 #endif
230    for(Standard_Integer i = From ; i <= To; i++)
231         SubSeq->Append(Value(i));
232    return SubSeq;
233 }
234
235 // ---------------------------------------------
236 // Split : Split a sequence in two sub-sequences
237 // ---------------------------------------------
238 Handle (PCollection_HSequence) 
239             PCollection_HSequence::Split(const Standard_Integer Index)
240 {
241    Standard_Integer i ;
242    if ( Index <= 0 || Index > Length() ) Standard_OutOfRange::Raise();
243
244 // construct the new sequence
245 #ifndef OBJS
246    Handle(PCollection_HSequence) Seq = new PCollection_HSequence;
247 #else
248    Handle(PCollection_HSequence) Seq = new (os_segment::of(this)) PCollection_HSequence;
249 #endif
250    for (i = Index ; i<= Size; i++)
251         Seq->Append(Value(i));
252
253 // Update the old sequence
254    if (Index == 1 ) {
255      Clear();
256      return Seq;
257    }
258 // Index research
259    i = 1;
260    Handle(PCollection_SeqNode) cell = FirstItem;
261    while (i != Index-1)  {
262      cell = cell->Next();             
263      ++i;
264    }
265 // Re-build the Sequence     
266    Handle(PCollection_SeqNode) pnul;
267    pnul.Nullify(); 
268    LastItem = cell;
269    LastItem->SetNext(pnul);
270    Size = Index - 1 ;
271    return Seq;
272 }
273
274 // ----------------------------------------------------------
275 // SetValue : Change the element of a given index in a sequence
276 // ----------------------------------------------------------
277 void PCollection_HSequence::SetValue(const Standard_Integer Index, 
278                                    const Item& T)
279 {
280    if (Index <= 0 || Index > Length()) Standard_OutOfRange::Raise();
281
282 // Index research
283    Standard_Integer i = 1;
284    Handle(PCollection_SeqNode) cell = FirstItem;
285    while (i != Index )  {
286      cell = cell->Next();
287      ++i;
288    }
289 // Change the value of the node
290    cell->SetValue(T);
291 }
292
293 // -----------------------------------------
294 // Value : Return the value of a given index
295 // -----------------------------------------
296 Item PCollection_HSequence::Value(const Standard_Integer Index) const 
297 {
298    if (Index <= 0 || Index > Length()) Standard_OutOfRange::Raise();
299 // Index research
300    Standard_Integer i = 1;
301    Handle(PCollection_SeqNode) cell = FirstItem;
302    while (i != Index )  {
303      cell = cell->Next();
304      ++i;
305    }
306 // returns the value of the node
307    return cell->Value();
308 }
309
310 // ----------------------------------------------------------------
311 // Contains : Returns True if the sequence contains a given element
312 // ----------------------------------------------------------------
313 //Standard_Boolean PCollection_HSequence::Contains(const Item& T) const 
314 Standard_Boolean PCollection_HSequence::Contains(const Item& ) const 
315 {
316   Standard_ProgramError::Raise("PCollection_HSequence::Contains : Obsolete method...");
317   return Standard_False;
318 }
319
320 // -------------------------------------------------------------
321 // Location : returns the index of the nth occurence of an item.
322 // -------------------------------------------------------------
323 //Standard_Integer PCollection_HSequence::Location(const Standard_Integer N,
324 //                                               const Item& T,
325 //                                               const Standard_Integer From, 
326 //                                               const Standard_Integer To) const
327 Standard_Integer PCollection_HSequence::Location(const Standard_Integer ,
328                                                const Item& ,
329                                                const Standard_Integer , 
330                                                const Standard_Integer ) const
331 {
332   Standard_ProgramError::Raise("PCollection_HSequence::Location : Obsolete method...");
333   return 0;
334 }
335
336 // -------------------------------------------------------------
337 // Location : returns the index of the nth occurence of an item.
338 // -------------------------------------------------------------
339 //Standard_Integer PCollection_HSequence::
340 //              Location(const Standard_Integer N,const Item& T) const 
341 Standard_Integer PCollection_HSequence::
342               Location(const Standard_Integer ,const Item& ) const 
343 {
344   Standard_ProgramError::Raise("PCollection_HSequence::Location : Obsolete method...");
345   return 0;
346 }
347
348 // -------------------------------------
349 // Remove : Remove an item in a sequence
350 // -------------------------------------
351 void PCollection_HSequence::Remove(const Standard_Integer Index)
352 {
353    if (Index <= 0 || Index > Size ) Standard_OutOfRange::Raise();
354    if (Size == 1)  { 
355       Size = 0;
356       FirstItem.Nullify();
357 #ifndef CSFDB
358       LastItem.Delete();          // free memory
359 #endif
360    } 
361    else {
362       Handle(PCollection_SeqNode) pnul,cell,previous,next;
363       pnul.Nullify();
364       if ( Index == 1 ) {                          // Remove the first Index
365          cell = FirstItem;  
366          FirstItem = FirstItem->Next();
367          FirstItem->SetPrevious(pnul);
368 #ifndef CSFDB
369          cell.Delete();                           // free memory
370 #endif
371          --Size;
372       } else if ( Index == Size ) {                // Remove the last Index
373          cell = LastItem;
374          LastItem = LastItem->Previous();
375          LastItem->SetNext(pnul);
376 #ifndef CSFDB
377          cell.Delete();                           // free memory
378 #endif
379          --Size;
380       } else {
381         Standard_Integer i = 1;
382         cell = FirstItem;
383         while (i != Index)  {
384            cell = cell->Next();             
385            ++i;
386         } 
387         previous = cell->Previous();
388         next = cell->Next();
389         previous->SetNext(next);
390         next->SetPrevious(previous);    
391 #ifndef CSFDB
392         cell.Delete();                           // free memory
393 #endif
394         --Size;
395       }
396    }
397 }
398
399 // ---------------------
400 // Remove a set of items
401 // --------------------- 
402 void PCollection_HSequence::Remove(const Standard_Integer From,const Standard_Integer To)
403 {
404    if (From <= 0 || From > Size || To <= 0 || To > Size || From > To )
405                                        Standard_OutOfRange::Raise(); 
406    for (Standard_Integer i = From; i<= To; i++) Remove(From);
407 }
408
409 // ---------------------------------------------------
410 // First : Returns the first element of the sequence
411 //         Raises an exeption if the sequence is empty
412 // ----------------------------------------------------
413 Item PCollection_HSequence::First() const 
414 {
415    if (Size == 0) Standard_NoSuchObject::Raise();
416    return FirstItem->Value();
417 }
418
419 // ----------------------------------------------------
420 // Last : Returns the last element of the sequence
421 //         Raises an exeption if the sequence is empty
422 // ----------------------------------------------------
423 Item PCollection_HSequence::Last() const 
424 {
425   if (Size == 0) Standard_NoSuchObject::Raise();
426   return LastItem->Value();
427 }
428
429 // IsEmpty : Returns Standard_True if the sequence is empty (i.e. Size = 0)
430 Standard_Boolean PCollection_HSequence::IsEmpty() const 
431 {
432   return (Size == 0);
433 }
434
435 // Length : Returns the length of the sequence
436 Standard_Integer PCollection_HSequence::Length() const 
437 {
438   return Size;
439 }
440
441 // GetFirst : Returns the field "FirstItem"
442 Handle(PCollection_SeqNode) PCollection_HSequence::GetFirst() const 
443 {
444   return FirstItem;
445 }
446
447 // GetLast : Returns the field "LastItem"
448 Handle(PCollection_SeqNode) PCollection_HSequence::GetLast() const 
449 {
450   return LastItem;
451 }
452
453 void PCollection_HSequence::Destroy()
454 {
455 #ifdef CSFDB
456   Clear();
457 #endif
458 }
459
460
461
462         
463         
464
465