b311480e |
1 | // Created on: 2006-11-23 |
2 | // Created by: Andrey BETENEV |
973c2be1 |
3 | // Copyright (c) 2006-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_SparseArray_HeaderFile |
17 | #define NCollection_SparseArray_HeaderFile |
18 | |
19 | #include <NCollection_SparseArrayBase.hxx> |
20 | |
7fd59977 |
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 |
d93f7683 |
83 | const TheItemType& Value (const Standard_Size theIndex) const |
7fd59977 |
84 | { |
85 | return *(const TheItemType*)this->getValue(theIndex); |
86 | } |
87 | |
88 | //! Const access to the item - operator() |
d93f7683 |
89 | const TheItemType& operator () (const Standard_Size theIndex) const |
7fd59977 |
90 | { |
91 | return Value (theIndex); |
92 | } |
93 | |
94 | //! Modification access to the item |
d93f7683 |
95 | TheItemType& ChangeValue (const Standard_Size theIndex) |
7fd59977 |
96 | { |
97 | return *(TheItemType*)(this->getValue (theIndex)); |
98 | } |
99 | |
100 | //! Access to the item - operator() |
d93f7683 |
101 | TheItemType& operator () (const Standard_Size theIndex) |
7fd59977 |
102 | { |
103 | return ChangeValue (theIndex); |
104 | } |
105 | |
106 | //! Set a value at specified index method |
d93f7683 |
107 | TheItemType& SetValue (const Standard_Size theIndex, |
7fd59977 |
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 |
d93f7683 |
132 | const TheItemType& Find (const Standard_Size theIndex) const |
7fd59977 |
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 |
d93f7683 |
139 | TheItemType& ChangeFind (const Standard_Size theIndex) |
7fd59977 |
140 | { |
141 | return *(TheItemType*)(this->changeValue (theIndex)); |
142 | } |
143 | |
144 | //! Set a value as explicit method |
d93f7683 |
145 | TheItemType& Bind (const Standard_Size theIndex, |
7fd59977 |
146 | const TheItemType& theValue) |
147 | { |
148 | return SetValue(theIndex, theValue); |
149 | } |
150 | |
151 | //! Returns True if the item is defined |
d93f7683 |
152 | Standard_Boolean IsBound (const Standard_Size theIndex) const |
7fd59977 |
153 | { |
154 | return this->HasValue(theIndex); |
155 | } |
156 | |
157 | //! Remove the item from array |
d93f7683 |
158 | Standard_Boolean UnBind (const Standard_Size theIndex) |
7fd59977 |
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 |
d93f7683 |
201 | Standard_Size Key (void) const { return Index(); } |
7fd59977 |
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 | |
7fd59977 |
273 | #endif |
274 | |