1 // Created on: 2002-03-28
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #ifndef NCollection_Sequence_HeaderFile
17 #define NCollection_Sequence_HeaderFile
19 #include <NCollection_BaseCollection.hxx>
20 #include <NCollection_BaseSequence.hxx>
21 #include <NCollection_StlIterator.hxx>
24 #include <Standard_OutOfRange.hxx>
25 #include <Standard_NoSuchObject.hxx>
29 * Purpose: Definition of a sequence of elements indexed by
30 * an Integer in range of 1..n
32 template <class TheItemType> class NCollection_Sequence
33 : public NCollection_BaseCollection<TheItemType>,
34 public NCollection_BaseSequence
37 //! STL-compliant typedef for value type
38 typedef TheItemType value_type;
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)
88 myPrevious = myCurrent;
89 myCurrent = myCurrent->Next();
92 //! Constant value access
93 virtual const TheItemType& Value (void) const
94 { return ((const Node *)myCurrent)->Value(); }
95 //! Variable value access
96 virtual TheItemType& ChangeValue (void) const
97 { return ((Node *)myCurrent)->ChangeValue(); }
98 //! Performs comparison of two iterators.
99 virtual Standard_Boolean IsEqual (const Iterator& theOther) const
101 return myCurrent == theOther.myCurrent;
103 }; // End of nested class Iterator
105 //! Shorthand for a regular iterator type.
106 typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, false> iterator;
108 //! Shorthand for a constant iterator type.
109 typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, true> const_iterator;
111 //! Returns an iterator pointing to the first element in the sequence.
112 iterator begin() const { return Iterator (*this, true); }
114 //! Returns an iterator referring to the past-the-end element in the sequence.
115 iterator end() const { Iterator anIter (*this, false); anIter.Next(); return anIter; }
117 //! Returns a const iterator pointing to the first element in the sequence.
118 const_iterator cbegin() const { return Iterator (*this, true); }
120 //! Returns a const iterator referring to the past-the-end element in the sequence.
121 const_iterator cend() const { Iterator anIter (*this, false); anIter.Next(); return anIter; }
124 // ---------- PUBLIC METHODS ------------
127 NCollection_Sequence(const Handle(NCollection_BaseAllocator)& theAllocator=0L)
128 : NCollection_BaseCollection<TheItemType>(theAllocator),
129 NCollection_BaseSequence() {}
132 NCollection_Sequence (const NCollection_Sequence& theOther) :
133 NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
134 NCollection_BaseSequence()
135 { *this = theOther; }
138 virtual Standard_Integer Size (void) const
142 Standard_Integer Length (void) const
145 //! Method for consistency with other collections.
146 //! @return Lower bound (inclusive) for iteration.
147 Standard_Integer Lower() const
152 //! Method for consistency with other collections.
153 //! @return Upper bound (inclusive) for iteration.
154 Standard_Integer Upper() const
160 Standard_Boolean IsEmpty (void) const
161 { return (mySize==0); }
167 //! Exchange two members
168 void Exchange (const Standard_Integer I,
169 const Standard_Integer J )
172 //! Static deleter to be passed to BaseSequence
173 static void delNode (NCollection_SeqNode * theNode,
174 Handle(NCollection_BaseAllocator)& theAl)
176 ((Node *) theNode)->~Node();
177 theAl->Free(theNode);
180 //! Clear the items out, take a new allocator if non null
181 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
183 ClearSeq (delNode, this->myAllocator);
184 if (!theAllocator.IsNull())
185 this->myAllocator = theAllocator;
188 //! Replace this sequence by the items of theOther
189 NCollection_Sequence& operator= (const NCollection_Sequence& theOther)
191 if (this == &theOther)
193 Clear (theOther.myAllocator);
194 Node * pCur = (Node *) theOther.myFirstItem;
196 Node* pNew = new (this->myAllocator) Node (pCur->Value());
198 pCur = (Node *) pCur->Next();
203 //! Replace this sequence by the items of theOther collection
204 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
206 if (this == &theOther)
209 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
210 theOther.CreateIterator();
211 for (; anIter.More(); anIter.Next())
212 Append(anIter.Value());
216 void Remove (Iterator& thePosition)
217 { RemoveSeq (thePosition, delNode, this->myAllocator); }
220 void Remove (const Standard_Integer theIndex)
221 { RemoveSeq (theIndex, delNode, this->myAllocator); }
223 //! Remove range of items
224 void Remove (const Standard_Integer theFromIndex,
225 const Standard_Integer theToIndex)
226 { RemoveSeq (theFromIndex, theToIndex, delNode, this->myAllocator); }
229 void Append (const TheItemType& theItem)
230 { PAppend (new (this->myAllocator) Node (theItem)); }
232 //! Append another sequence (making it empty)
233 void Append (NCollection_Sequence& theSeq)
235 if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
240 void Prepend (const TheItemType& theItem)
241 { PPrepend (new (this->myAllocator) Node (theItem)); }
243 //! Prepend another sequence (making it empty)
244 void Prepend (NCollection_Sequence& theSeq)
246 if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
250 //! InsertBefore theIndex theItem
251 void InsertBefore (const Standard_Integer theIndex,
252 const TheItemType& theItem)
253 { InsertAfter (theIndex-1, theItem); }
255 //! InsertBefore theIndex another sequence
256 void InsertBefore (const Standard_Integer theIndex,
257 NCollection_Sequence& theSeq)
258 { InsertAfter (theIndex-1, theSeq); }
260 //! InsertAfter the position of iterator
261 void InsertAfter (Iterator& thePosition,
262 const TheItemType& theItem)
263 { PInsertAfter (thePosition, new (this->myAllocator) Node (theItem)); }
265 //! InsertAfter theIndex theItem
266 void InsertAfter (const Standard_Integer theIndex,
267 NCollection_Sequence& theSeq)
268 { PInsertAfter (theIndex, theSeq); }
270 //! InsertAfter theIndex another sequence
271 void InsertAfter (const Standard_Integer theIndex,
272 const TheItemType& theItem)
274 #if !defined No_Exception && !defined No_Standard_OutOfRange
275 if (theIndex < 0 || theIndex > mySize)
276 Standard_OutOfRange::Raise ("NCollection_Sequence::InsertAfter");
278 PInsertAfter (theIndex, new (this->myAllocator) Node (theItem));
281 //! Split in two sequences
282 void Split (const Standard_Integer theIndex, NCollection_Sequence& theSeq)
284 theSeq.Clear (this->myAllocator);
285 PSplit (theIndex, theSeq);
288 //! First item access
289 const TheItemType& First () const
291 #if !defined No_Exception && !defined No_Standard_NoSuchObject
293 Standard_NoSuchObject::Raise ("NCollection_Sequence::First");
295 return ((const Node *) myFirstItem) -> Value();
298 //! First item access
299 TheItemType& ChangeFirst()
301 #if !defined No_Exception && !defined No_Standard_NoSuchObject
303 Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeFirst");
305 return ((Node* )myFirstItem)->ChangeValue();
309 const TheItemType& Last () const
311 #if !defined No_Exception && !defined No_Standard_NoSuchObject
313 Standard_NoSuchObject::Raise ("NCollection_Sequence::Last");
315 return ((const Node *) myLastItem) -> Value();
319 TheItemType& ChangeLast()
321 #if !defined No_Exception && !defined No_Standard_NoSuchObject
323 Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeLast");
325 return ((Node* )myLastItem)->ChangeValue();
328 //! Constant item access by theIndex
329 const TheItemType& Value (const Standard_Integer theIndex) const
331 #if !defined No_Exception && !defined No_Standard_OutOfRange
332 if (theIndex <= 0 || theIndex > mySize)
333 Standard_OutOfRange::Raise ("NCollection_Sequence::Value");
335 NCollection_Sequence * const aLocalTHIS = (NCollection_Sequence *) this;
336 aLocalTHIS -> myCurrentItem = Find (theIndex);
337 aLocalTHIS -> myCurrentIndex = theIndex;
338 return ((const Node *) myCurrentItem) -> Value();
341 //! Constant operator()
342 const TheItemType& operator() (const Standard_Integer theIndex) const
343 { return Value(theIndex); }
345 //! Variable item access by theIndex
346 TheItemType& ChangeValue (const Standard_Integer theIndex)
348 #if !defined No_Exception && !defined No_Standard_OutOfRange
349 if (theIndex <= 0 || theIndex > mySize)
350 Standard_OutOfRange::Raise ("NCollection_Sequence::ChangeValue");
352 myCurrentItem = Find (theIndex);
353 myCurrentIndex = theIndex;
354 return ((Node *) myCurrentItem) -> ChangeValue();
357 //! Variable operator()
358 TheItemType& operator() (const Standard_Integer theIndex)
359 { return ChangeValue(theIndex); }
361 //! Set item value by theIndex
362 void SetValue (const Standard_Integer theIndex,
363 const TheItemType& theItem)
364 { ChangeValue (theIndex) = theItem; }
366 // ******** Destructor - clears the Sequence
367 ~NCollection_Sequence (void)
372 // ----------- PRIVATE METHODS -----------
374 //! Creates Iterator for use on BaseCollection
375 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
376 CreateIterator(void) const
377 { return *(new (this->IterAllocator()) Iterator(*this)); }
379 // ---------- FRIEND CLASSES ------------
380 friend class Iterator;