OCC22540 Regression: Exception during building of patch by GeomPlate
[occt.git] / src / NCollection / NCollection_SList.hxx
CommitLineData
7fd59977 1// File: NCollection_SList.hxx
2// Created: 17.04.02 10:12:48
3// Author: Alexander Kartomin (akm)
4// Copyright: Open Cascade 2002
5
6#ifndef NCollection_SList_HeaderFile
7#define NCollection_SList_HeaderFile
8
9#include <NCollection_BaseCollection.hxx>
10
11#if !defined No_Exception && !defined No_Standard_NoSuchObject
12#include <Standard_NoSuchObject.hxx>
13#endif
14
15#ifdef WNT
16// Disable the warning "operator new unmatched by delete"
17#pragma warning (disable:4291)
18#endif
19
20/**
21 * Purpose: An SList is a LISP like list of Items.
22 * An SList is :
23 * . Empty.
24 * . Or it has a Value and a Tail which is an other SList.
25 *
26 * The Tail of an empty list is an empty list.
27 * SList are shared. It means that they can be
28 * modified through other lists.
29 * SList may be used as Iterators. They have Next,
30 * More, and value methods. To iterate on the content
31 * of the list S just do.
32 *
33 * SList Iterator;
34 * for (Iterator = S; Iterator.More(); Iterator.Next())
35 * X = Iterator.Value();
36 *
37 * Memory usage is automatically managed for SLists
38 * (using reference counts).
39 *
40 * Example:
41 * If S1 and S2 are SLists :
42 * if S1.Value() is X.
43 *
44 * And the following is done :
45 * S2 = S1;
46 * S2.SetValue(Y);
47 *
48 * S1.Value() becomes also Y. So SList must be used
49 * with care. Mainly the SetValue() method is
50 * dangerous.
51 */
52template <class TheItemType> class NCollection_SList
53 : public NCollection_BaseCollection<TheItemType>,
54 public NCollection_BaseCollection<TheItemType>::Iterator
55{
56 public:
57 //! The node of SList
58 class SListNode
59 {
60 private:
61 //! Constructor
62 SListNode (const TheItemType& theItem,
63 const NCollection_SList& theTail) :
64 myCount(1),
65 myValue(theItem)
66 { myTail = new (theTail.myAllocator) NCollection_SList(theTail); }
67 //! Tail
68 NCollection_SList& Tail (void)
69 { return (*myTail); }
70 //! Value
71 TheItemType& Value (void)
72 { return myValue; }
73 //! Clear
74 void Clear (void)
75 {
76 myTail->Clear();
77 myTail->myAllocator->Free(myTail);
78 }
79 //! Operator new for allocating nodes
80 void* operator new(size_t theSize,
81 const Handle(NCollection_BaseAllocator)& theAllocator)
82 { return theAllocator->Allocate(theSize); }
83 //! news to avoid warnings on hiding - not for use
84 void* operator new(size_t theSize)
85 { return Standard::Allocate(theSize); }
86 void* operator new(size_t /*theSize*/, void* theAddress)
87 { return theAddress; }
88 private:
89 // ---------- PRIVATE FIELDS ------------
90 Standard_Integer myCount; //!< Reference count
91 NCollection_SList * myTail; //!< The tail
92 TheItemType myValue; //!< Datum
93
94 // Everything above is private. Only SList has an access
95 friend class NCollection_SList<TheItemType>;
96 }; // End of nested class SListNode
97
98 public:
99 // ---------- PUBLIC METHODS ------------
100
101 //! Empty constructor
102 NCollection_SList(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
103 NCollection_BaseCollection<TheItemType>(theAllocator),
104 myNode(NULL) {}
105
106 //! Constructor
107 NCollection_SList(const TheItemType& theItem,
108 const NCollection_SList& theTail) :
109 NCollection_BaseCollection<TheItemType>(theTail.myAllocator)
110 { myNode = new (theTail.myAllocator) SListNode(theItem,theTail); }
111
112 //! Copy constructor
113 NCollection_SList (const NCollection_SList& theOther) :
114 NCollection_BaseCollection<TheItemType>(theOther.myAllocator)
115 {
116 myNode = theOther.myNode;
117 if (myNode)
118 myNode->myCount++;
119 }
120
121 //! Operator new for creating 'iterator'
122 void* operator new(size_t theSize,
123 const Handle(NCollection_BaseAllocator)& theAllocator)
124 { return theAllocator->Allocate(theSize); }
125
126 //! Clear the items out
127 void Clear (void)
128 {
129 if (!myNode)
130 return;
131 myNode->myCount--;
132 if (myNode->myCount < 1)
133 {
134 myNode->Clear();
135 this->myAllocator->Free(myNode);
136 }
137 myNode = NULL;
138 }
139
140 //! Make this list identical to theOther
141 NCollection_SList& operator= (const NCollection_SList& theOther)
142 {
143 if (myNode != theOther.myNode)
144 {
145 if (theOther.myNode)
146 theOther.myNode->myCount++;
147 Clear();
148 this->myAllocator = theOther.myAllocator;
149 myNode = theOther.myNode;
150 }
151 return *this;
152 }
153
154 //! Replace this list by the items of theOther collection
155 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
156 {
157 if (this == &theOther)
158 return;
159 Clear();
160 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
161 theOther.CreateIterator();
162 if (!anIter.More())
163 return;
164 SListNode *aNode, *aPrevNode=NULL;
165 for (; anIter.More(); anIter.Next())
166 {
167 aNode = new (this->myAllocator) SListNode
168 (anIter.Value(), NCollection_SList(this->myAllocator));
169 if (IsEmpty())
170 myNode = aNode;
171 else
172 aPrevNode->Tail().myNode = aNode;
173 aPrevNode = aNode;
174 }
175 }
176
177 //! IsEmpty query
178 Standard_Boolean IsEmpty (void) const
179 { return (myNode==NULL); }
180
181 //! Value - constant access
182 virtual const TheItemType& Value (void) const
183 {
184#if !defined No_Exception && !defined No_Standard_NoSuchObject
185 if (IsEmpty())
186 Standard_NoSuchObject::Raise ("NCollection_SList::Value");
187#endif
188 return myNode->Value();
189 }
190
191 //! ChangeValue - variable access
192 virtual TheItemType& ChangeValue (void) const
193 {
194#if !defined No_Exception && !defined No_Standard_NoSuchObject
195 if (IsEmpty())
196 Standard_NoSuchObject::Raise ("NCollection_SList::ChangeValue");
197#endif
198 return myNode->Value();
199 }
200
201 //! SetValue
202 void SetValue (const TheItemType& theItem)
203 {
204#if !defined No_Exception && !defined No_Standard_NoSuchObject
205 if (IsEmpty())
206 Standard_NoSuchObject::Raise ("NCollection_SList::SetValue");
207#endif
208 myNode->Value() = theItem;
209 }
210
211 //! Tail
212 const NCollection_SList& Tail (void) const
213 {
214 if (!IsEmpty())
215 return myNode->Tail();
216 else
217 return *this;
218 }
219
220 //! ChangeTail
221 NCollection_SList& ChangeTail (void)
222 {
223 if (!IsEmpty())
224 return myNode->Tail();
225 else
226 return *this;
227 }
228
229 //! SetTail
230 void SetTail (NCollection_SList& theList)
231 {
232 if (!IsEmpty())
233 myNode->Tail() = theList;
234 else
235 *this = theList;
236 }
237
238 //! Construct
239 void Construct(const TheItemType& theItem)
240 { *this = NCollection_SList (theItem, *this); }
241
242 //! Constructed
243 NCollection_SList Constructed(const TheItemType& theItem) const
244 { return NCollection_SList (theItem, *this); }
245
246 //! ToTail
247 void ToTail (void)
248 { *this = Tail(); }
249
250 //! Initialize (~Assign)
251 void Initialize (const NCollection_SList& theOther)
252 { *this = theOther; }
253
254 //! Init (virtual method of base iterator)
255 void Init (const NCollection_SList& theOther)
256 { *this = theOther; }
257
258 //! More (~!IsEmpty)
259 virtual Standard_Boolean More (void) const
260 { return !IsEmpty(); }
261
262 //! Next (~ToTail)
263 virtual void Next (void)
264 { ToTail(); }
265
266 //! Size - Number of items
267 virtual Standard_Integer Size (void) const
268 { return (IsEmpty() ? 0 : 1+myNode->Tail().Size()); }
269
270 //! Destructor - clears the SList
271 ~NCollection_SList (void)
272 { Clear(); }
273
274
275 private:
276 // ----------- PRIVATE METHODS -----------
277
278 //! Creates Iterator for use on BaseCollection
279 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
280 CreateIterator(void) const
281 { return *(new (this->IterAllocator()) NCollection_SList(*this)); }
282
283 private:
284 // ---------- PRIVATE FIELDS ------------
285 SListNode* myNode;
286
287 friend class SListNode;
288};
289
290#ifdef WNT
291#pragma warning (default:4291)
292#endif
293
294#endif