Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-04 09:15:26

0001 // Created on: 2006-11-23
0002 // Created by: Andrey BETENEV
0003 // Copyright (c) 2006-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef NCollection_SparseArray_HeaderFile
0017 #define NCollection_SparseArray_HeaderFile
0018 
0019 #include <NCollection_SparseArrayBase.hxx>
0020 
0021 /**
0022  * Dynamically resizable sparse array of objects
0023  *
0024  * This class is similar to NCollection_DynamicArray: it works like virtually
0025  * unlimited array of items accessible by index; however unlike simple
0026  * Vector it distinguishes items that have been set from the ones that
0027  * have not been set explicitly.
0028  *
0029  * This class can be also seen as equivalence of
0030  * NCollection_DataMap<int,TheItemType>
0031  * with the only one practical difference: it can be much less
0032  * memory-expensive if items are small (e.g. Integer or Handle).
0033  *
0034  * The index starts from 0, i.e. should be non-negative. Memory is allocated
0035  * when item is set by SetValue().
0036  *
0037  * Iterator returns only defined items;
0038  * the item can be tested for being defined by IsSet(),
0039  * and undefined by UnsetValue().
0040  *
0041  * The attempt to access the item that has not been set will result
0042  * in OutOfRange exception in Debug mode; in Release mode this will either
0043  * return null-filled object or cause access violation.
0044  */
0045 
0046 template <class TheItemType>
0047 class NCollection_SparseArray : public NCollection_SparseArrayBase
0048 {
0049 public:
0050   //! Constructor; accepts size of blocks
0051   explicit NCollection_SparseArray(size_t theIncrement) noexcept
0052       : NCollection_SparseArrayBase(sizeof(TheItemType), theIncrement, destroyItemImpl)
0053   {
0054   }
0055 
0056   //! Explicit assignment operator
0057   NCollection_SparseArray& Assign(const NCollection_SparseArray& theOther)
0058   {
0059     if (this == &theOther)
0060       return *this;
0061     this->assign(theOther, createItemImpl, destroyItemImpl, copyItemImpl);
0062     return *this;
0063   }
0064 
0065   //! Exchange the data of two arrays;
0066   //! can be used primarily to move contents of theOther into the new array
0067   //! in a fast way (without creation of duplicated data)
0068   void Exchange(NCollection_SparseArray& theOther) noexcept { this->exchange(theOther); }
0069 
0070   //! Clears all the data
0071   void Clear() { clearItems(destroyItemImpl); }
0072 
0073 public:
0074   //!@name Array-like interface (in addition to inherited methods)
0075   //!@{
0076 
0077   //! Direct const access to the item
0078   const TheItemType& Value(const size_t theIndex) const
0079   {
0080     return *(const TheItemType*)this->getValue(theIndex);
0081   }
0082 
0083   //! Const access to the item - operator()
0084   const TheItemType& operator()(const size_t theIndex) const { return Value(theIndex); }
0085 
0086   //! Modification access to the item
0087   TheItemType& ChangeValue(const size_t theIndex)
0088   {
0089     return *(TheItemType*)(this->getValue(theIndex));
0090   }
0091 
0092   //! Access to the item - operator()
0093   TheItemType& operator()(const size_t theIndex) { return ChangeValue(theIndex); }
0094 
0095   //! Set a value at specified index method
0096   TheItemType& SetValue(const size_t theIndex, const TheItemType& theValue)
0097   {
0098     return *(TheItemType*)this->setValue(theIndex, (void*)&theValue, createItemImpl, copyItemImpl);
0099   }
0100 
0101   //! Deletes the item from the array;
0102   //! returns True if that item was defined
0103   bool UnsetValue(const size_t theIndex) { return this->unsetValue(theIndex, destroyItemImpl); }
0104 
0105   //!@}
0106 
0107 public:
0108   //!@name DataMap-like interface
0109   //!@{
0110 
0111   //! Returns number of items in the array
0112   size_t Extent() const noexcept { return Size(); }
0113 
0114   //! Returns True if array is empty
0115   bool IsEmpty() const noexcept { return Size() == 0; }
0116 
0117   //! Direct const access to the item
0118   const TheItemType& Find(const size_t theIndex) const { return Value(theIndex); }
0119 
0120   //! Modification access to the item
0121   TheItemType& ChangeFind(const size_t theIndex) { return ChangeValue(theIndex); }
0122 
0123   //! Set a value as explicit method
0124   TheItemType& Bind(const size_t theIndex, const TheItemType& theValue)
0125   {
0126     return SetValue(theIndex, theValue);
0127   }
0128 
0129   //! Returns True if the item is defined
0130   bool IsBound(const size_t theIndex) const { return this->HasValue(theIndex); }
0131 
0132   //! Remove the item from array
0133   bool UnBind(const size_t theIndex) { return UnsetValue(theIndex); }
0134 
0135   //!@}
0136 
0137 public:
0138   // Iterator interface
0139 
0140   /**
0141    * Implementation of type-specific const Iterator class
0142    */
0143   class ConstIterator : public NCollection_SparseArrayBase::Iterator
0144   {
0145   public:
0146     //! Empty constructor - for later Init
0147     ConstIterator() noexcept = default;
0148 
0149     //! Constructor with initialisation
0150     ConstIterator(const NCollection_SparseArray& theVector)
0151         : NCollection_SparseArrayBase::Iterator(&theVector)
0152     {
0153     }
0154 
0155     //! Initialisation
0156     void Init(const NCollection_SparseArray& theVector) { this->init(&theVector); }
0157 
0158     //! Constant value access
0159     const TheItemType& Value() const { return *(const TheItemType*)this->value(); }
0160 
0161     //! Constant value access operator
0162     const TheItemType& operator()() const { return *(const TheItemType*)this->value(); }
0163 
0164     //! Access current index with 'a-la map' interface
0165     size_t Key() const noexcept { return Index(); }
0166   };
0167 
0168   /**
0169    * Implementation of type-specific non-const Iterator class
0170    */
0171   class Iterator : public ConstIterator
0172   {
0173   public:
0174     //! Empty constructor - for later Init
0175     Iterator() noexcept = default;
0176 
0177     //! Constructor with initialisation
0178     Iterator(NCollection_SparseArray& theVector)
0179         : ConstIterator(theVector)
0180     {
0181     }
0182 
0183     //! Initialisation
0184     void Init(const NCollection_SparseArray& theVector) { this->init(&theVector); }
0185 
0186     //! Value access
0187     TheItemType& ChangeValue() { return *(TheItemType*)this->value(); }
0188 
0189     //! Value access operator
0190     TheItemType& operator()() { return *(TheItemType*)this->value(); }
0191 
0192     //! Const access operator - the same as in parent class
0193     const TheItemType& operator()() const { return *(const TheItemType*)this->value(); }
0194   };
0195 
0196 private:
0197   // Static functions providing type-specific item operations
0198 
0199   //! Copy-construct a new item from existing item
0200   static void createItemImpl(void* theAddress, void* theOther)
0201   {
0202     new (theAddress) TheItemType(*(const TheItemType*)theOther);
0203   }
0204 
0205   //! Call destructor on the item at given address
0206   static void destroyItemImpl(void* theAddress)
0207   {
0208     ((TheItemType*)theAddress)->TheItemType::~TheItemType();
0209   }
0210 
0211   //! Call assignment operator on the item
0212   static void copyItemImpl(void* theAddress, void* theOther)
0213   {
0214     (*(TheItemType*)theAddress) = *(const TheItemType*)theOther;
0215   }
0216 };
0217 
0218 #endif