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 | */ |
31 | template <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 |