0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / NCollection / NCollection_Sequence.hxx
CommitLineData
b311480e 1// Created on: 2002-03-28
2// Created by: Alexander GRIGORIEV
973c2be1 3// Copyright (c) 2002-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
7fd59977 16#ifndef NCollection_Sequence_HeaderFile
17#define NCollection_Sequence_HeaderFile
18
7fd59977 19#include <NCollection_BaseSequence.hxx>
79a35943 20#include <NCollection_StlIterator.hxx>
7fd59977 21
7fd59977 22#include <Standard_OutOfRange.hxx>
23#include <Standard_NoSuchObject.hxx>
7fd59977 24
7fd59977 25/**
26 * Purpose: Definition of a sequence of elements indexed by
27 * an Integer in range of 1..n
28 */
ddf2fe8e 29template <class TheItemType>
30class NCollection_Sequence : public NCollection_BaseSequence
7fd59977 31{
79a35943 32public:
33 //! STL-compliant typedef for value type
34 typedef TheItemType value_type;
7fd59977 35
79a35943 36public:
7fd59977 37 //! Class defining sequence node - for internal use by Sequence
38 class Node : public NCollection_SeqNode
39 {
40 public:
41 //! Constructor
42 Node (const TheItemType& theItem) :
43 NCollection_SeqNode ()
44 { myValue = theItem; }
45 //! Constant value access
46 const TheItemType& Value () const { return myValue; }
47 //! Variable value access
48 TheItemType& ChangeValue () { return myValue; }
7fd59977 49
50 private:
51 TheItemType myValue;
52 }; // End of nested class Node
53
54 public:
55 //! Implementation of the Iterator interface.
ddf2fe8e 56 class Iterator : public NCollection_BaseSequence::Iterator
7fd59977 57 {
58 public:
59 //! Empty constructor - for later Init
60 Iterator (void) {}
61 //! Constructor with initialisation
62 Iterator (const NCollection_Sequence& theSeq,
63 const Standard_Boolean isStart = Standard_True)
64 : NCollection_BaseSequence::Iterator (theSeq, isStart) {}
7fd59977 65 //! Check end
ddf2fe8e 66 Standard_Boolean More (void) const
7fd59977 67 { return (myCurrent!=NULL); }
68 //! Make step
ddf2fe8e 69 void Next (void)
79a35943 70 {
71 if (myCurrent)
72 {
73 myPrevious = myCurrent;
74 myCurrent = myCurrent->Next();
75 }
76 }
7fd59977 77 //! Constant value access
ddf2fe8e 78 const TheItemType& Value (void) const
7fd59977 79 { return ((const Node *)myCurrent)->Value(); }
80 //! Variable value access
ddf2fe8e 81 TheItemType& ChangeValue (void) const
7fd59977 82 { return ((Node *)myCurrent)->ChangeValue(); }
79a35943 83 //! Performs comparison of two iterators.
ddf2fe8e 84 Standard_Boolean IsEqual (const Iterator& theOther) const
79a35943 85 {
86 return myCurrent == theOther.myCurrent;
87 }
7fd59977 88 }; // End of nested class Iterator
89
79a35943 90 //! Shorthand for a regular iterator type.
91 typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, false> iterator;
92
93 //! Shorthand for a constant iterator type.
94 typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, true> const_iterator;
95
96 //! Returns an iterator pointing to the first element in the sequence.
97 iterator begin() const { return Iterator (*this, true); }
98
99 //! Returns an iterator referring to the past-the-end element in the sequence.
100 iterator end() const { Iterator anIter (*this, false); anIter.Next(); return anIter; }
101
102 //! Returns a const iterator pointing to the first element in the sequence.
103 const_iterator cbegin() const { return Iterator (*this, true); }
104
105 //! Returns a const iterator referring to the past-the-end element in the sequence.
106 const_iterator cend() const { Iterator anIter (*this, false); anIter.Next(); return anIter; }
107
7fd59977 108 public:
109 // ---------- PUBLIC METHODS ------------
110
b6a0525b 111 //! Empty constructor.
112 NCollection_Sequence() : NCollection_BaseSequence(Handle(NCollection_BaseAllocator)()) {}
113
7fd59977 114 //! Constructor
b6a0525b 115 explicit NCollection_Sequence (const Handle(NCollection_BaseAllocator)& theAllocator) : NCollection_BaseSequence(theAllocator) {}
7fd59977 116
117 //! Copy constructor
118 NCollection_Sequence (const NCollection_Sequence& theOther) :
ddf2fe8e 119 NCollection_BaseSequence(theOther.myAllocator)
120 {
121 Assign (theOther);
122 }
7fd59977 123
124 //! Number of items
ddf2fe8e 125 Standard_Integer Size (void) const
7fd59977 126 { return mySize; }
127
128 //! Number of items
129 Standard_Integer Length (void) const
130 { return mySize; }
131
a174a3c5 132 //! Method for consistency with other collections.
133 //! @return Lower bound (inclusive) for iteration.
134 Standard_Integer Lower() const
135 {
136 return 1;
137 }
138
139 //! Method for consistency with other collections.
140 //! @return Upper bound (inclusive) for iteration.
141 Standard_Integer Upper() const
142 {
143 return mySize;
144 }
145
7fd59977 146 //! Empty query
147 Standard_Boolean IsEmpty (void) const
148 { return (mySize==0); }
149
150 //! Reverse sequence
151 void Reverse (void)
152 { PReverse(); }
153
154 //! Exchange two members
155 void Exchange (const Standard_Integer I,
156 const Standard_Integer J )
157 { PExchange(I, J); }
158
159 //! Static deleter to be passed to BaseSequence
160 static void delNode (NCollection_SeqNode * theNode,
161 Handle(NCollection_BaseAllocator)& theAl)
162 {
163 ((Node *) theNode)->~Node();
164 theAl->Free(theNode);
165 }
166
167 //! Clear the items out, take a new allocator if non null
168 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
169 {
ddf2fe8e 170 ClearSeq (delNode);
7fd59977 171 if (!theAllocator.IsNull())
172 this->myAllocator = theAllocator;
173 }
174
5e452c37 175 //! Replace this sequence by the items of theOther.
176 //! This method does not change the internal allocator.
ddf2fe8e 177 NCollection_Sequence& Assign (const NCollection_Sequence& theOther)
7fd59977 178 {
395a5977 179 if (this != &theOther)
180 {
181 Clear();
182 appendSeq((const Node *)theOther.myFirstItem);
7fd59977 183 }
184 return * this;
185 }
186
ddf2fe8e 187 //! Replacement operator
188 NCollection_Sequence& operator= (const NCollection_Sequence& theOther)
7fd59977 189 {
ddf2fe8e 190 return Assign (theOther);
7fd59977 191 }
192
193 //! Remove one item
194 void Remove (Iterator& thePosition)
ddf2fe8e 195 { RemoveSeq (thePosition, delNode); }
7fd59977 196
197 //! Remove one item
198 void Remove (const Standard_Integer theIndex)
ddf2fe8e 199 { RemoveSeq (theIndex, delNode); }
7fd59977 200
201 //! Remove range of items
202 void Remove (const Standard_Integer theFromIndex,
203 const Standard_Integer theToIndex)
ddf2fe8e 204 { RemoveSeq (theFromIndex, theToIndex, delNode); }
7fd59977 205
206 //! Append one item
207 void Append (const TheItemType& theItem)
208 { PAppend (new (this->myAllocator) Node (theItem)); }
209
210 //! Append another sequence (making it empty)
211 void Append (NCollection_Sequence& theSeq)
212 {
395a5977 213 if (this == &theSeq || theSeq.IsEmpty())
214 return;
215 if (this->myAllocator == theSeq.myAllocator)
216 {
217 // Then we take the sequence and glue it to our end -
218 // deallocation will bring no problem
219 PAppend(theSeq);
220 }
221 else
222 {
223 // No - this sequence has different memory scope
224 appendSeq((const Node *)theSeq.myFirstItem);
225 theSeq.Clear();
226 }
7fd59977 227 }
228
229 //! Prepend one item
230 void Prepend (const TheItemType& theItem)
231 { PPrepend (new (this->myAllocator) Node (theItem)); }
232
233 //! Prepend another sequence (making it empty)
234 void Prepend (NCollection_Sequence& theSeq)
235 {
395a5977 236 if (this == &theSeq || theSeq.IsEmpty())
237 return;
238 if (this->myAllocator == theSeq.myAllocator)
239 {
240 // Then we take the sequence and glue it to our head -
241 // deallocation will bring no problem
242 PPrepend(theSeq);
243 }
244 else
245 {
246 // No - this sequence has different memory scope
247 prependSeq((const Node *)theSeq.myFirstItem, 1);
248 theSeq.Clear();
249 }
7fd59977 250 }
251
252 //! InsertBefore theIndex theItem
253 void InsertBefore (const Standard_Integer theIndex,
254 const TheItemType& theItem)
255 { InsertAfter (theIndex-1, theItem); }
256
395a5977 257 //! InsertBefore theIndex another sequence (making it empty)
7fd59977 258 void InsertBefore (const Standard_Integer theIndex,
259 NCollection_Sequence& theSeq)
260 { InsertAfter (theIndex-1, theSeq); }
261
262 //! InsertAfter the position of iterator
263 void InsertAfter (Iterator& thePosition,
264 const TheItemType& theItem)
265 { PInsertAfter (thePosition, new (this->myAllocator) Node (theItem)); }
266
395a5977 267 //! InsertAfter theIndex another sequence (making it empty)
7fd59977 268 void InsertAfter (const Standard_Integer theIndex,
269 NCollection_Sequence& theSeq)
395a5977 270 {
271 if (this == &theSeq || theSeq.IsEmpty())
272 return;
273 if (this->myAllocator == theSeq.myAllocator)
274 {
275 // Then we take the list and glue it to our head -
276 // deallocation will bring no problem
277 PInsertAfter(theIndex, theSeq);
278 }
279 else
280 {
281 // No - this sequence has different memory scope
282 prependSeq((const Node *)theSeq.myFirstItem, theIndex + 1);
283 theSeq.Clear();
284 }
285 }
7fd59977 286
395a5977 287 //! InsertAfter theIndex theItem
7fd59977 288 void InsertAfter (const Standard_Integer theIndex,
289 const TheItemType& theItem)
290 {
e3a6386d 291 Standard_OutOfRange_Raise_if (theIndex < 0 || theIndex > mySize, "NCollection_Sequence::InsertAfter");
7fd59977 292 PInsertAfter (theIndex, new (this->myAllocator) Node (theItem));
293 }
294
295 //! Split in two sequences
296 void Split (const Standard_Integer theIndex, NCollection_Sequence& theSeq)
297 {
298 theSeq.Clear (this->myAllocator);
299 PSplit (theIndex, theSeq);
300 }
301
302 //! First item access
303 const TheItemType& First () const
304 {
e3a6386d 305 Standard_NoSuchObject_Raise_if (mySize == 0, "NCollection_Sequence::First");
7fd59977 306 return ((const Node *) myFirstItem) -> Value();
307 }
308
a174a3c5 309 //! First item access
310 TheItemType& ChangeFirst()
311 {
e3a6386d 312 Standard_NoSuchObject_Raise_if (mySize == 0, "NCollection_Sequence::ChangeFirst");
a174a3c5 313 return ((Node* )myFirstItem)->ChangeValue();
314 }
315
7fd59977 316 //! Last item access
317 const TheItemType& Last () const
318 {
e3a6386d 319 Standard_NoSuchObject_Raise_if (mySize == 0, "NCollection_Sequence::Last");
7fd59977 320 return ((const Node *) myLastItem) -> Value();
321 }
322
a174a3c5 323 //! Last item access
324 TheItemType& ChangeLast()
325 {
e3a6386d 326 Standard_NoSuchObject_Raise_if (mySize == 0, "NCollection_Sequence::ChangeLast");
a174a3c5 327 return ((Node* )myLastItem)->ChangeValue();
328 }
329
7fd59977 330 //! Constant item access by theIndex
331 const TheItemType& Value (const Standard_Integer theIndex) const
332 {
e3a6386d 333 Standard_OutOfRange_Raise_if (theIndex <= 0 || theIndex > mySize, "NCollection_Sequence::Value");
334
7fd59977 335 NCollection_Sequence * const aLocalTHIS = (NCollection_Sequence *) this;
336 aLocalTHIS -> myCurrentItem = Find (theIndex);
337 aLocalTHIS -> myCurrentIndex = theIndex;
338 return ((const Node *) myCurrentItem) -> Value();
339 }
340
341 //! Constant operator()
342 const TheItemType& operator() (const Standard_Integer theIndex) const
343 { return Value(theIndex); }
344
345 //! Variable item access by theIndex
346 TheItemType& ChangeValue (const Standard_Integer theIndex)
347 {
e3a6386d 348 Standard_OutOfRange_Raise_if (theIndex <= 0 || theIndex > mySize, "NCollection_Sequence::ChangeValue");
349
7fd59977 350 myCurrentItem = Find (theIndex);
351 myCurrentIndex = theIndex;
352 return ((Node *) myCurrentItem) -> ChangeValue();
353 }
354
355 //! Variable operator()
356 TheItemType& operator() (const Standard_Integer theIndex)
357 { return ChangeValue(theIndex); }
358
359 //! Set item value by theIndex
360 void SetValue (const Standard_Integer theIndex,
361 const TheItemType& theItem)
362 { ChangeValue (theIndex) = theItem; }
363
364 // ******** Destructor - clears the Sequence
6928e351 365 virtual ~NCollection_Sequence (void)
7fd59977 366 { Clear(); }
367
7fd59977 368 private:
7fd59977 369
370 // ---------- FRIEND CLASSES ------------
371 friend class Iterator;
372
395a5977 373 // ----------- PRIVATE METHODS -----------
374
375 //! append the sequence headed by the given Node
376 void appendSeq(const Node * pCur)
377 {
378 while (pCur)
379 {
380 Node* pNew = new (this->myAllocator) Node(pCur->Value());
381 PAppend(pNew);
382 pCur = (const Node *)pCur->Next();
383 }
384 }
385
386 //! insert the sequence headed by the given Node before the item with the given index
387 void prependSeq(const Node * pCur, Standard_Integer ind)
388 {
389 ind--;
390 while (pCur)
391 {
392 Node* pNew = new (this->myAllocator) Node(pCur->Value());
393 PInsertAfter(ind++, pNew);
394 pCur = (const Node *)pCur->Next();
395 }
396 }
397
7fd59977 398};
399
7fd59977 400#endif