1 // Created on: 2002-03-28
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2002-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
20 #ifndef NCollection_Sequence_HeaderFile
21 #define NCollection_Sequence_HeaderFile
23 #include <NCollection_BaseCollection.hxx>
24 #include <NCollection_BaseSequence.hxx>
27 #include <Standard_OutOfRange.hxx>
28 #include <Standard_NoSuchObject.hxx>
32 * Purpose: Definition of a sequence of elements indexed by
33 * an Integer in range of 1..n
35 template <class TheItemType> class NCollection_Sequence
36 : public NCollection_BaseCollection<TheItemType>,
37 public NCollection_BaseSequence
41 //! Class defining sequence node - for internal use by Sequence
42 class Node : public NCollection_SeqNode
46 Node (const TheItemType& theItem) :
47 NCollection_SeqNode ()
48 { myValue = theItem; }
49 //! Constant value access
50 const TheItemType& Value () const { return myValue; }
51 //! Variable value access
52 TheItemType& ChangeValue () { return myValue; }
55 DEFINE_NCOLLECTION_ALLOC
59 }; // End of nested class Node
62 //! Implementation of the Iterator interface.
63 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
64 public NCollection_BaseSequence::Iterator
67 //! Empty constructor - for later Init
69 //! Constructor with initialisation
70 Iterator (const NCollection_Sequence& theSeq,
71 const Standard_Boolean isStart = Standard_True)
72 : NCollection_BaseSequence::Iterator (theSeq, isStart) {}
74 Iterator& operator= (const Iterator& theIt)
76 NCollection_BaseSequence::Iterator& me = * this;
81 virtual Standard_Boolean More (void) const
82 { return (myCurrent!=NULL); }
84 virtual void Next (void)
85 { if (myCurrent) myCurrent = (NCollection_SeqNode *) myCurrent->Next(); }
86 //! Constant value access
87 virtual const TheItemType& Value (void) const
88 { return ((const Node *)myCurrent)->Value(); }
89 //! Variable value access
90 virtual TheItemType& ChangeValue (void) const
91 { return ((Node *)myCurrent)->ChangeValue(); }
92 }; // End of nested class Iterator
95 // ---------- PUBLIC METHODS ------------
98 NCollection_Sequence(const Handle(NCollection_BaseAllocator)& theAllocator=0L)
99 : NCollection_BaseCollection<TheItemType>(theAllocator),
100 NCollection_BaseSequence() {}
103 NCollection_Sequence (const NCollection_Sequence& theOther) :
104 NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
105 NCollection_BaseSequence()
106 { *this = theOther; }
109 virtual Standard_Integer Size (void) const
113 Standard_Integer Length (void) const
116 //! Method for consistency with other collections.
117 //! @return Lower bound (inclusive) for iteration.
118 Standard_Integer Lower() const
123 //! Method for consistency with other collections.
124 //! @return Upper bound (inclusive) for iteration.
125 Standard_Integer Upper() const
131 Standard_Boolean IsEmpty (void) const
132 { return (mySize==0); }
138 //! Exchange two members
139 void Exchange (const Standard_Integer I,
140 const Standard_Integer J )
143 //! Static deleter to be passed to BaseSequence
144 static void delNode (NCollection_SeqNode * theNode,
145 Handle(NCollection_BaseAllocator)& theAl)
147 ((Node *) theNode)->~Node();
148 theAl->Free(theNode);
151 //! Clear the items out, take a new allocator if non null
152 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
154 ClearSeq (delNode, this->myAllocator);
155 if (!theAllocator.IsNull())
156 this->myAllocator = theAllocator;
159 //! Replace this sequence by the items of theOther
160 NCollection_Sequence& operator= (const NCollection_Sequence& theOther)
162 if (this == &theOther)
164 Clear (theOther.myAllocator);
165 Node * pCur = (Node *) theOther.myFirstItem;
167 Node* pNew = new (this->myAllocator) Node (pCur->Value());
169 pCur = (Node *) pCur->Next();
174 //! Replace this sequence by the items of theOther collection
175 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
177 if (this == &theOther)
180 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
181 theOther.CreateIterator();
182 for (; anIter.More(); anIter.Next())
183 Append(anIter.Value());
187 void Remove (Iterator& thePosition)
188 { RemoveSeq (thePosition, delNode, this->myAllocator); }
191 void Remove (const Standard_Integer theIndex)
192 { RemoveSeq (theIndex, delNode, this->myAllocator); }
194 //! Remove range of items
195 void Remove (const Standard_Integer theFromIndex,
196 const Standard_Integer theToIndex)
197 { RemoveSeq (theFromIndex, theToIndex, delNode, this->myAllocator); }
200 void Append (const TheItemType& theItem)
201 { PAppend (new (this->myAllocator) Node (theItem)); }
203 //! Append another sequence (making it empty)
204 void Append (NCollection_Sequence& theSeq)
206 if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
211 void Prepend (const TheItemType& theItem)
212 { PPrepend (new (this->myAllocator) Node (theItem)); }
214 //! Prepend another sequence (making it empty)
215 void Prepend (NCollection_Sequence& theSeq)
217 if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
221 //! InsertBefore theIndex theItem
222 void InsertBefore (const Standard_Integer theIndex,
223 const TheItemType& theItem)
224 { InsertAfter (theIndex-1, theItem); }
226 //! InsertBefore theIndex another sequence
227 void InsertBefore (const Standard_Integer theIndex,
228 NCollection_Sequence& theSeq)
229 { InsertAfter (theIndex-1, theSeq); }
231 //! InsertAfter the position of iterator
232 void InsertAfter (Iterator& thePosition,
233 const TheItemType& theItem)
234 { PInsertAfter (thePosition, new (this->myAllocator) Node (theItem)); }
236 //! InsertAfter theIndex theItem
237 void InsertAfter (const Standard_Integer theIndex,
238 NCollection_Sequence& theSeq)
239 { PInsertAfter (theIndex, theSeq); }
241 //! InsertAfter theIndex another sequence
242 void InsertAfter (const Standard_Integer theIndex,
243 const TheItemType& theItem)
245 #if !defined No_Exception && !defined No_Standard_OutOfRange
246 if (theIndex < 0 || theIndex > mySize)
247 Standard_OutOfRange::Raise ("NCollection_Sequence::InsertAfter");
249 PInsertAfter (theIndex, new (this->myAllocator) Node (theItem));
252 //! Split in two sequences
253 void Split (const Standard_Integer theIndex, NCollection_Sequence& theSeq)
255 theSeq.Clear (this->myAllocator);
256 PSplit (theIndex, theSeq);
259 //! First item access
260 const TheItemType& First () const
262 #if !defined No_Exception && !defined No_Standard_NoSuchObject
264 Standard_NoSuchObject::Raise ("NCollection_Sequence::First");
266 return ((const Node *) myFirstItem) -> Value();
269 //! First item access
270 TheItemType& ChangeFirst()
272 #if !defined No_Exception && !defined No_Standard_NoSuchObject
274 Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeFirst");
276 return ((Node* )myFirstItem)->ChangeValue();
280 const TheItemType& Last () const
282 #if !defined No_Exception && !defined No_Standard_NoSuchObject
284 Standard_NoSuchObject::Raise ("NCollection_Sequence::Last");
286 return ((const Node *) myLastItem) -> Value();
290 TheItemType& ChangeLast()
292 #if !defined No_Exception && !defined No_Standard_NoSuchObject
294 Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeLast");
296 return ((Node* )myLastItem)->ChangeValue();
299 //! Constant item access by theIndex
300 const TheItemType& Value (const Standard_Integer theIndex) const
302 #if !defined No_Exception && !defined No_Standard_OutOfRange
303 if (theIndex <= 0 || theIndex > mySize)
304 Standard_OutOfRange::Raise ("NCollection_Sequence::Value");
306 NCollection_Sequence * const aLocalTHIS = (NCollection_Sequence *) this;
307 aLocalTHIS -> myCurrentItem = Find (theIndex);
308 aLocalTHIS -> myCurrentIndex = theIndex;
309 return ((const Node *) myCurrentItem) -> Value();
312 //! Constant operator()
313 const TheItemType& operator() (const Standard_Integer theIndex) const
314 { return Value(theIndex); }
316 //! Variable item access by theIndex
317 TheItemType& ChangeValue (const Standard_Integer theIndex)
319 #if !defined No_Exception && !defined No_Standard_OutOfRange
320 if (theIndex <= 0 || theIndex > mySize)
321 Standard_OutOfRange::Raise ("NCollection_Sequence::ChangeValue");
323 myCurrentItem = Find (theIndex);
324 myCurrentIndex = theIndex;
325 return ((Node *) myCurrentItem) -> ChangeValue();
328 //! Variable operator()
329 TheItemType& operator() (const Standard_Integer theIndex)
330 { return ChangeValue(theIndex); }
332 //! Set item value by theIndex
333 void SetValue (const Standard_Integer theIndex,
334 const TheItemType& theItem)
335 { ChangeValue (theIndex) = theItem; }
337 // ******** Destructor - clears the Sequence
338 ~NCollection_Sequence (void)
343 // ----------- PRIVATE METHODS -----------
345 //! Creates Iterator for use on BaseCollection
346 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
347 CreateIterator(void) const
348 { return *(new (this->IterAllocator()) Iterator(*this)); }
350 // ---------- FRIEND CLASSES ------------
351 friend class Iterator;