Integration of OCCT 6.5.0 from SVN
[occt.git] / src / NCollection / NCollection_List.hxx
CommitLineData
7fd59977 1// File: NCollection_List.hxx
2// Created: 17.04.02 10:12:48
3// Author: Alexander Kartomin (akm)
4// <a-kartomin@opencascade.com>
5// Copyright: Open Cascade 2002
6
7#ifndef NCollection_List_HeaderFile
8#define NCollection_List_HeaderFile
9
10#include <NCollection_TListIterator.hxx>
11
12#if !defined No_Exception && !defined No_Standard_NoSuchObject
13#include <Standard_NoSuchObject.hxx>
14#endif
15
16#ifdef WNT
17// Disable the warning "operator new unmatched by delete"
18#pragma warning (push)
19#pragma warning (disable:4291)
20#endif
21
22/**
23 * Purpose: Simple list to link items together keeping the first
24 * and the last one.
25 * Inherits BaseList, adding the data item to each node.
26 */
27template <class TheItemType> class NCollection_List
28 : public NCollection_BaseCollection<TheItemType>,
29 public NCollection_BaseList
30{
31 public:
32 typedef NCollection_TListNode<TheItemType> ListNode;
33 typedef NCollection_TListIterator<TheItemType> Iterator;
34
35 public:
36 // ---------- PUBLIC METHODS ------------
37
38 //! Constructor
39 NCollection_List(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
40 NCollection_BaseCollection<TheItemType>(theAllocator),
41 NCollection_BaseList() {}
42
43 //! Copy constructor
44 NCollection_List (const NCollection_List& theOther) :
45 NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
46 NCollection_BaseList()
47 { *this = theOther; }
48
49 //! Size - Number of items
50 virtual Standard_Integer Size (void) const
51 { return Extent(); }
52
53 //! Replace this list by the items of theOther collection
54 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
55 {
56 if (this == &theOther)
57 return;
58 Clear();
59 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
60 theOther.CreateIterator();
61 for (; anIter.More(); anIter.Next())
62 {
63 ListNode* pNew = new (this->myAllocator) ListNode(anIter.Value());
64 PAppend(pNew);
65 }
66 }
67
68 //! Replace this list by the items of another list (theOther parameter)
69 void Assign (const NCollection_List& theOther)
70 {
71 if (this != &theOther) {
72 Clear();
73 appendList(theOther.PFirst());
74 }
75 }
76
77 //! Replace this list by the items of theOther list
78 NCollection_List& operator= (const NCollection_List& theOther)
79 {
80 if (this != &theOther) {
81 Clear (theOther.myAllocator);
82 appendList(theOther.PFirst());
83 }
84 return *this;
85 }
86
87 //! Clear this list
88 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
89 {
90 PClear (ListNode::delNode, this->myAllocator);
91 if (!theAllocator.IsNull())
92 this->myAllocator = theAllocator;
93 }
94
95 //! First item
96 const TheItemType& First (void) const
97 {
98#if !defined No_Exception && !defined No_Standard_NoSuchObject
99 if (IsEmpty())
100 Standard_NoSuchObject::Raise ("NCollection_List::First");
101#endif
102 return ((const ListNode *) PFirst())->Value();
103 }
104
105 //! Last item
106 const TheItemType& Last (void) const
107 {
108#if !defined No_Exception && !defined No_Standard_NoSuchObject
109 if (IsEmpty())
110 Standard_NoSuchObject::Raise ("NCollection_List::Last");
111#endif
112 return ((const ListNode *) PLast())->Value();
113 }
114
115 //! Append one item at the end
116 TheItemType& Append (const TheItemType& theItem)
117 {
118 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
119 PAppend(pNew);
120 return ((ListNode *) PLast())->ChangeValue();
121 }
122
123 //! Append one item at the end and output iterator
124 //! pointing at the appended item
125 void Append (const TheItemType& theItem, Iterator& theIter)
126 {
127 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
128 PAppend(pNew, theIter);
129 }
130
131 //! Append another list at the end
132 void Append (NCollection_List& theOther)
133 {
134 if (this == &theOther || theOther.Extent()<1)
135 return;
136 if (this->myAllocator == theOther.myAllocator)
137 {
138 // Then we take the list and glue it to our end -
139 // deallocation will bring no problem
140 PAppend(theOther);
141 }
142 else
143 {
144 // No - this list has different memory scope
145 appendList(theOther.myFirst);
146 theOther.Clear();
147 }
148 }
149
150 //! Prepend one item at the beginning
151 TheItemType& Prepend (const TheItemType& theItem)
152 {
153 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
154 PPrepend(pNew);
155 return ((ListNode *) PFirst())->ChangeValue();
156 }
157
158 //! Prepend another list at the beginning
159 void Prepend (NCollection_List& theOther)
160 {
161 if (this == &theOther || theOther.Extent()<1)
162 return;
163 if (this->myAllocator == theOther.myAllocator)
164 {
165 // Then we take the list and glue it to our head -
166 // deallocation will bring no problem
167 PPrepend(theOther);
168 }
169 else
170 {
171 // No - this list has different memory scope
172 Iterator it(*this);
173 prependList(theOther.PFirst(), it);
174 theOther.Clear();
175 }
176 }
177
178 //! RemoveFirst item
179 void RemoveFirst (void)
180 { PRemoveFirst (ListNode::delNode, this->myAllocator); }
181
182 //! Remove item
183 void Remove (Iterator& theIter)
184 {
185 PRemove (theIter, ListNode::delNode, this->myAllocator);
186 }
187
188 //! InsertBefore
189 TheItemType& InsertBefore (const TheItemType& theItem,
190 Iterator& theIter)
191 {
192 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
193 PInsertBefore (pNew, theIter);
194 return pNew -> ChangeValue();
195 }
196
197 //! InsertBefore
198 void InsertBefore (NCollection_List& theOther,
199 Iterator& theIter)
200 {
201 if (this == &theOther)
202 return;
203
204 if (this->myAllocator == theOther.myAllocator)
205 {
206 // Then we take the list and glue it to our head -
207 // deallocation will bring no problem
208 PInsertBefore (theOther, theIter);
209 }
210 else
211 {
212 // No - this list has different memory scope
213 prependList(theOther.myFirst, theIter);
214 theOther.Clear();
215 }
216 }
217
218 //! InsertAfter
219 TheItemType& InsertAfter (const TheItemType& theItem,
220 Iterator& theIter)
221 {
222 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
223 PInsertAfter (pNew, theIter);
224 return pNew -> ChangeValue();
225 }
226
227 //! InsertAfter
228 void InsertAfter (NCollection_List& theOther,
229 Iterator& theIter)
230 {
231 if (!theIter.More())
232 {
233 Append(theOther);
234 return;
235 }
236 if (this->myAllocator == theOther.myAllocator)
237 {
238 // Then we take the list and glue it to our head -
239 // deallocation will bring no problem
240 PInsertAfter (theOther, theIter);
241 }
242 else
243 {
244 // No - this list has different memory scope
245#if !defined No_Exception && !defined No_Standard_NoSuchObject
246 if (!theIter.More())
247 Standard_NoSuchObject::Raise ("NCollection_List::InsertAfter");
248#endif
249 Iterator anIter;
250 anIter.myPrevious = theIter.myCurrent;
251 anIter.myCurrent = theIter.myCurrent->Next();
252 prependList(theOther.PFirst(), anIter);
253 theOther.Clear();
254 }
255 }
256
257 //! Reverse the list
258 void Reverse ()
259 { PReverse(); }
260
261 //! Destructor - clears the List
262 ~NCollection_List (void)
263 { Clear(); }
264
265 private:
266 // ----------- PRIVATE METHODS -----------
267
268 //! Creates Iterator for use on BaseCollection
269 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
270 CreateIterator(void) const
271 { return *(new (this->IterAllocator()) Iterator(*this)); }
272
273 //! append the list headed by the given ListNode
274 void appendList(const NCollection_ListNode * pCur) {
275 while (pCur) {
276 NCollection_ListNode * pNew =
277 new (this->myAllocator) ListNode(((const ListNode *)(pCur))->Value());
278 PAppend(pNew);
279 pCur = pCur->Next();
280 }
281 }
282
283 //! insert the list headed by the given ListNode before the given iterator
284 void prependList(const NCollection_ListNode * pCur, Iterator& theIter) {
285 while (pCur) {
286 NCollection_ListNode * pNew =
287 new (this->myAllocator) ListNode (((const ListNode *)(pCur))->Value());
288 PInsertBefore(pNew, theIter);
289 pCur = pCur->Next();
290 }
291 }
292};
293
294#ifdef WNT
295#pragma warning (pop)
296#endif
297
298#endif