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