0024512: clang++ compiler complains about extra semicolon
[occt.git] / src / NCollection / NCollection_SparseArray.hxx
1 // Created on: 2006-11-23
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2006-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
8 // under the terms of the GNU Lesser General Public 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_SparseArray_HeaderFile
17 #define NCollection_SparseArray_HeaderFile
18
19 #include <NCollection_SparseArrayBase.hxx>
20
21 /**
22 * Dynamically resizable sparse array of objects
23 *
24 * This class is similar to NCollection_Vector: it works like virtually
25 * unlimited array of items accessible by index; however unlike simple
26 * Vector it distinguishes items that have been set from the ones that
27 * have not been set explicitly.
28 *
29 * This class can be also seen as equivalence of
30 * NCollection_DataMap<Standard_Integer,TheItemType>
31 * with the only one practical difference: it can be much less 
32 * memory-expensive if items are small (e.g. Integer or Handle).
33
34 * The index starts from 0, i.e. should be non-negative. Memory is allocated
35 * when item is set by SetValue(). 
36 *
37 * Iterator returns only defined items; 
38 * the item can be tested for being defined by IsSet(), 
39 * and undefined by UnsetValue().
40 *
41 * The attempt to access the item that has not been set will result
42 * in OutOfRange exception in Debug mode; in Release mode this will either
43 * return null-filled object or cause access violation.
44 */
45
46 template <class TheItemType> class NCollection_SparseArray 
47                                  : public NCollection_SparseArrayBase
48 {
49 public:
50
51   //! Constructor; accepts size of blocks 
52   NCollection_SparseArray (Standard_Size theIncrement)
53     : NCollection_SparseArrayBase(sizeof(TheItemType),theIncrement)
54   { 
55   }
56
57   //! Explicit assignment operator
58   NCollection_SparseArray& Assign (const NCollection_SparseArray& theOther) 
59   {
60     this->assign (theOther);
61     return *this;
62   }
63
64   //! Exchange the data of two arrays;
65   //! can be used primarily to move contents of theOther into the new array
66   //! in a fast way (without creation of duplicated data)
67   void Exchange (NCollection_SparseArray& theOther) 
68   {
69     this->exchange (theOther);
70   }
71
72   //! Destructor
73   virtual ~NCollection_SparseArray ()
74   {
75     Clear();
76   }
77
78 public:
79   //!@name Array-like interface (in addition to inherited methods)
80   //!@{
81
82   //! Direct const access to the item 
83   const TheItemType& Value (const Standard_Size theIndex) const 
84   {
85     return *(const TheItemType*)this->getValue(theIndex);
86   }
87
88   //! Const access to the item - operator()
89   const TheItemType& operator () (const Standard_Size theIndex) const
90   { 
91     return Value (theIndex); 
92   }
93
94   //! Modification access to the item
95   TheItemType& ChangeValue (const Standard_Size theIndex) 
96   {
97     return *(TheItemType*)(this->getValue (theIndex));
98   }
99
100   //! Access to the item - operator()
101   TheItemType& operator () (const Standard_Size theIndex)
102   { 
103     return ChangeValue (theIndex); 
104   }
105   
106   //! Set a value at specified index method
107   TheItemType& SetValue (const Standard_Size theIndex,
108                          const TheItemType&     theValue) 
109   {
110     return *(TheItemType*)this->setValue(theIndex, (Standard_Address)&theValue);
111   }
112
113   //!@}
114   
115 public:
116   //!@name DataMap-like interface
117   //!@{
118
119   //! Returns number of items in the array
120   Standard_Size Extent () const 
121   {
122     return Size();
123   }
124
125   //! Returns True if array is empty
126   Standard_Boolean IsEmpty () const 
127   {
128     return Size() == 0;
129   }
130
131   //! Direct const access to the item 
132   const TheItemType& Find (const Standard_Size theIndex) const 
133   {
134     return *(TheItemType*)this->getValue(theIndex);
135   }
136
137   //! Modification access to the item; allocates space if 
138   //! necessary and marks the item as defined
139   TheItemType& ChangeFind (const Standard_Size theIndex) 
140   {
141     return *(TheItemType*)(this->changeValue (theIndex));
142   }
143
144   //! Set a value as explicit method
145   TheItemType& Bind (const Standard_Size theIndex,
146                      const TheItemType&     theValue) 
147   {
148     return SetValue(theIndex, theValue);
149   }
150   
151   //! Returns True if the item is defined
152   Standard_Boolean IsBound (const Standard_Size theIndex) const
153   {
154     return this->HasValue(theIndex);
155   }
156   
157   //! Remove the item from array
158   Standard_Boolean UnBind (const Standard_Size theIndex) 
159   {
160     return this->UnsetValue(theIndex);
161   }
162   
163   //!@}
164
165 public:
166   // Iterator interface
167
168   /**
169    * Implementation of type-specific const Iterator class
170    */
171   class ConstIterator : public NCollection_SparseArrayBase::Iterator
172   {
173   public:
174
175     //! Empty constructor - for later Init
176     ConstIterator () {}
177
178     //! Constructor with initialisation
179     ConstIterator (const NCollection_SparseArray& theVector) :
180       NCollection_SparseArrayBase::Iterator (&theVector) {}
181
182     //! Initialisation
183     void Init (const NCollection_SparseArray& theVector) 
184     { 
185       this->init (&theVector); 
186     } 
187
188     //! Constant value access
189     const TheItemType& Value (void) const
190     {
191       return *(const TheItemType*)this->value(); 
192     }
193
194     //! Constant value access operator
195     const TheItemType& operator () (void) const
196     {
197       return *(const TheItemType*)this->value(); 
198     }
199
200     //! Access current index with 'a-la map' interface
201     Standard_Size Key (void) const { return Index(); }
202   };
203
204   /**
205    * Implementation of type-specific non-const Iterator class
206    */
207   class Iterator : public ConstIterator
208   {
209   public:
210
211     //! Empty constructor - for later Init
212     Iterator () {}
213
214     //! Constructor with initialisation
215     Iterator (NCollection_SparseArray& theVector) :
216       ConstIterator (theVector) {}
217
218     //! Initialisation
219     void Init (const NCollection_SparseArray& theVector) 
220     { 
221       this->init (&theVector); 
222     } 
223
224     //! Value access
225     TheItemType& ChangeValue (void)
226     {
227       return *(TheItemType*)this->value(); 
228     }
229
230     //! Value access operator
231     TheItemType& operator () (void)
232     {
233       return *(TheItemType*)this->value(); 
234     }
235
236     //! Const access operator - the same as in parent class
237     const TheItemType& operator () (void) const
238     {
239       return *(const TheItemType*)this->value(); 
240     }
241   };
242
243 private:
244   // Implementation of virtual methods providing type-specific behaviour
245
246   //! Create new item at the specified address with default constructor
247 //  virtual void createItem (Standard_Address theAddress) 
248 //  {
249 //    new (theAddress) TheItemType;
250 //  }
251   
252   //! Create new item at the specified address with copy constructor
253   //! from existing item
254   virtual void createItem (Standard_Address theAddress, Standard_Address theOther)
255   {
256     new (theAddress) TheItemType(*(const TheItemType*)theOther);
257   }
258   
259   //! Call destructor to the item at given address
260   virtual void destroyItem (Standard_Address theAddress)
261   {
262     ((TheItemType*)theAddress)->TheItemType::~TheItemType();
263   }
264
265   //! Call assignment operator to the item
266   virtual void copyItem (Standard_Address theAddress, Standard_Address theOther)
267   {
268     (*(TheItemType*)theAddress) = *(const TheItemType*)theOther;
269   }
270
271 };
272
273 #endif
274