0027838: Foundation Classes - support wchar_t* input within TCollection_AsciiString...
[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//
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 29template <class TheItemType>
30class NCollection_Sequence : public NCollection_BaseSequence
7fd59977 31{
79a35943 32public:
33 //! STL-compliant typedef for value type
34 typedef TheItemType value_type;
7fd59977 35
79a35943 36public:
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