0022627: Change OCCT memory management defaults
[occt.git] / src / LDOM / LDOM_DeclareSequence.hxx
CommitLineData
7fd59977 1// File: LH3D_DeclareSequence.hxx
2// Created: 29.01.01 15:36:46
3// Author: Alexander GRIGORIEV
4// Copyright: OpenCascade 2001
5
6#ifndef _Sequence_Declare_HeaderFile
7#define _Sequence_Declare_HeaderFile
8
9#ifndef _Standard_Macro_HeaderFile
10#include <Standard_Macro.hxx>
11#endif
12
13// Declaration of Sequence (numbered list) class.
14// Remarks on the current implementation:
15//
16// 1. Methods First() and Last() added
17// 2. The method InsertAt(anIndex) replaces InsertBefore and InsertAfter.
18// This method never throws exception "OutOfRange". Its behaviour:
19// anIndex <= 1 => equivalent to Prepend()
20// anIndex > Length() => equivalent to Append()
21// else => equivalent to InsertBefore.
22
23// *******************************************************************
24// use the following somewhere in a header file;
25// ClassName - name of the list class to create
26// Type - type of members of the list
27// *******************************************************************
28
29#define DECLARE_SEQUENCE( ClassName, Type ) \
30 \
31class ClassName { \
32 public: \
33 inline ClassName (); \
34 inline ClassName (const ClassName& anOther); \
35 inline ClassName& operator= (const ClassName& anOther); \
36 inline Standard_Integer Length () const; \
37 inline const Type& First () const; \
38 inline const Type& Last () const; \
39 inline const Type& Value (const Standard_Integer)const;\
40 inline Type& ChangeValue (const Standard_Integer); \
41 inline const Type& operator () (const Standard_Integer)const;\
42 inline Type& operator () (const Standard_Integer); \
43 \
44 Standard_EXPORT virtual ~ClassName (); \
45 Standard_EXPORT void Append (const Type& aVal); \
46 Standard_EXPORT void Prepend (const Type& aVal); \
47 Standard_EXPORT void InsertAt (const Standard_Integer, \
48 const Type& aVal); \
49 Standard_EXPORT void Clear (); \
50 Standard_EXPORT void Remove (const Standard_Integer); \
51 \
52 private: \
53 class Node { \
54 private: \
55 Type myValue; \
56 Node * myPrev; \
57 Node * myNext; \
58 public: \
59 Node (const Type& aValue, Node * aPrv, Node * aNxt) \
60 : myValue (aValue), myPrev (aPrv), myNext (aNxt) {} \
61 const Type& Value () const { return myValue; } \
62 Type& ChangeValue () { return myValue; } \
63 friend class ClassName; \
64 }; \
65 \
66 Standard_EXPORT const void * FindItem (const Standard_Integer)const;\
67 Standard_EXPORT void Assign (const ClassName& anOther); \
68 \
69 Node * myFirst; \
70 Node * myLast; \
71 Node * myCurrent; \
72 Standard_Integer myICur; \
73 Standard_Integer myLength; \
74}; \
75 \
76inline ClassName::ClassName () : \
77 myFirst (NULL), \
78 myLast (NULL), \
79 myCurrent (NULL), \
80 myICur (0), \
81 myLength (0) {} \
82 \
83inline ClassName::ClassName (const ClassName& anOther) : \
84 myFirst (NULL) \
85{ \
86 Assign (anOther); \
87} \
88 \
89inline ClassName& ClassName::operator= (const ClassName& anOther) \
90{ \
91 Assign (anOther); \
92 return * this; \
93} \
94 \
95inline Standard_Integer ClassName::Length () const{ \
96 return myLength; \
97} \
98 \
99inline const Type& ClassName::First () const \
100{ \
101 return myFirst -> Value (); /* exception if out of range */ \
102} \
103 \
104inline const Type& ClassName::Last () const \
105{ \
106 return myLast -> Value(); /* exception if out of range */ \
107} \
108 \
109inline const Type& ClassName::Value (const Standard_Integer anI) const \
110{ \
111 const Node * anItem = (const Node *) FindItem (anI); \
112 return anItem -> Value (); /* exception if out of range */ \
113} \
114 \
115inline Type& ClassName::ChangeValue (const Standard_Integer anI) \
116{ \
117 Node * anItem = (Node *) FindItem (anI); \
118 return anItem -> ChangeValue (); /* exception if out of range */ \
119} \
120 \
121inline const Type& ClassName::operator() (const Standard_Integer anI) const \
122{ \
123 return Value (anI); \
124} \
125 \
126inline Type& ClassName::operator() (const Standard_Integer anI) \
127{ \
128 return ChangeValue (anI); \
129} \
130
131// *******************************************************************
132// use the following in a translation unit (*.cxx);
133//
134// *******************************************************************
135#define IMPLEMENT_SEQUENCE( ClassName, Type ) \
136const void * ClassName::FindItem (const Standard_Integer anI) const \
137{ \
138 if (anI < 1 || anI > myLength) return NULL; \
139 Standard_Integer aCounter; \
140 Node * aCurrent = (Node *) myCurrent; \
141 Standard_Boolean aDir (Standard_False); \
142 if (aCurrent == NULL) { \
143 aCurrent = myFirst; \
144 aCounter = anI - 1; \
145 aDir = Standard_True; \
146 }else{ \
147 aCounter = Abs (anI - myICur); \
148 if (anI <= aCounter) { \
149 aCurrent = myFirst; \
150 aCounter = anI - 1; \
151 aDir = Standard_True; \
152 }else if (myLength - anI < aCounter) { \
153 aCurrent = myLast; \
154 aCounter = myLength - anI; \
155 }else if (anI > myICur) \
156 aDir = Standard_True; \
157 } \
158 if (aDir) \
159 while (aCounter--) aCurrent = aCurrent -> myNext; \
160 else \
161 while (aCounter--) aCurrent = aCurrent -> myPrev; \
162 (Standard_Integer&) myICur = anI; \
163 (Node *&) myCurrent = aCurrent; \
164 return aCurrent; \
165} \
166 \
167ClassName::~ClassName () \
168{ \
169 Clear (); \
170} \
171 \
172void ClassName::Append (const Type& aVal) \
173{ \
174 Node * anItem = new Node (aVal, myLast, NULL); \
175 if (myLength == 0) \
176 myFirst = anItem; \
177 else \
178 myLast -> myNext = anItem; \
179 myLast = anItem; \
180 myLength++; \
181} \
182 \
183void ClassName::Prepend (const Type& aVal) \
184{ \
185 Node * anItem = new Node (aVal, NULL, myFirst); \
186 if (myLength == 0) \
187 myLast = anItem; \
188 else \
189 myFirst -> myPrev = anItem; \
190 myFirst = anItem; \
191 myLength++; \
192 if (myICur > 0) myICur++; \
193} \
194 \
195void ClassName::InsertAt (const Standard_Integer anI, const Type& aVal) \
196{ \
197 if (anI <= 1) Prepend (aVal); \
198 else if (anI > myLength) Append (aVal); \
199 else if (FindItem(anI)) { \
200 Node * anItem = new Node (aVal, myCurrent -> myPrev, myCurrent); \
201 myCurrent -> myPrev = anItem; \
202 if (anItem -> myPrev) anItem -> myPrev -> myNext = anItem; \
203 myLength++; \
204 myICur++; \
205 } else ; \
206} \
207 \
208void ClassName::Clear () \
209{ \
210 while (myFirst) { \
211 Node * aCurr = myFirst -> myNext; \
212 delete myFirst; \
213 myFirst = aCurr; \
214 } \
215 myFirst = myLast = myCurrent = NULL; \
216 myLength = 0; \
217 myICur = 0; \
218} \
219 \
220void ClassName::Remove (const Standard_Integer anI) \
221{ \
222 Node * anItem = (Node *) FindItem (anI); \
223 if (anItem) { \
224 if (myCurrent -> myPrev) { \
225 myCurrent -> myPrev -> myNext = myCurrent -> myNext; \
226 } \
227 if (myCurrent -> myNext) { \
228 myCurrent -> myNext -> myPrev = myCurrent -> myPrev; \
229 myCurrent = myCurrent -> myNext; \
230 }else{ \
231 myCurrent = myCurrent -> myPrev; \
232 myICur--; \
233 } \
234 if (myFirst == anItem) myFirst = myFirst -> myNext; \
235 if (myLast == anItem) myLast = myLast -> myPrev; \
236 delete anItem; \
237 myLength--; \
238 } \
239} \
240 \
241void ClassName::Assign (const ClassName& anOther) \
242{ \
243 Clear (); \
244 if (anOther.Length () == 0) return; \
245 myFirst = new Node (anOther.First(), NULL, NULL); \
246 Node * aPrevious = myFirst; \
247 myLength = 1; \
248 while (myLength < anOther.Length()) { \
249 myLength++; \
250 Node * aCurrent = new Node (anOther.Value(myLength), aPrevious, NULL); \
251 aPrevious = aPrevious -> myNext = aCurrent; \
252 } \
253 myLast = aPrevious; \
254} \
255
256#endif