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