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