0022815: Missing delete operator for placement new
[occt.git] / src / NCollection / NCollection_Sequence.hxx
1 // File:        NCollection_Sequence.hxx
2 // Created:     28.03.02 20:41:43
3 // Author:      Alexander GRIGORIEV
4 // Copyright:   Open Cascade 2002
5
6 #ifndef NCollection_Sequence_HeaderFile
7 #define NCollection_Sequence_HeaderFile
8
9 #include <NCollection_BaseCollection.hxx>
10 #include <NCollection_BaseSequence.hxx>
11
12 #ifndef No_Exception
13 #include <Standard_OutOfRange.hxx>
14 #include <Standard_NoSuchObject.hxx>
15 #endif
16
17 /**
18  * Purpose:     Definition of a sequence of elements indexed by
19  *              an Integer in range of 1..n
20  */              
21 template <class TheItemType> class NCollection_Sequence
22   : public NCollection_BaseCollection<TheItemType>,
23     public NCollection_BaseSequence
24 {
25
26  public:
27   //!   Class defining sequence node - for internal use by Sequence
28   class Node : public NCollection_SeqNode
29   {
30   public:
31     //! Constructor
32     Node (const TheItemType& theItem) :
33       NCollection_SeqNode ()
34       { myValue = theItem; }
35     //! Constant value access
36     const TheItemType& Value () const { return myValue; }
37     //! Variable value access
38     TheItemType&       ChangeValue () { return myValue; }
39     //! Memory allocation
40     DEFINE_STANDARD_ALLOC
41     DEFINE_NCOLLECTION_ALLOC
42
43   private:
44     TheItemType    myValue;
45   }; // End of nested class Node
46
47  public:
48   //!   Implementation of the Iterator interface.
49   class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
50                    public NCollection_BaseSequence::Iterator
51   {
52   public:
53     //! Empty constructor - for later Init
54     Iterator  (void) {}
55     //! Constructor with initialisation
56     Iterator  (const NCollection_Sequence& theSeq,
57                const Standard_Boolean      isStart = Standard_True)
58       : NCollection_BaseSequence::Iterator (theSeq, isStart) {}
59     //! Assignment
60     Iterator& operator= (const Iterator& theIt)
61     {
62       NCollection_BaseSequence::Iterator& me = * this;
63       me.operator= (theIt);
64       return * this;
65     }
66     //! Check end
67     virtual Standard_Boolean More (void) const
68     { return (myCurrent!=NULL); }
69     //! Make step
70     virtual void Next (void)         
71     { if (myCurrent) myCurrent = (NCollection_SeqNode *) myCurrent->Next(); }
72     //! Constant value access
73     virtual const TheItemType& Value (void) const
74     { return ((const Node *)myCurrent)->Value(); }
75     //! Variable value access
76     virtual TheItemType& ChangeValue (void) const
77     { return ((Node *)myCurrent)->ChangeValue(); }
78   }; // End of nested class Iterator
79
80  public:
81   // ---------- PUBLIC METHODS ------------
82
83   //! Constructor
84   NCollection_Sequence(const Handle(NCollection_BaseAllocator)& theAllocator=0L)
85     : NCollection_BaseCollection<TheItemType>(theAllocator),
86       NCollection_BaseSequence() {}
87
88   //! Copy constructor
89   NCollection_Sequence (const NCollection_Sequence& theOther) :
90     NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
91     NCollection_BaseSequence()
92   { *this = theOther; }
93
94   //! Number of items
95   virtual Standard_Integer Size (void) const
96   { return mySize; }
97
98   //! Number of items
99   Standard_Integer Length (void) const
100   { return mySize; }
101
102   //! Empty query
103   Standard_Boolean IsEmpty (void) const
104   { return (mySize==0); }
105
106   //! Reverse sequence
107   void Reverse (void)
108   { PReverse(); }
109
110   //! Exchange two members
111   void Exchange (const Standard_Integer I,
112                  const Standard_Integer J )
113   { PExchange(I, J); }
114
115   //! Static deleter to be passed to BaseSequence
116   static void delNode (NCollection_SeqNode * theNode, 
117                        Handle(NCollection_BaseAllocator)& theAl)
118   {
119     ((Node *) theNode)->~Node();
120     theAl->Free(theNode);
121   }
122
123   //! Clear the items out, take a new allocator if non null
124   void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
125   {
126     ClearSeq (delNode, this->myAllocator);
127     if (!theAllocator.IsNull())
128       this->myAllocator = theAllocator;
129   }
130   
131   //! Replace this sequence by the items of theOther
132   NCollection_Sequence& operator= (const NCollection_Sequence& theOther)
133   { 
134     if (this == &theOther) 
135       return *this;
136     Clear (theOther.myAllocator);
137     Node * pCur = (Node *) theOther.myFirstItem;
138     while (pCur) {
139       Node* pNew = new (this->myAllocator) Node (pCur->Value());
140       PAppend (pNew);
141       pCur = (Node *) pCur->Next();
142     }
143     return * this;
144   }
145
146   //! Replace this sequence by the items of theOther collection
147   virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
148   {
149     if (this == &theOther)
150       return;
151     Clear ();
152     TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter = 
153       theOther.CreateIterator();
154     for (; anIter.More(); anIter.Next())
155       Append(anIter.Value());
156   }
157
158   //! Remove one item
159   void Remove (Iterator& thePosition)
160   { RemoveSeq (thePosition, delNode, this->myAllocator); }
161
162   //! Remove one item
163   void Remove (const Standard_Integer theIndex)
164   { RemoveSeq (theIndex, delNode, this->myAllocator); }
165
166   //! Remove range of items
167   void Remove (const Standard_Integer theFromIndex,
168                const Standard_Integer theToIndex)
169   { RemoveSeq (theFromIndex, theToIndex, delNode, this->myAllocator); }
170
171   //! Append one item
172   void Append (const TheItemType& theItem)
173   { PAppend (new (this->myAllocator) Node (theItem)); }
174
175   //! Append another sequence (making it empty)
176   void Append (NCollection_Sequence& theSeq)
177   {
178     if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
179     PAppend (theSeq);
180   }
181
182   //! Prepend one item
183   void Prepend (const TheItemType& theItem)
184   { PPrepend (new (this->myAllocator) Node (theItem)); }
185
186   //! Prepend another sequence (making it empty)
187   void Prepend (NCollection_Sequence& theSeq)
188   {
189     if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
190     PPrepend (theSeq);
191   }
192
193   //! InsertBefore theIndex theItem
194   void InsertBefore (const Standard_Integer theIndex, 
195                      const TheItemType&     theItem)
196   { InsertAfter (theIndex-1, theItem); }
197
198   //! InsertBefore theIndex another sequence
199   void InsertBefore (const Standard_Integer theIndex,
200                      NCollection_Sequence&  theSeq)
201   { InsertAfter (theIndex-1, theSeq); }
202   
203   //! InsertAfter the position of iterator
204   void InsertAfter  (Iterator&              thePosition,
205                      const TheItemType&     theItem)
206   { PInsertAfter (thePosition, new (this->myAllocator) Node (theItem)); }
207
208   //! InsertAfter theIndex theItem
209   void InsertAfter  (const Standard_Integer theIndex,
210                      NCollection_Sequence&  theSeq)
211   { PInsertAfter (theIndex, theSeq); }
212
213   //! InsertAfter theIndex another sequence
214   void InsertAfter (const Standard_Integer  theIndex, 
215                     const TheItemType&      theItem)
216   {
217 #if !defined No_Exception && !defined No_Standard_OutOfRange
218     if (theIndex < 0 || theIndex > mySize)
219       Standard_OutOfRange::Raise ("NCollection_Sequence::InsertAfter");
220 #endif
221     PInsertAfter (theIndex, new (this->myAllocator) Node (theItem));
222   }
223
224   //! Split in two sequences
225   void Split (const Standard_Integer theIndex, NCollection_Sequence& theSeq)
226   {
227     theSeq.Clear (this->myAllocator);
228     PSplit (theIndex, theSeq);
229   }
230
231   //! First item access
232   const TheItemType& First () const
233   {
234 #if !defined No_Exception && !defined No_Standard_NoSuchObject
235     if (mySize == 0)
236       Standard_NoSuchObject::Raise ("NCollection_Sequence::First");
237 #endif
238     return ((const Node *) myFirstItem) -> Value();
239   }
240
241   //! Last item access
242   const TheItemType& Last () const
243   {
244 #if !defined No_Exception && !defined No_Standard_NoSuchObject
245     if (mySize == 0)
246       Standard_NoSuchObject::Raise ("NCollection_Sequence::Last");
247 #endif
248     return ((const Node *) myLastItem) -> Value();
249   }
250
251   //! Constant item access by theIndex
252   const TheItemType& Value (const Standard_Integer theIndex) const
253   {
254 #if !defined No_Exception && !defined No_Standard_OutOfRange
255     if (theIndex <= 0 || theIndex > mySize)
256       Standard_OutOfRange::Raise ("NCollection_Sequence::Value");
257 #endif
258     NCollection_Sequence * const aLocalTHIS = (NCollection_Sequence *) this;
259     aLocalTHIS -> myCurrentItem  = Find (theIndex);
260     aLocalTHIS -> myCurrentIndex = theIndex;
261     return ((const Node *) myCurrentItem) -> Value();
262   }
263
264   //! Constant operator()
265   const TheItemType& operator() (const Standard_Integer theIndex) const
266   { return Value(theIndex); }
267
268   //! Variable item access by theIndex
269   TheItemType& ChangeValue (const Standard_Integer theIndex)
270   {
271 #if !defined No_Exception && !defined No_Standard_OutOfRange
272     if (theIndex <= 0 || theIndex > mySize)
273       Standard_OutOfRange::Raise ("NCollection_Sequence::ChangeValue");
274 #endif
275     myCurrentItem  = Find (theIndex);
276     myCurrentIndex = theIndex;
277     return ((Node *) myCurrentItem) -> ChangeValue();
278   }
279
280   //! Variable operator()
281   TheItemType& operator() (const Standard_Integer theIndex)
282   { return ChangeValue(theIndex); }
283
284   //! Set item value by theIndex
285   void SetValue (const Standard_Integer theIndex, 
286                  const TheItemType& theItem)
287   { ChangeValue (theIndex) = theItem; }
288
289   // ******** Destructor - clears the Sequence
290   ~NCollection_Sequence (void)
291   { Clear(); }
292
293
294  private:
295   // ----------- PRIVATE METHODS -----------
296
297   //! Creates Iterator for use on BaseCollection
298   virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& 
299     CreateIterator(void) const
300   { return *(new (this->IterAllocator()) Iterator(*this)); }
301
302   // ---------- FRIEND CLASSES ------------
303   friend class Iterator;
304
305 };
306
307 #endif