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 | */ |
27 | template <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 |