0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / LDOM / LDOM_DeclareSequence.hxx
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
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                                                                               \
46 class 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                                                                               \
91 inline ClassName::ClassName () :                                              \
92        myFirst   (NULL),                                                      \
93        myLast    (NULL),                                                      \
94        myCurrent (NULL),                                                      \
95        myICur    (0),                                                         \
96        myLength  (0) {}                                                       \
97                                                                               \
98 inline ClassName::ClassName (const ClassName& anOther) :                      \
99        myFirst   (NULL)                                                       \
100 {                                                                             \
101    Assign (anOther);                                                          \
102 }                                                                             \
103                                                                               \
104 inline ClassName& ClassName::operator= (const ClassName& anOther)             \
105 {                                                                             \
106    Assign (anOther);                                                          \
107    return * this;                                                             \
108 }                                                                             \
109                                                                               \
110 inline Standard_Integer ClassName::Length () const{                           \
111    return myLength;                                                           \
112 }                                                                             \
113                                                                               \
114 inline const Type& ClassName::First () const                                  \
115 {                                                                             \
116    return myFirst -> Value (); /* exception if out of range */                \
117 }                                                                             \
118                                                                               \
119 inline const Type& ClassName::Last () const                                   \
120 {                                                                             \
121    return myLast -> Value(); /* exception if out of range */                  \
122 }                                                                             \
123                                                                               \
124 inline 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                                                                               \
130 inline 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                                                                               \
136 inline const Type& ClassName::operator() (const Standard_Integer anI) const   \
137 {                                                                             \
138    return Value (anI);                                                        \
139 }                                                                             \
140                                                                               \
141 inline 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 )                                 \
151 const 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                                                                               \
182 ClassName::~ClassName ()                                                      \
183 {                                                                             \
184    Clear ();                                                                  \
185 }                                                                             \
186                                                                               \
187 void 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                                                                               \
198 void 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                                                                               \
210 void 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                                                                               \
223 void 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                                                                               \
235 void 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                                                                               \
256 void 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