0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / LDOM / LDOM_DeclareSequence.hxx
CommitLineData
b311480e 1// Created on: 2001-01-29
2// Created by: Alexander GRIGORIEV
3// Copyright (c) 2001-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21#ifndef _Sequence_Declare_HeaderFile
22#define _Sequence_Declare_HeaderFile
23
24#ifndef _Standard_Macro_HeaderFile
25#include <Standard_Macro.hxx>
26#endif
27
28// Declaration of Sequence (numbered list) class.
29// Remarks on the current implementation:
30//
31// 1. Methods First() and Last() added
32// 2. The method InsertAt(anIndex) replaces InsertBefore and InsertAfter.
33// This method never throws exception "OutOfRange". Its behaviour:
34// anIndex <= 1 => equivalent to Prepend()
35// anIndex > Length() => equivalent to Append()
36// else => equivalent to InsertBefore.
37
38// *******************************************************************
39// use the following somewhere in a header file;
40// ClassName - name of the list class to create
41// Type - type of members of the list
42// *******************************************************************
43
44#define DECLARE_SEQUENCE( ClassName, Type ) \
45 \
46class ClassName { \
47 public: \
48 inline ClassName (); \
49 inline ClassName (const ClassName& anOther); \
50 inline ClassName& operator= (const ClassName& anOther); \
51 inline Standard_Integer Length () const; \
52 inline const Type& First () const; \
53 inline const Type& Last () const; \
54 inline const Type& Value (const Standard_Integer)const;\
55 inline Type& ChangeValue (const Standard_Integer); \
56 inline const Type& operator () (const Standard_Integer)const;\
57 inline Type& operator () (const Standard_Integer); \
58 \
59 Standard_EXPORT virtual ~ClassName (); \
60 Standard_EXPORT void Append (const Type& aVal); \
61 Standard_EXPORT void Prepend (const Type& aVal); \
62 Standard_EXPORT void InsertAt (const Standard_Integer, \
63 const Type& aVal); \
64 Standard_EXPORT void Clear (); \
65 Standard_EXPORT void Remove (const Standard_Integer); \
66 \
67 private: \
68 class Node { \
69 private: \
70 Type myValue; \
71 Node * myPrev; \
72 Node * myNext; \
73 public: \
74 Node (const Type& aValue, Node * aPrv, Node * aNxt) \
75 : myValue (aValue), myPrev (aPrv), myNext (aNxt) {} \
76 const Type& Value () const { return myValue; } \
77 Type& ChangeValue () { return myValue; } \
78 friend class ClassName; \
79 }; \
80 \
81 Standard_EXPORT const void * FindItem (const Standard_Integer)const;\
82 Standard_EXPORT void Assign (const ClassName& anOther); \
83 \
84 Node * myFirst; \
85 Node * myLast; \
86 Node * myCurrent; \
87 Standard_Integer myICur; \
88 Standard_Integer myLength; \
89}; \
90 \
91inline ClassName::ClassName () : \
92 myFirst (NULL), \
93 myLast (NULL), \
94 myCurrent (NULL), \
95 myICur (0), \
96 myLength (0) {} \
97 \
98inline ClassName::ClassName (const ClassName& anOther) : \
99 myFirst (NULL) \
100{ \
101 Assign (anOther); \
102} \
103 \
104inline ClassName& ClassName::operator= (const ClassName& anOther) \
105{ \
106 Assign (anOther); \
107 return * this; \
108} \
109 \
110inline Standard_Integer ClassName::Length () const{ \
111 return myLength; \
112} \
113 \
114inline const Type& ClassName::First () const \
115{ \
116 return myFirst -> Value (); /* exception if out of range */ \
117} \
118 \
119inline const Type& ClassName::Last () const \
120{ \
121 return myLast -> Value(); /* exception if out of range */ \
122} \
123 \
124inline const Type& ClassName::Value (const Standard_Integer anI) const \
125{ \
126 const Node * anItem = (const Node *) FindItem (anI); \
127 return anItem -> Value (); /* exception if out of range */ \
128} \
129 \
130inline Type& ClassName::ChangeValue (const Standard_Integer anI) \
131{ \
132 Node * anItem = (Node *) FindItem (anI); \
133 return anItem -> ChangeValue (); /* exception if out of range */ \
134} \
135 \
136inline const Type& ClassName::operator() (const Standard_Integer anI) const \
137{ \
138 return Value (anI); \
139} \
140 \
141inline Type& ClassName::operator() (const Standard_Integer anI) \
142{ \
143 return ChangeValue (anI); \
144} \
145
146// *******************************************************************
147// use the following in a translation unit (*.cxx);
148//
149// *******************************************************************
150#define IMPLEMENT_SEQUENCE( ClassName, Type ) \
151const void * ClassName::FindItem (const Standard_Integer anI) const \
152{ \
153 if (anI < 1 || anI > myLength) return NULL; \
154 Standard_Integer aCounter; \
155 Node * aCurrent = (Node *) myCurrent; \
156 Standard_Boolean aDir (Standard_False); \
157 if (aCurrent == NULL) { \
158 aCurrent = myFirst; \
159 aCounter = anI - 1; \
160 aDir = Standard_True; \
161 }else{ \
162 aCounter = Abs (anI - myICur); \
163 if (anI <= aCounter) { \
164 aCurrent = myFirst; \
165 aCounter = anI - 1; \
166 aDir = Standard_True; \
167 }else if (myLength - anI < aCounter) { \
168 aCurrent = myLast; \
169 aCounter = myLength - anI; \
170 }else if (anI > myICur) \
171 aDir = Standard_True; \
172 } \
173 if (aDir) \
174 while (aCounter--) aCurrent = aCurrent -> myNext; \
175 else \
176 while (aCounter--) aCurrent = aCurrent -> myPrev; \
177 (Standard_Integer&) myICur = anI; \
178 (Node *&) myCurrent = aCurrent; \
179 return aCurrent; \
180} \
181 \
182ClassName::~ClassName () \
183{ \
184 Clear (); \
185} \
186 \
187void ClassName::Append (const Type& aVal) \
188{ \
189 Node * anItem = new Node (aVal, myLast, NULL); \
190 if (myLength == 0) \
191 myFirst = anItem; \
192 else \
193 myLast -> myNext = anItem; \
194 myLast = anItem; \
195 myLength++; \
196} \
197 \
198void ClassName::Prepend (const Type& aVal) \
199{ \
200 Node * anItem = new Node (aVal, NULL, myFirst); \
201 if (myLength == 0) \
202 myLast = anItem; \
203 else \
204 myFirst -> myPrev = anItem; \
205 myFirst = anItem; \
206 myLength++; \
207 if (myICur > 0) myICur++; \
208} \
209 \
210void ClassName::InsertAt (const Standard_Integer anI, const Type& aVal) \
211{ \
212 if (anI <= 1) Prepend (aVal); \
213 else if (anI > myLength) Append (aVal); \
214 else if (FindItem(anI)) { \
215 Node * anItem = new Node (aVal, myCurrent -> myPrev, myCurrent); \
216 myCurrent -> myPrev = anItem; \
217 if (anItem -> myPrev) anItem -> myPrev -> myNext = anItem; \
218 myLength++; \
219 myICur++; \
220 } else ; \
221} \
222 \
223void ClassName::Clear () \
224{ \
225 while (myFirst) { \
226 Node * aCurr = myFirst -> myNext; \
227 delete myFirst; \
228 myFirst = aCurr; \
229 } \
230 myFirst = myLast = myCurrent = NULL; \
231 myLength = 0; \
232 myICur = 0; \
233} \
234 \
235void ClassName::Remove (const Standard_Integer anI) \
236{ \
237 Node * anItem = (Node *) FindItem (anI); \
238 if (anItem) { \
239 if (myCurrent -> myPrev) { \
240 myCurrent -> myPrev -> myNext = myCurrent -> myNext; \
241 } \
242 if (myCurrent -> myNext) { \
243 myCurrent -> myNext -> myPrev = myCurrent -> myPrev; \
244 myCurrent = myCurrent -> myNext; \
245 }else{ \
246 myCurrent = myCurrent -> myPrev; \
247 myICur--; \
248 } \
249 if (myFirst == anItem) myFirst = myFirst -> myNext; \
250 if (myLast == anItem) myLast = myLast -> myPrev; \
251 delete anItem; \
252 myLength--; \
253 } \
254} \
255 \
256void ClassName::Assign (const ClassName& anOther) \
257{ \
258 Clear (); \
259 if (anOther.Length () == 0) return; \
260 myFirst = new Node (anOther.First(), NULL, NULL); \
261 Node * aPrevious = myFirst; \
262 myLength = 1; \
263 while (myLength < anOther.Length()) { \
264 myLength++; \
265 Node * aCurrent = new Node (anOther.Value(myLength), aPrevious, NULL); \
266 aPrevious = aPrevious -> myNext = aCurrent; \
267 } \
268 myLast = aPrevious; \
269} \
270
271#endif