0024512: clang++ compiler complains about extra semicolon
[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//
973c2be1 7// This library is free software; you can redistribute it and / or modify it
8// under the terms of the GNU Lesser General Public 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.
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
19#include <NCollection_BaseCollection.hxx>
20#include <NCollection_BaseSequence.hxx>
21
22#ifndef No_Exception
23#include <Standard_OutOfRange.hxx>
24#include <Standard_NoSuchObject.hxx>
25#endif
26
7fd59977 27/**
28 * Purpose: Definition of a sequence of elements indexed by
29 * an Integer in range of 1..n
30 */
31template <class TheItemType> class NCollection_Sequence
32 : public NCollection_BaseCollection<TheItemType>,
33 public NCollection_BaseSequence
34{
35
36 public:
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; }
49 //! Memory allocation
1c35b92f 50 DEFINE_STANDARD_ALLOC
51 DEFINE_NCOLLECTION_ALLOC
7fd59977 52
53 private:
54 TheItemType myValue;
55 }; // End of nested class Node
56
57 public:
58 //! Implementation of the Iterator interface.
59 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
60 public NCollection_BaseSequence::Iterator
61 {
62 public:
63 //! Empty constructor - for later Init
64 Iterator (void) {}
65 //! Constructor with initialisation
66 Iterator (const NCollection_Sequence& theSeq,
67 const Standard_Boolean isStart = Standard_True)
68 : NCollection_BaseSequence::Iterator (theSeq, isStart) {}
69 //! Assignment
70 Iterator& operator= (const Iterator& theIt)
71 {
72 NCollection_BaseSequence::Iterator& me = * this;
73 me.operator= (theIt);
74 return * this;
75 }
76 //! Check end
77 virtual Standard_Boolean More (void) const
78 { return (myCurrent!=NULL); }
79 //! Make step
80 virtual void Next (void)
81 { if (myCurrent) myCurrent = (NCollection_SeqNode *) myCurrent->Next(); }
82 //! Constant value access
83 virtual const TheItemType& Value (void) const
84 { return ((const Node *)myCurrent)->Value(); }
85 //! Variable value access
86 virtual TheItemType& ChangeValue (void) const
87 { return ((Node *)myCurrent)->ChangeValue(); }
7fd59977 88 }; // End of nested class Iterator
89
90 public:
91 // ---------- PUBLIC METHODS ------------
92
93 //! Constructor
94 NCollection_Sequence(const Handle(NCollection_BaseAllocator)& theAllocator=0L)
95 : NCollection_BaseCollection<TheItemType>(theAllocator),
96 NCollection_BaseSequence() {}
97
98 //! Copy constructor
99 NCollection_Sequence (const NCollection_Sequence& theOther) :
100 NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
101 NCollection_BaseSequence()
102 { *this = theOther; }
103
104 //! Number of items
105 virtual Standard_Integer Size (void) const
106 { return mySize; }
107
108 //! Number of items
109 Standard_Integer Length (void) const
110 { return mySize; }
111
a174a3c5 112 //! Method for consistency with other collections.
113 //! @return Lower bound (inclusive) for iteration.
114 Standard_Integer Lower() const
115 {
116 return 1;
117 }
118
119 //! Method for consistency with other collections.
120 //! @return Upper bound (inclusive) for iteration.
121 Standard_Integer Upper() const
122 {
123 return mySize;
124 }
125
7fd59977 126 //! Empty query
127 Standard_Boolean IsEmpty (void) const
128 { return (mySize==0); }
129
130 //! Reverse sequence
131 void Reverse (void)
132 { PReverse(); }
133
134 //! Exchange two members
135 void Exchange (const Standard_Integer I,
136 const Standard_Integer J )
137 { PExchange(I, J); }
138
139 //! Static deleter to be passed to BaseSequence
140 static void delNode (NCollection_SeqNode * theNode,
141 Handle(NCollection_BaseAllocator)& theAl)
142 {
143 ((Node *) theNode)->~Node();
144 theAl->Free(theNode);
145 }
146
147 //! Clear the items out, take a new allocator if non null
148 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
149 {
150 ClearSeq (delNode, this->myAllocator);
151 if (!theAllocator.IsNull())
152 this->myAllocator = theAllocator;
153 }
154
155 //! Replace this sequence by the items of theOther
156 NCollection_Sequence& operator= (const NCollection_Sequence& theOther)
157 {
158 if (this == &theOther)
159 return *this;
160 Clear (theOther.myAllocator);
161 Node * pCur = (Node *) theOther.myFirstItem;
162 while (pCur) {
163 Node* pNew = new (this->myAllocator) Node (pCur->Value());
164 PAppend (pNew);
165 pCur = (Node *) pCur->Next();
166 }
167 return * this;
168 }
169
170 //! Replace this sequence by the items of theOther collection
171 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
172 {
173 if (this == &theOther)
174 return;
175 Clear ();
176 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
177 theOther.CreateIterator();
178 for (; anIter.More(); anIter.Next())
179 Append(anIter.Value());
180 }
181
182 //! Remove one item
183 void Remove (Iterator& thePosition)
184 { RemoveSeq (thePosition, delNode, this->myAllocator); }
185
186 //! Remove one item
187 void Remove (const Standard_Integer theIndex)
188 { RemoveSeq (theIndex, delNode, this->myAllocator); }
189
190 //! Remove range of items
191 void Remove (const Standard_Integer theFromIndex,
192 const Standard_Integer theToIndex)
193 { RemoveSeq (theFromIndex, theToIndex, delNode, this->myAllocator); }
194
195 //! Append one item
196 void Append (const TheItemType& theItem)
197 { PAppend (new (this->myAllocator) Node (theItem)); }
198
199 //! Append another sequence (making it empty)
200 void Append (NCollection_Sequence& theSeq)
201 {
202 if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
203 PAppend (theSeq);
204 }
205
206 //! Prepend one item
207 void Prepend (const TheItemType& theItem)
208 { PPrepend (new (this->myAllocator) Node (theItem)); }
209
210 //! Prepend another sequence (making it empty)
211 void Prepend (NCollection_Sequence& theSeq)
212 {
213 if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
214 PPrepend (theSeq);
215 }
216
217 //! InsertBefore theIndex theItem
218 void InsertBefore (const Standard_Integer theIndex,
219 const TheItemType& theItem)
220 { InsertAfter (theIndex-1, theItem); }
221
222 //! InsertBefore theIndex another sequence
223 void InsertBefore (const Standard_Integer theIndex,
224 NCollection_Sequence& theSeq)
225 { InsertAfter (theIndex-1, theSeq); }
226
227 //! InsertAfter the position of iterator
228 void InsertAfter (Iterator& thePosition,
229 const TheItemType& theItem)
230 { PInsertAfter (thePosition, new (this->myAllocator) Node (theItem)); }
231
232 //! InsertAfter theIndex theItem
233 void InsertAfter (const Standard_Integer theIndex,
234 NCollection_Sequence& theSeq)
235 { PInsertAfter (theIndex, theSeq); }
236
237 //! InsertAfter theIndex another sequence
238 void InsertAfter (const Standard_Integer theIndex,
239 const TheItemType& theItem)
240 {
241#if !defined No_Exception && !defined No_Standard_OutOfRange
242 if (theIndex < 0 || theIndex > mySize)
243 Standard_OutOfRange::Raise ("NCollection_Sequence::InsertAfter");
244#endif
245 PInsertAfter (theIndex, new (this->myAllocator) Node (theItem));
246 }
247
248 //! Split in two sequences
249 void Split (const Standard_Integer theIndex, NCollection_Sequence& theSeq)
250 {
251 theSeq.Clear (this->myAllocator);
252 PSplit (theIndex, theSeq);
253 }
254
255 //! First item access
256 const TheItemType& First () const
257 {
258#if !defined No_Exception && !defined No_Standard_NoSuchObject
259 if (mySize == 0)
260 Standard_NoSuchObject::Raise ("NCollection_Sequence::First");
261#endif
262 return ((const Node *) myFirstItem) -> Value();
263 }
264
a174a3c5 265 //! First item access
266 TheItemType& ChangeFirst()
267 {
268#if !defined No_Exception && !defined No_Standard_NoSuchObject
269 if (mySize == 0)
270 Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeFirst");
271#endif
272 return ((Node* )myFirstItem)->ChangeValue();
273 }
274
7fd59977 275 //! Last item access
276 const TheItemType& Last () const
277 {
278#if !defined No_Exception && !defined No_Standard_NoSuchObject
279 if (mySize == 0)
280 Standard_NoSuchObject::Raise ("NCollection_Sequence::Last");
281#endif
282 return ((const Node *) myLastItem) -> Value();
283 }
284
a174a3c5 285 //! Last item access
286 TheItemType& ChangeLast()
287 {
288#if !defined No_Exception && !defined No_Standard_NoSuchObject
289 if (mySize == 0)
290 Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeLast");
291#endif
292 return ((Node* )myLastItem)->ChangeValue();
293 }
294
7fd59977 295 //! Constant item access by theIndex
296 const TheItemType& Value (const Standard_Integer theIndex) const
297 {
298#if !defined No_Exception && !defined No_Standard_OutOfRange
299 if (theIndex <= 0 || theIndex > mySize)
300 Standard_OutOfRange::Raise ("NCollection_Sequence::Value");
301#endif
302 NCollection_Sequence * const aLocalTHIS = (NCollection_Sequence *) this;
303 aLocalTHIS -> myCurrentItem = Find (theIndex);
304 aLocalTHIS -> myCurrentIndex = theIndex;
305 return ((const Node *) myCurrentItem) -> Value();
306 }
307
308 //! Constant operator()
309 const TheItemType& operator() (const Standard_Integer theIndex) const
310 { return Value(theIndex); }
311
312 //! Variable item access by theIndex
313 TheItemType& ChangeValue (const Standard_Integer theIndex)
314 {
315#if !defined No_Exception && !defined No_Standard_OutOfRange
316 if (theIndex <= 0 || theIndex > mySize)
317 Standard_OutOfRange::Raise ("NCollection_Sequence::ChangeValue");
318#endif
319 myCurrentItem = Find (theIndex);
320 myCurrentIndex = theIndex;
321 return ((Node *) myCurrentItem) -> ChangeValue();
322 }
323
324 //! Variable operator()
325 TheItemType& operator() (const Standard_Integer theIndex)
326 { return ChangeValue(theIndex); }
327
328 //! Set item value by theIndex
329 void SetValue (const Standard_Integer theIndex,
330 const TheItemType& theItem)
331 { ChangeValue (theIndex) = theItem; }
332
333 // ******** Destructor - clears the Sequence
334 ~NCollection_Sequence (void)
335 { Clear(); }
336
337
338 private:
339 // ----------- PRIVATE METHODS -----------
340
341 //! Creates Iterator for use on BaseCollection
342 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
343 CreateIterator(void) const
344 { return *(new (this->IterAllocator()) Iterator(*this)); }
345
346 // ---------- FRIEND CLASSES ------------
347 friend class Iterator;
348
349};
350
7fd59977 351#endif