0024971: Incomplete interface of NCollection classes
[occt.git] / src / NCollection / NCollection_Array2.hxx
1 // Created on: 2002-04-15
2 // Created by: Alexander Kartomin (akm)
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef NCollection_Array2_HeaderFile
17 #define NCollection_Array2_HeaderFile
18
19 #include <Standard_DimensionMismatch.hxx>
20 #include <Standard_OutOfMemory.hxx>
21 #include <Standard_OutOfRange.hxx>
22
23 #include <NCollection_DefineAlloc.hxx>
24
25 // *********************************************** Template for Array2 class
26 /**
27 * Purpose:   The class Array2 represents bi-dimensional arrays 
28 *            of fixed size known at run time. 
29 *            The ranges of indices are user defined.
30 *            
31 * Warning:   Programs clients of such class must be independant
32 *            of the range of the first element. Then, a C++ for
33 *            loop must be written like this
34 *            
35 *            for (i = A.LowerRow(); i <= A.UpperRow(); i++)
36 *              for (j = A.LowerCol(); j <= A.UpperCol(); j++)
37 */            
38 template <class TheItemType>
39 class NCollection_Array2
40 {
41 public:
42   //! STL-compliant typedef for value type
43   typedef TheItemType value_type;
44
45 public:
46   // **************** Implementation of the Iterator interface.
47   class Iterator
48   {
49   public:
50     //! Empty constructor - for later Init
51     Iterator (void) :
52       myCurrent (0),
53       mySize    (0),
54       myArray   (NULL) {}
55     //! Constructor with initialisation
56     Iterator  (const NCollection_Array2& theArray) :
57       myCurrent (0),
58       mySize    (theArray.Length()),
59       myArray   ((NCollection_Array2 *) &theArray) {}
60     //! Initialisation
61     void Init (const NCollection_Array2& theArray)
62     { 
63       myCurrent = 0;
64       mySize    = theArray.Length();
65       myArray   = (NCollection_Array2 *) &theArray; 
66     }
67     //! Check end
68     Standard_Boolean More (void) const
69     { return (myCurrent < mySize); }
70     //! Make step
71     void Next (void)
72     { myCurrent++; }
73     //! Constant value access
74     const TheItemType& Value (void) const
75     { return myArray->myStart[myCurrent]; }
76     //! Variable value access
77     TheItemType& ChangeValue (void) const
78     { return myArray->myStart[myCurrent]; }
79   private:
80     Standard_Integer    myCurrent;  //!< Index of the current item
81     Standard_Integer    mySize;     //!< Total amount of items
82     NCollection_Array2* myArray;    //!< Pointer to the array being iterated
83   }; // End of nested class Iterator
84
85  public:
86   // ---------- PUBLIC METHODS ------------
87
88   //! Constructor
89   NCollection_Array2(const Standard_Integer theRowLower,
90                      const Standard_Integer theRowUpper,
91                      const Standard_Integer theColLower,
92                      const Standard_Integer theColUpper) :
93     myLowerRow                                  (theRowLower),
94     myUpperRow                                  (theRowUpper),
95     myLowerCol                                  (theColLower),
96     myUpperCol                                  (theColUpper),
97     myDeletable                                 (Standard_True)
98   { Allocate(); }
99
100   //! Copy constructor 
101   NCollection_Array2 (const NCollection_Array2& theOther) :
102     myLowerRow                                  (theOther.LowerRow()),
103     myUpperRow                                  (theOther.UpperRow()),
104     myLowerCol                                  (theOther.LowerCol()),
105     myUpperCol                                  (theOther.UpperCol()),
106     myDeletable                                 (Standard_True)
107   {
108     Allocate();
109     *this = theOther;
110   }
111
112   //! C array-based constructor
113   NCollection_Array2(const TheItemType&     theBegin,
114                      const Standard_Integer theRowLower,
115                      const Standard_Integer theRowUpper,
116                      const Standard_Integer theColLower,
117                      const Standard_Integer theColUpper) :
118     myLowerRow                                  (theRowLower),
119     myUpperRow                                  (theRowUpper),
120     myLowerCol                                  (theColLower),
121     myUpperCol                                  (theColUpper),
122     myDeletable                                 (Standard_False)
123   {
124     myStart = (TheItemType *) &theBegin;
125     Allocate();
126   }
127
128   //! Initialise the values
129   void Init (const TheItemType& theValue) 
130   {
131     TheItemType *pCur, *pEnd=myStart+Size();
132     for(pCur = myStart; pCur<pEnd; pCur++)
133       *pCur = theValue;
134   }
135
136   //! Size (number of items)
137   Standard_Integer Size (void) const
138   { return Length(); }
139   //! Length (number of items)
140   Standard_Integer Length (void) const
141   { return RowLength() * ColLength(); }
142
143   //! RowLength 
144   Standard_Integer RowLength (void) const
145   { return (myUpperCol-myLowerCol+1); }
146   //! ColLength 
147   Standard_Integer ColLength (void) const
148   { return (myUpperRow-myLowerRow+1); }
149
150   //! LowerRow
151   Standard_Integer LowerRow (void) const
152   { return myLowerRow; }
153   //! UpperRow
154   Standard_Integer UpperRow (void) const
155   { return myUpperRow; }
156   //! LowerCol
157   Standard_Integer LowerCol (void) const
158   { return myLowerCol; }
159   //! UpperCol
160   Standard_Integer UpperCol (void) const
161   { return myUpperCol; }
162
163   //! myDeletable flag
164   Standard_Boolean IsDeletable (void) const
165   { return myDeletable; }
166
167   //! Assignment
168   NCollection_Array2& Assign (const NCollection_Array2& theOther)
169   { 
170     if (&theOther == this)
171       return *this;
172     Standard_DimensionMismatch_Raise_if (Length() != theOther.Length(), "NCollection_Array2::operator=");
173     TheItemType * pMyItem  = myStart;
174     TheItemType * pItem    = theOther.myStart;
175     const Standard_Integer iSize = Length();
176     for (Standard_Integer i=0; i < iSize; i++, pItem++, pMyItem++)
177       *pMyItem = *pItem;
178     return *this; 
179   }
180
181   //! Assignment operator
182   NCollection_Array2& operator= (const NCollection_Array2& theOther)
183   { 
184     return Assign (theOther);
185   }
186
187   //! Constant value access
188   const TheItemType& Value (const Standard_Integer theRow,
189                             const Standard_Integer theCol) const
190   {
191     Standard_OutOfRange_Raise_if (theRow < myLowerRow || theRow > myUpperRow ||
192                                   theCol < myLowerCol || theCol > myUpperCol, "NCollection_Array2::Value");
193     return myData[theRow][theCol];
194   }
195
196   //! operator() - alias to ChangeValue
197   const TheItemType& operator() (const Standard_Integer theRow,
198                                  const Standard_Integer theCol) const
199   { return Value (theRow,theCol); }
200
201   //! Variable value access
202   TheItemType& ChangeValue (const Standard_Integer theRow,
203                             const Standard_Integer theCol)
204   {
205     Standard_OutOfRange_Raise_if (theRow < myLowerRow || theRow > myUpperRow ||
206                                   theCol < myLowerCol || theCol > myUpperCol, "NCollection_Array2::ChangeValue");
207     return myData[theRow][theCol];
208   }
209
210   //! operator() - alias to ChangeValue
211   TheItemType& operator() (const Standard_Integer theRow,
212                            const Standard_Integer theCol)
213   { return ChangeValue (theRow,theCol); }
214
215   //! SetValue
216   void SetValue (const Standard_Integer theRow,
217                  const Standard_Integer theCol,
218                  const TheItemType&     theItem)
219   {
220     Standard_OutOfRange_Raise_if (theRow < myLowerRow || theRow > myUpperRow ||
221                                   theCol < myLowerCol || theCol > myUpperCol, "NCollection_Array2::SetValue");
222     myData[theRow][theCol] = theItem;
223   }
224   
225   //! Destructor - releases the memory
226   ~NCollection_Array2 (void)
227   { 
228     if (myDeletable) delete [] myStart;
229     delete [] &(myData[myLowerRow]);
230   }
231
232  private:
233   // ----------- PRIVATE METHODS -----------
234
235   //! Allocate memory for the array, set up indirection table
236   void Allocate (void)
237   {
238     const Standard_Integer iRowSize = myUpperCol - myLowerCol + 1;
239     const Standard_Integer iColSize = myUpperRow - myLowerRow + 1;
240     Standard_RangeError_Raise_if (iRowSize <= 0  || iColSize <= 0, "NCollection_Array2::Allocate");
241     if (myDeletable) {
242       // allocation of the data in the array
243       myStart = new TheItemType[iRowSize * iColSize];
244       Standard_OutOfMemory_Raise_if (!myStart, "NCollection_Array2 : Allocation failed");
245     }
246     // else myStart is set to the beginning of the given array
247     TheItemType** pTable = new TheItemType* [iColSize];
248     Standard_OutOfMemory_Raise_if (!pTable, "NCollection_Array2 : Allocation failed");
249
250     // Items of pTable point to the '0'th items in the rows of the array
251     TheItemType* pRow = myStart - myLowerCol;
252     for (Standard_Integer i = 0; i < iColSize; i++) 
253     {
254       pTable[i] = pRow;
255       pRow += iRowSize;
256     }
257
258     // Set myData to the '0'th row pointer of the pTable
259     myData = pTable - myLowerRow;
260   }
261
262  protected:
263   // ---------- PROTECTED FIELDS -----------
264   Standard_Integer myLowerRow;
265   Standard_Integer myUpperRow;
266   Standard_Integer myLowerCol;
267   Standard_Integer myUpperCol;
268
269   TheItemType**    myData;      //!< Pointer to the row pointers table
270   TheItemType*     myStart;     //!< Pointer to the memory array
271   Standard_Boolean myDeletable; //!< Flag showing who allocated the array
272
273   // ----------- FRIEND CLASSES ------------
274  friend class Iterator;
275
276 };
277
278 #endif