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