summaryrefslogtreecommitdiff
path: root/inc/NCollection_SparseArray.hxx
blob: 456481ba28f47e9268376f744df2172d67c7f60f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
// File:      NCollection_SparseArray.hxx
// Created:   23.11.06 11:12:02
// Author:    Andrey BETENEV
// Copyright: Open Cascade 2006

#ifndef NCollection_SparseArray_HeaderFile
#define NCollection_SparseArray_HeaderFile

#include <NCollection_SparseArrayBase.hxx>

#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif

/**
* Dynamically resizable sparse array of objects
*
* This class is similar to NCollection_Vector: it works like virtually
* unlimited array of items accessible by index; however unlike simple
* Vector it distinguishes items that have been set from the ones that
* have not been set explicitly.
*
* This class can be also seen as equivalence of
* NCollection_DataMap<Standard_Integer,TheItemType>
* with the only one practical difference: it can be much less 
* memory-expensive if items are small (e.g. Integer or Handle).
* 
* The index starts from 0, i.e. should be non-negative. Memory is allocated
* when item is set by SetValue(). 
*
* Iterator returns only defined items; 
* the item can be tested for being defined by IsSet(), 
* and undefined by UnsetValue().
*
* The attempt to access the item that has not been set will result
* in OutOfRange exception in Debug mode; in Release mode this will either
* return null-filled object or cause access violation.
*/

template <class TheItemType> class NCollection_SparseArray 
                                 : public NCollection_SparseArrayBase
{
public:

  //! Constructor; accepts size of blocks 
  NCollection_SparseArray (Standard_Size theIncrement)
    : NCollection_SparseArrayBase(sizeof(TheItemType),theIncrement)
  { 
  }

  //! Explicit assignment operator
  NCollection_SparseArray& Assign (const NCollection_SparseArray& theOther) 
  {
    this->assign (theOther);
    return *this;
  }

  //! Exchange the data of two arrays;
  //! can be used primarily to move contents of theOther into the new array
  //! in a fast way (without creation of duplicated data)
  void Exchange (NCollection_SparseArray& theOther) 
  {
    this->exchange (theOther);
  }

  //! Destructor
  virtual ~NCollection_SparseArray ()
  {
    Clear();
  }

public:
  //!@name Array-like interface (in addition to inherited methods)
  //!@{

  //! Direct const access to the item 
  const TheItemType& Value (const Standard_Integer theIndex) const 
  {
    return *(const TheItemType*)this->getValue(theIndex);
  }

  //! Const access to the item - operator()
  const TheItemType& operator () (const Standard_Integer theIndex) const
  { 
    return Value (theIndex); 
  }

  //! Modification access to the item
  TheItemType& ChangeValue (const Standard_Integer theIndex) 
  {
    return *(TheItemType*)(this->getValue (theIndex));
  }

  //! Access to the item - operator()
  TheItemType& operator () (const Standard_Integer theIndex)
  { 
    return ChangeValue (theIndex); 
  }
  
  //! Set a value at specified index method
  TheItemType& SetValue (const Standard_Integer theIndex,
                         const TheItemType&     theValue) 
  {
    return *(TheItemType*)this->setValue(theIndex, (Standard_Address)&theValue);
  }

  //!@}
  
public:
  //!@name DataMap-like interface
  //!@{

  //! Returns number of items in the array
  Standard_Size Extent () const 
  {
    return Size();
  }

  //! Returns True if array is empty
  Standard_Boolean IsEmpty () const 
  {
    return Size() == 0;
  }

  //! Direct const access to the item 
  const TheItemType& Find (const Standard_Integer theIndex) const 
  {
    return *(TheItemType*)this->getValue(theIndex);
  }

  //! Modification access to the item; allocates space if 
  //! necessary and marks the item as defined
  TheItemType& ChangeFind (const Standard_Integer theIndex) 
  {
    return *(TheItemType*)(this->changeValue (theIndex));
  }

  //! Set a value as explicit method
  TheItemType& Bind (const Standard_Integer theIndex,
		     const TheItemType&     theValue) 
  {
    return SetValue(theIndex, theValue);
  }
  
  //! Returns True if the item is defined
  Standard_Boolean IsBound (const Standard_Integer theIndex) const
  {
    return this->HasValue(theIndex);
  }
  
  //! Remove the item from array
  Standard_Boolean UnBind (const Standard_Integer theIndex) 
  {
    return this->UnsetValue(theIndex);
  }
  
  //!@}

public:
  // Iterator interface

  /**
   * Implementation of type-specific const Iterator class
   */
  class ConstIterator : public NCollection_SparseArrayBase::Iterator
  {
  public:

    //! Empty constructor - for later Init
    ConstIterator () {}

    //! Constructor with initialisation
    ConstIterator (const NCollection_SparseArray& theVector) :
      NCollection_SparseArrayBase::Iterator (&theVector) {}

    //! Initialisation
    void Init (const NCollection_SparseArray& theVector) 
    { 
      this->init (&theVector); 
    } 

    //! Constant value access
    const TheItemType& Value (void) const
    {
      return *(const TheItemType*)this->value(); 
    }

    //! Constant value access operator
    const TheItemType& operator () (void) const
    {
      return *(const TheItemType*)this->value(); 
    }

    //! Access current index with 'a-la map' interface
    Standard_Integer Key (void) const { return Index(); }
  };

  /**
   * Implementation of type-specific non-const Iterator class
   */
  class Iterator : public ConstIterator
  {
  public:

    //! Empty constructor - for later Init
    Iterator () {}

    //! Constructor with initialisation
    Iterator (NCollection_SparseArray& theVector) :
      ConstIterator (theVector) {}

    //! Initialisation
    void Init (const NCollection_SparseArray& theVector) 
    { 
      this->init (&theVector); 
    } 

    //! Value access
    TheItemType& ChangeValue (void)
    {
      return *(TheItemType*)this->value(); 
    }

    //! Value access operator
    TheItemType& operator () (void)
    {
      return *(TheItemType*)this->value(); 
    }

    //! Const access operator - the same as in parent class
    const TheItemType& operator () (void) const
    {
      return *(const TheItemType*)this->value(); 
    }
  };

private:
  // Implementation of virtual methods providing type-specific behaviour

  //! Create new item at the specified address with default constructor
//  virtual void createItem (Standard_Address theAddress) 
//  {
//    new (theAddress) TheItemType;
//  }
  
  //! Create new item at the specified address with copy constructor
  //! from existing item
  virtual void createItem (Standard_Address theAddress, Standard_Address theOther)
  {
    new (theAddress) TheItemType(*(const TheItemType*)theOther);
  }
  
  //! Call destructor to the item at given address
  virtual void destroyItem (Standard_Address theAddress)
  {
    ((TheItemType*)theAddress)->TheItemType::~TheItemType();
  }

  //! Call assignment operator to the item
  virtual void copyItem (Standard_Address theAddress, Standard_Address theOther)
  {
    (*(TheItemType*)theAddress) = *(const TheItemType*)theOther;
  }

};

#ifdef WNT
#pragma warning (pop)
#endif

#endif