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_BaseSequence.hxx>
20 #include <NCollection_StlIterator.hxx>
23 #include <Standard_OutOfRange.hxx>
24 #include <Standard_NoSuchObject.hxx>
28 * Purpose: Definition of a sequence of elements indexed by
29 * an Integer in range of 1..n
31 template <class TheItemType>
32 class NCollection_Sequence : public NCollection_BaseSequence
35 //! STL-compliant typedef for value type
36 typedef TheItemType value_type;
39 //! Class defining sequence node - for internal use by Sequence
40 class Node : public NCollection_SeqNode
44 Node (const TheItemType& theItem) :
45 NCollection_SeqNode ()
46 { myValue = theItem; }
47 //! Constant value access
48 const TheItemType& Value () const { return myValue; }
49 //! Variable value access
50 TheItemType& ChangeValue () { return myValue; }
54 }; // End of nested class Node
57 //! Implementation of the Iterator interface.
58 class Iterator : public NCollection_BaseSequence::Iterator
61 //! Empty constructor - for later Init
63 //! Constructor with initialisation
64 Iterator (const NCollection_Sequence& theSeq,
65 const Standard_Boolean isStart = Standard_True)
66 : NCollection_BaseSequence::Iterator (theSeq, isStart) {}
68 Standard_Boolean More (void) const
69 { return (myCurrent!=NULL); }
75 myPrevious = myCurrent;
76 myCurrent = myCurrent->Next();
79 //! Constant value access
80 const TheItemType& Value (void) const
81 { return ((const Node *)myCurrent)->Value(); }
82 //! Variable value access
83 TheItemType& ChangeValue (void) const
84 { return ((Node *)myCurrent)->ChangeValue(); }
85 //! Performs comparison of two iterators.
86 Standard_Boolean IsEqual (const Iterator& theOther) const
88 return myCurrent == theOther.myCurrent;
90 }; // End of nested class Iterator
92 //! Shorthand for a regular iterator type.
93 typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, false> iterator;
95 //! Shorthand for a constant iterator type.
96 typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, true> const_iterator;
98 //! Returns an iterator pointing to the first element in the sequence.
99 iterator begin() const { return Iterator (*this, true); }
101 //! Returns an iterator referring to the past-the-end element in the sequence.
102 iterator end() const { Iterator anIter (*this, false); anIter.Next(); return anIter; }
104 //! Returns a const iterator pointing to the first element in the sequence.
105 const_iterator cbegin() const { return Iterator (*this, true); }
107 //! Returns a const iterator referring to the past-the-end element in the sequence.
108 const_iterator cend() const { Iterator anIter (*this, false); anIter.Next(); return anIter; }
111 // ---------- PUBLIC METHODS ------------
114 NCollection_Sequence(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
115 NCollection_BaseSequence(theAllocator) {}
118 NCollection_Sequence (const NCollection_Sequence& theOther) :
119 NCollection_BaseSequence(theOther.myAllocator)
125 Standard_Integer Size (void) const
129 Standard_Integer Length (void) const
132 //! Method for consistency with other collections.
133 //! @return Lower bound (inclusive) for iteration.
134 Standard_Integer Lower() const
139 //! Method for consistency with other collections.
140 //! @return Upper bound (inclusive) for iteration.
141 Standard_Integer Upper() const
147 Standard_Boolean IsEmpty (void) const
148 { return (mySize==0); }
154 //! Exchange two members
155 void Exchange (const Standard_Integer I,
156 const Standard_Integer J )
159 //! Static deleter to be passed to BaseSequence
160 static void delNode (NCollection_SeqNode * theNode,
161 Handle(NCollection_BaseAllocator)& theAl)
163 ((Node *) theNode)->~Node();
164 theAl->Free(theNode);
167 //! Clear the items out, take a new allocator if non null
168 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
171 if (!theAllocator.IsNull())
172 this->myAllocator = theAllocator;
175 //! Replace this sequence by the items of theOther
176 NCollection_Sequence& Assign (const NCollection_Sequence& theOther)
178 if (this == &theOther)
180 Clear (theOther.myAllocator);
181 Node * pCur = (Node *) theOther.myFirstItem;
183 Node* pNew = new (this->myAllocator) Node (pCur->Value());
185 pCur = (Node *) pCur->Next();
190 //! Replacement operator
191 NCollection_Sequence& operator= (const NCollection_Sequence& theOther)
193 return Assign (theOther);
197 void Remove (Iterator& thePosition)
198 { RemoveSeq (thePosition, delNode); }
201 void Remove (const Standard_Integer theIndex)
202 { RemoveSeq (theIndex, delNode); }
204 //! Remove range of items
205 void Remove (const Standard_Integer theFromIndex,
206 const Standard_Integer theToIndex)
207 { RemoveSeq (theFromIndex, theToIndex, delNode); }
210 void Append (const TheItemType& theItem)
211 { PAppend (new (this->myAllocator) Node (theItem)); }
213 //! Append another sequence (making it empty)
214 void Append (NCollection_Sequence& theSeq)
216 if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
221 void Prepend (const TheItemType& theItem)
222 { PPrepend (new (this->myAllocator) Node (theItem)); }
224 //! Prepend another sequence (making it empty)
225 void Prepend (NCollection_Sequence& theSeq)
227 if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
231 //! InsertBefore theIndex theItem
232 void InsertBefore (const Standard_Integer theIndex,
233 const TheItemType& theItem)
234 { InsertAfter (theIndex-1, theItem); }
236 //! InsertBefore theIndex another sequence
237 void InsertBefore (const Standard_Integer theIndex,
238 NCollection_Sequence& theSeq)
239 { InsertAfter (theIndex-1, theSeq); }
241 //! InsertAfter the position of iterator
242 void InsertAfter (Iterator& thePosition,
243 const TheItemType& theItem)
244 { PInsertAfter (thePosition, new (this->myAllocator) Node (theItem)); }
246 //! InsertAfter theIndex theItem
247 void InsertAfter (const Standard_Integer theIndex,
248 NCollection_Sequence& theSeq)
249 { PInsertAfter (theIndex, theSeq); }
251 //! InsertAfter theIndex another sequence
252 void InsertAfter (const Standard_Integer theIndex,
253 const TheItemType& theItem)
255 #if !defined No_Exception && !defined No_Standard_OutOfRange
256 if (theIndex < 0 || theIndex > mySize)
257 Standard_OutOfRange::Raise ("NCollection_Sequence::InsertAfter");
259 PInsertAfter (theIndex, new (this->myAllocator) Node (theItem));
262 //! Split in two sequences
263 void Split (const Standard_Integer theIndex, NCollection_Sequence& theSeq)
265 theSeq.Clear (this->myAllocator);
266 PSplit (theIndex, theSeq);
269 //! First item access
270 const TheItemType& First () const
272 #if !defined No_Exception && !defined No_Standard_NoSuchObject
274 Standard_NoSuchObject::Raise ("NCollection_Sequence::First");
276 return ((const Node *) myFirstItem) -> Value();
279 //! First item access
280 TheItemType& ChangeFirst()
282 #if !defined No_Exception && !defined No_Standard_NoSuchObject
284 Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeFirst");
286 return ((Node* )myFirstItem)->ChangeValue();
290 const TheItemType& Last () const
292 #if !defined No_Exception && !defined No_Standard_NoSuchObject
294 Standard_NoSuchObject::Raise ("NCollection_Sequence::Last");
296 return ((const Node *) myLastItem) -> Value();
300 TheItemType& ChangeLast()
302 #if !defined No_Exception && !defined No_Standard_NoSuchObject
304 Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeLast");
306 return ((Node* )myLastItem)->ChangeValue();
309 //! Constant item access by theIndex
310 const TheItemType& Value (const Standard_Integer theIndex) const
312 #if !defined No_Exception && !defined No_Standard_OutOfRange
313 if (theIndex <= 0 || theIndex > mySize)
314 Standard_OutOfRange::Raise ("NCollection_Sequence::Value");
316 NCollection_Sequence * const aLocalTHIS = (NCollection_Sequence *) this;
317 aLocalTHIS -> myCurrentItem = Find (theIndex);
318 aLocalTHIS -> myCurrentIndex = theIndex;
319 return ((const Node *) myCurrentItem) -> Value();
322 //! Constant operator()
323 const TheItemType& operator() (const Standard_Integer theIndex) const
324 { return Value(theIndex); }
326 //! Variable item access by theIndex
327 TheItemType& ChangeValue (const Standard_Integer theIndex)
329 #if !defined No_Exception && !defined No_Standard_OutOfRange
330 if (theIndex <= 0 || theIndex > mySize)
331 Standard_OutOfRange::Raise ("NCollection_Sequence::ChangeValue");
333 myCurrentItem = Find (theIndex);
334 myCurrentIndex = theIndex;
335 return ((Node *) myCurrentItem) -> ChangeValue();
338 //! Variable operator()
339 TheItemType& operator() (const Standard_Integer theIndex)
340 { return ChangeValue(theIndex); }
342 //! Set item value by theIndex
343 void SetValue (const Standard_Integer theIndex,
344 const TheItemType& theItem)
345 { ChangeValue (theIndex) = theItem; }
347 // ******** Destructor - clears the Sequence
348 ~NCollection_Sequence (void)
353 // ---------- FRIEND CLASSES ------------
354 friend class Iterator;