File indexing completed on 2026-09-10 09:17:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef LDOM_DeclareSequence_HeaderFile
0017 #define LDOM_DeclareSequence_HeaderFile
0018
0019 #ifndef _Standard_Macro_HeaderFile
0020 #include <Standard_Macro.hxx>
0021 #endif
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #define DECLARE_SEQUENCE(ClassName, Type) \
0040 \
0041 class ClassName \
0042 { \
0043 public: \
0044 inline ClassName(); \
0045 inline ClassName(const ClassName& anOther); \
0046 inline ClassName& operator=(const ClassName& anOther); \
0047 inline Standard_Integer Length() const; \
0048 inline const Type& First() const; \
0049 inline const Type& Last() const; \
0050 inline const Type& Value(const Standard_Integer) const; \
0051 inline Type& ChangeValue(const Standard_Integer); \
0052 inline const Type& operator()(const Standard_Integer) const; \
0053 inline Type& operator()(const Standard_Integer); \
0054 \
0055 Standard_EXPORT virtual ~ClassName(); \
0056 Standard_EXPORT void Append(const Type& aVal); \
0057 Standard_EXPORT void Prepend(const Type& aVal); \
0058 Standard_EXPORT void InsertAt(const Standard_Integer, const Type& aVal); \
0059 Standard_EXPORT void Clear(); \
0060 Standard_EXPORT void Remove(const Standard_Integer); \
0061 \
0062 private: \
0063 class Node \
0064 { \
0065 private: \
0066 Type myValue; \
0067 Node* myPrev; \
0068 Node* myNext; \
0069 \
0070 public: \
0071 Node(const Type& aValue, Node* aPrv, Node* aNxt) \
0072 : myValue(aValue), \
0073 myPrev(aPrv), \
0074 myNext(aNxt) \
0075 { \
0076 } \
0077 const Type& Value() const \
0078 { \
0079 return myValue; \
0080 } \
0081 Type& ChangeValue() \
0082 { \
0083 return myValue; \
0084 } \
0085 friend class ClassName; \
0086 }; \
0087 \
0088 Standard_EXPORT const void* FindItem(const Standard_Integer) const; \
0089 Standard_EXPORT void Assign(const ClassName& anOther); \
0090 \
0091 Node* myFirst; \
0092 Node* myLast; \
0093 Node* myCurrent; \
0094 Standard_Integer myICur; \
0095 Standard_Integer myLength; \
0096 }; \
0097 \
0098 inline ClassName::ClassName() \
0099 : myFirst(NULL), \
0100 myLast(NULL), \
0101 myCurrent(NULL), \
0102 myICur(0), \
0103 myLength(0) \
0104 { \
0105 } \
0106 \
0107 inline ClassName::ClassName(const ClassName& anOther) \
0108 : myFirst(NULL) \
0109 { \
0110 Assign(anOther); \
0111 } \
0112 \
0113 inline ClassName& ClassName::operator=(const ClassName& anOther) \
0114 { \
0115 Assign(anOther); \
0116 return *this; \
0117 } \
0118 \
0119 inline Standard_Integer ClassName::Length() const \
0120 { \
0121 return myLength; \
0122 } \
0123 \
0124 inline const Type& ClassName::First() const \
0125 { \
0126 return myFirst->Value(); \
0127 } \
0128 \
0129 inline const Type& ClassName::Last() const \
0130 { \
0131 return myLast->Value(); \
0132 } \
0133 \
0134 inline const Type& ClassName::Value(const Standard_Integer anI) const \
0135 { \
0136 const Node* anItem = (const Node*)FindItem(anI); \
0137 return anItem->Value(); \
0138 } \
0139 \
0140 inline Type& ClassName::ChangeValue(const Standard_Integer anI) \
0141 { \
0142 Node* anItem = (Node*)FindItem(anI); \
0143 return anItem->ChangeValue(); \
0144 } \
0145 \
0146 inline const Type& ClassName::operator()(const Standard_Integer anI) const \
0147 { \
0148 return Value(anI); \
0149 } \
0150 \
0151 inline Type& ClassName::operator()(const Standard_Integer anI) \
0152 { \
0153 return ChangeValue(anI); \
0154 }
0155
0156
0157
0158
0159
0160 #define IMPLEMENT_SEQUENCE(ClassName, Type) \
0161 const void* ClassName::FindItem(const Standard_Integer anI) const \
0162 { \
0163 if (anI < 1 || anI > myLength) \
0164 return NULL; \
0165 Standard_Integer aCounter; \
0166 Node* aCurrent = (Node*)myCurrent; \
0167 Standard_Boolean aDir(Standard_False); \
0168 if (aCurrent == NULL) \
0169 { \
0170 aCurrent = myFirst; \
0171 aCounter = anI - 1; \
0172 aDir = Standard_True; \
0173 } \
0174 else \
0175 { \
0176 aCounter = Abs(anI - myICur); \
0177 if (anI <= aCounter) \
0178 { \
0179 aCurrent = myFirst; \
0180 aCounter = anI - 1; \
0181 aDir = Standard_True; \
0182 } \
0183 else if (myLength - anI < aCounter) \
0184 { \
0185 aCurrent = myLast; \
0186 aCounter = myLength - anI; \
0187 } \
0188 else if (anI > myICur) \
0189 aDir = Standard_True; \
0190 } \
0191 if (aDir) \
0192 while (aCounter--) \
0193 aCurrent = aCurrent->myNext; \
0194 else \
0195 while (aCounter--) \
0196 aCurrent = aCurrent->myPrev; \
0197 (Standard_Integer&)myICur = anI; \
0198 (Node*&)myCurrent = aCurrent; \
0199 return aCurrent; \
0200 } \
0201 \
0202 ClassName::~ClassName() \
0203 { \
0204 Clear(); \
0205 } \
0206 \
0207 void ClassName::Append(const Type& aVal) \
0208 { \
0209 Node* anItem = new Node(aVal, myLast, NULL); \
0210 if (myLength == 0) \
0211 myFirst = anItem; \
0212 else \
0213 myLast->myNext = anItem; \
0214 myLast = anItem; \
0215 myLength++; \
0216 } \
0217 \
0218 void ClassName::Prepend(const Type& aVal) \
0219 { \
0220 Node* anItem = new Node(aVal, NULL, myFirst); \
0221 if (myLength == 0) \
0222 myLast = anItem; \
0223 else \
0224 myFirst->myPrev = anItem; \
0225 myFirst = anItem; \
0226 myLength++; \
0227 if (myICur > 0) \
0228 myICur++; \
0229 } \
0230 \
0231 void ClassName::InsertAt(const Standard_Integer anI, const Type& aVal) \
0232 { \
0233 if (anI <= 1) \
0234 Prepend(aVal); \
0235 else if (anI > myLength) \
0236 Append(aVal); \
0237 else if (FindItem(anI)) \
0238 { \
0239 Node* anItem = new Node(aVal, myCurrent->myPrev, myCurrent); \
0240 myCurrent->myPrev = anItem; \
0241 if (anItem->myPrev) \
0242 anItem->myPrev->myNext = anItem; \
0243 myLength++; \
0244 myICur++; \
0245 } \
0246 } \
0247 \
0248 void ClassName::Clear() \
0249 { \
0250 while (myFirst) \
0251 { \
0252 Node* aCurr = myFirst->myNext; \
0253 delete myFirst; \
0254 myFirst = aCurr; \
0255 } \
0256 myFirst = myLast = myCurrent = NULL; \
0257 myLength = 0; \
0258 myICur = 0; \
0259 } \
0260 \
0261 void ClassName::Remove(const Standard_Integer anI) \
0262 { \
0263 Node* anItem = (Node*)FindItem(anI); \
0264 if (anItem) \
0265 { \
0266 if (myCurrent->myPrev) \
0267 { \
0268 myCurrent->myPrev->myNext = myCurrent->myNext; \
0269 } \
0270 if (myCurrent->myNext) \
0271 { \
0272 myCurrent->myNext->myPrev = myCurrent->myPrev; \
0273 myCurrent = myCurrent->myNext; \
0274 } \
0275 else \
0276 { \
0277 myCurrent = myCurrent->myPrev; \
0278 myICur--; \
0279 } \
0280 if (myFirst == anItem) \
0281 myFirst = myFirst->myNext; \
0282 if (myLast == anItem) \
0283 myLast = myLast->myPrev; \
0284 delete anItem; \
0285 myLength--; \
0286 } \
0287 } \
0288 \
0289 void ClassName::Assign(const ClassName& anOther) \
0290 { \
0291 Clear(); \
0292 if (anOther.Length() == 0) \
0293 return; \
0294 myFirst = new Node(anOther.First(), NULL, NULL); \
0295 Node* aPrevious = myFirst; \
0296 myLength = 1; \
0297 while (myLength < anOther.Length()) \
0298 { \
0299 myLength++; \
0300 Node* aCurrent = new Node(anOther.Value(myLength), aPrevious, NULL); \
0301 aPrevious = aPrevious->myNext = aCurrent; \
0302 } \
0303 myLast = aPrevious; \
0304 }
0305
0306 #endif