0024911: Avoid using virtual functions in NCollection classes
[occt.git] / src / NCollection / NCollection_Array1.hxx
CommitLineData
b311480e 1// Created on: 2002-04-15
2// Created by: Alexander Kartomin (akm)
973c2be1 3// Copyright (c) 2002-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#ifndef NCollection_Array1_HeaderFile
17#define NCollection_Array1_HeaderFile
18
19#ifndef No_Exception
20#include <Standard_DimensionMismatch.hxx>
21#include <Standard_OutOfMemory.hxx>
22#include <Standard_OutOfRange.hxx>
23#endif
24
ddf2fe8e 25#include <NCollection_DefineAlloc.hxx>
79a35943 26#include <NCollection_StlIterator.hxx>
7fd59977 27
7fd59977 28// *********************************************** Template for Array1 class
29
30/**
31* Purpose: The class Array1 represents unidimensional arrays
32* of fixed size known at run time.
33* The range of the index is user defined.
34* An array1 can be constructed with a "C array".
35* This functionality is useful to call methods expecting
36* an Array1. It allows to carry the bounds inside the arrays.
37*
38* Examples: Item tab[100]; // An example with a C array
39* Array1OfItem ttab (tab[0],1,100);
40*
41* Array1OfItem tttab (ttab(10),10,20); // a slice of ttab
42*
43* If you want to reindex an array from 1 to Length do :
44*
45* Array1 tab1(tab(tab.Lower()),1,tab.Length());
46*
47* Warning: Programs client of such a class must be independant
48* of the range of the first element. Then, a C++ for
49* loop must be written like this
50*
51* for (i = A.Lower(); i <= A.Upper(); i++)
52*
53* Changes: In comparison to TCollection the flag isAllocated was
54* renamed into myDeletable (alike in the Array2). For naming
55* compatibility the method IsAllocated remained in class along
56* with IsDeletable.
57*/
ddf2fe8e 58template <class TheItemType>
59class NCollection_Array1
7fd59977 60{
79a35943 61public:
62 //! STL-compliant typedef for value type
63 typedef TheItemType value_type;
7fd59977 64
79a35943 65public:
7fd59977 66 //! Implementation of the Iterator interface.
ddf2fe8e 67 class Iterator
7fd59977 68 {
69 public:
79a35943 70
7fd59977 71 //! Empty constructor - for later Init
79a35943 72 Iterator (void) :
73 myPtrCur (NULL),
74 myPtrEnd (NULL)
75 {
76 //
77 }
78
79 //! Constructor with initialization
80 Iterator (const NCollection_Array1& theArray, Standard_Boolean theToEnd = Standard_False) :
81 myPtrEnd (const_cast<TheItemType*> (&theArray.Last() + 1))
82 {
83 myPtrCur = theToEnd ? myPtrEnd : const_cast<TheItemType*> (&theArray.First());
84 }
85
7fd59977 86 //! Initialisation
87 void Init (const NCollection_Array1& theArray)
88 {
79a35943 89 myPtrCur = const_cast<TheItemType*> (&theArray.First());
90 myPtrEnd = const_cast<TheItemType*> (&theArray.Last() + 1);
7fd59977 91 }
79a35943 92
93 //! Assignment
94 Iterator& operator= (const Iterator& theOther)
95 {
96 myPtrCur = theOther.myPtrCur;
97 myPtrEnd = theOther.myPtrEnd;
98 return *this;
99 }
100
7fd59977 101 //! Check end
ddf2fe8e 102 Standard_Boolean More (void) const
79a35943 103 { return myPtrCur < myPtrEnd; }
104
105 //! Increment operator
ddf2fe8e 106 void Next (void)
79a35943 107 { ++myPtrCur; }
108
109 //! Decrement operator
ddf2fe8e 110 void Previous()
79a35943 111 { --myPtrCur; }
112
113 //! Offset operator.
ddf2fe8e 114 void Offset (ptrdiff_t theOffset)
79a35943 115 { myPtrCur += theOffset; }
116
117 //! Difference operator.
ddf2fe8e 118 ptrdiff_t Differ (const Iterator& theOther) const
79a35943 119 { return myPtrCur - theOther.myPtrCur; }
120
7fd59977 121 //! Constant value access
ddf2fe8e 122 const TheItemType& Value (void) const
79a35943 123 { return *myPtrCur; }
124
7fd59977 125 //! Variable value access
ddf2fe8e 126 TheItemType& ChangeValue (void) const
79a35943 127 { return *myPtrCur; }
128
129 //! Performs comparison of two iterators
ddf2fe8e 130 Standard_Boolean IsEqual (const Iterator& theOther) const
79a35943 131 { return myPtrCur == theOther.myPtrCur; }
132
7fd59977 133 private:
79a35943 134 TheItemType* myPtrCur; //!< Pointer to the current element in the array
135 TheItemType* myPtrEnd; //!< Pointer to the past-the-end element in the array
7fd59977 136 }; // End of the nested class Iterator
137
79a35943 138 //! Shorthand for a regular iterator type.
139 typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, false> iterator;
140
141 //! Shorthand for a constant iterator type.
142 typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, true> const_iterator;
143
144 //! Returns an iterator pointing to the first element in the array.
145 iterator begin() const { return Iterator (*this, false); }
146
147 //! Returns an iterator referring to the past-the-end element in the array.
148 iterator end() const { return Iterator (*this, true); }
149
150 //! Returns a const iterator pointing to the first element in the array.
151 const_iterator cbegin() const { return Iterator (*this, false); }
152
153 //! Returns a const iterator referring to the past-the-end element in the array.
154 const_iterator cend() const { return Iterator (*this, true); }
155
7fd59977 156 public:
157 // ---------- PUBLIC METHODS ------------
158
159 //! Constructor
160 NCollection_Array1(const Standard_Integer theLower,
161 const Standard_Integer theUpper) :
7fd59977 162 myLowerBound (theLower),
163 myUpperBound (theUpper),
164 myDeletable (Standard_True)
165 {
166#if !defined No_Exception && !defined No_Standard_RangeError
167 if (theUpper < theLower)
168 Standard_RangeError::Raise ("NCollection_Array1::Create");
169#endif
170 TheItemType* pBegin = new TheItemType[Length()];
171#if !defined No_Exception && !defined No_Standard_OutOfMemory
172 if (!pBegin)
173 Standard_OutOfMemory::Raise ("NCollection_Array1 : Allocation failed");
174#endif
175
176 myData = pBegin - theLower;
177 }
178
179 //! Copy constructor
180 NCollection_Array1 (const NCollection_Array1& theOther) :
7fd59977 181 myLowerBound (theOther.Lower()),
182 myUpperBound (theOther.Upper()),
183 myDeletable (Standard_True)
184 {
185 TheItemType* pBegin = new TheItemType[Length()];
186#if !defined No_Exception && !defined No_Standard_OutOfMemory
187 if (!pBegin)
188 Standard_OutOfMemory::Raise ("NCollection_Array1 : Allocation failed");
189#endif
190 myData = pBegin - myLowerBound;
191
192 *this = theOther;
193 }
194
195 //! C array-based constructor
196 NCollection_Array1 (const TheItemType& theBegin,
197 const Standard_Integer theLower,
198 const Standard_Integer theUpper) :
7fd59977 199 myLowerBound (theLower),
200 myUpperBound (theUpper),
201 myDeletable (Standard_False)
202 {
203#if !defined No_Exception && !defined No_Standard_RangeError
204 if (theUpper < theLower)
205 Standard_RangeError::Raise ("NCollection_Array1::Array1");
206#endif
207 myData = (TheItemType *) &theBegin - theLower;
208 }
209
210 //! Initialise the items with theValue
211 void Init (const TheItemType& theValue)
212 {
213 TheItemType *pCur = &myData[myLowerBound], *pEnd=&myData[myUpperBound];
214 for(; pCur <= pEnd; pCur++)
215 *pCur = (TheItemType&) theValue;
216 }
217
218 //! Size query
ddf2fe8e 219 Standard_Integer Size (void) const
7fd59977 220 { return Length(); }
221 //! Length query (the same)
222 Standard_Integer Length (void) const
223 { return (myUpperBound-myLowerBound+1); }
224
225 //! Lower bound
226 Standard_Integer Lower (void) const
227 { return myLowerBound; }
228 //! Upper bound
229 Standard_Integer Upper (void) const
230 { return myUpperBound; }
231
232 //! myDeletable flag
233 Standard_Boolean IsDeletable (void) const
234 { return myDeletable; }
235
236 //! IsAllocated flag - for naming compatibility
237 Standard_Boolean IsAllocated (void) const
238 { return myDeletable; }
239
ddf2fe8e 240 //! Assignment
241 NCollection_Array1& Assign (const NCollection_Array1& theOther)
7fd59977 242 {
243 if (&theOther == this)
244 return *this;
245#if !defined No_Exception && !defined No_Standard_DimensionMismatch
246 if (Length() != theOther.Length())
247 Standard_DimensionMismatch::Raise ("NCollection_Array1::operator=");
248#endif
249 TheItemType * pMyItem = &myData[myLowerBound];
250 TheItemType * const pEndItem = &(theOther.myData)[theOther.myUpperBound];
251 TheItemType * pItem = &(theOther.myData)[theOther.myLowerBound];
252 while (pItem <= pEndItem) * pMyItem ++ = * pItem ++;
253 return *this;
254 }
255
ddf2fe8e 256 //! Assignment operator
257 NCollection_Array1& operator= (const NCollection_Array1& theOther)
258 {
259 return Assign (theOther);
260 }
261
a174a3c5 262 //! @return first element
263 const TheItemType& First() const
264 {
265 return myData[myLowerBound];
266 }
267
268 //! @return first element
269 TheItemType& ChangeFirst()
270 {
271 return myData[myLowerBound];
272 }
273
274 //! @return last element
275 const TheItemType& Last() const
276 {
277 return myData[myUpperBound];
278 }
279
280 //! @return last element
281 TheItemType& ChangeLast()
282 {
283 return myData[myUpperBound];
284 }
285
7fd59977 286 //! Constant value access
287 const TheItemType& Value (const Standard_Integer theIndex) const
288 {
289#if !defined No_Exception && !defined No_Standard_OutOfRange
290 if (theIndex < myLowerBound || theIndex > myUpperBound)
291 Standard_OutOfRange::Raise ("NCollection_Array1::Value");
292#endif
293 return myData[theIndex];
294 }
295
296 //! operator() - alias to Value
297 const TheItemType& operator() (const Standard_Integer theIndex) const
298 { return Value (theIndex); }
299
300 //! Variable value access
301 TheItemType& ChangeValue (const Standard_Integer theIndex)
302 {
303#if !defined No_Exception && !defined No_Standard_OutOfRange
304 if (theIndex < myLowerBound || theIndex > myUpperBound)
305 Standard_OutOfRange::Raise ("NCollection_Array1::ChangeValue");
306#endif
307 return myData[theIndex];
308 }
309
310 //! operator() - alias to ChangeValue
311 TheItemType& operator() (const Standard_Integer theIndex)
312 { return ChangeValue (theIndex); }
313
314 //! Set value
315 void SetValue (const Standard_Integer theIndex,
316 const TheItemType& theItem)
317 {
318#if !defined No_Exception && !defined No_Standard_OutOfRange
319 if (theIndex < myLowerBound || theIndex > myUpperBound)
320 Standard_OutOfRange::Raise ("NCollection_Array1::SetValue");
321#endif
322 myData[theIndex] = theItem;
323 }
324
325 //! Destructor - releases the memory
326 ~NCollection_Array1 (void)
327 { if (myDeletable) delete [] &(myData[myLowerBound]); }
328
7fd59977 329 protected:
330 // ---------- PROTECTED FIELDS -----------
331 Standard_Integer myLowerBound;
332 Standard_Integer myUpperBound;
333 Standard_Boolean myDeletable; //!< Flag showing who allocated the array
334 TheItemType* myData; //!< Pointer to '0'th array item
335};
336
7fd59977 337#endif