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