File indexing completed on 2025-10-29 08:49:57
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 
0013 
0014 
0015 
0016 #ifndef NCollection_SparseArrayBase_HeaderFile
0017 #define NCollection_SparseArrayBase_HeaderFile
0018 
0019 #include <Standard.hxx>
0020 #include <Standard_OutOfRange.hxx>
0021 
0022 typedef size_t Standard_Size;
0023 
0024 
0025 
0026 
0027 
0028 
0029 
0030 class NCollection_SparseArrayBase 
0031 {
0032 public:
0033   
0034   
0035 
0036   
0037   Standard_EXPORT void Clear ();
0038 
0039   
0040   Standard_Size Size () const { return mySize; }
0041 
0042   
0043   Standard_EXPORT Standard_Boolean HasValue (const Standard_Size theIndex) const;
0044 
0045   
0046   
0047   Standard_EXPORT Standard_Boolean UnsetValue (const Standard_Size theIndex);
0048 
0049   
0050 
0051 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
0052 public: 
0053 #else
0054 private:
0055 #endif
0056 
0057   
0058 
0059 
0060 
0061 
0062 
0063 
0064 
0065 
0066 
0067 
0068 
0069   class Block {
0070   public:
0071 
0072     typedef unsigned char Cell; 
0073 
0074     
0075     static Standard_Size BitsPerCell() { return sizeof(Cell) * 8; } 
0076 
0077   public:
0078 
0079     
0080     Block (const Standard_Address theAddr, const Standard_Size theNbItems, 
0081            const Standard_Size theItemSize)
0082       : Count((Standard_Size*)theAddr),
0083         Array((char*)theAddr + sizeof(Standard_Size)), 
0084         Bits ((Cell*)((char*)theAddr + sizeof(Standard_Size) + theNbItems * theItemSize))
0085     {
0086     }
0087 
0088     
0089     static Standard_Size Size (const Standard_Size theNbItems, 
0090                    const Standard_Size theItemSize) 
0091     {
0092       return sizeof(Standard_Size) + 
0093              sizeof(Cell) * ( (theNbItems + BitsPerCell() - 1) / BitsPerCell() ) +
0094              theNbItems * theItemSize;
0095     }
0096 
0097     
0098     static char* ToArray (const Standard_Address theAddress, 
0099               const Standard_Size , 
0100               const Standard_Size ) 
0101     {
0102       return (char*)theAddress + sizeof(Standard_Size);
0103     }
0104 
0105   public:
0106 
0107     
0108     
0109     Cell Set (Standard_Size i) 
0110     {
0111       Cell* abyte = Bits + i / BitsPerCell();
0112       Cell  amask = (Cell)( '\1' << ( i % BitsPerCell() ) );
0113       Cell  anold = (Cell)( *abyte & amask );
0114       *abyte = (Cell)( *abyte | amask );
0115       return ! anold;
0116     }
0117 
0118     
0119     Cell IsSet (Standard_Size i) 
0120     {
0121       Cell* abyte = Bits + i / BitsPerCell();
0122       Cell  amask = (Cell)( '\1' << ( i % BitsPerCell() ) );
0123       return (Cell)( *abyte & amask );
0124     }
0125 
0126     
0127     
0128     Cell Unset (Standard_Size i) 
0129     {
0130       Cell* abyte = Bits + i / BitsPerCell();
0131       Cell  amask = (Cell)( '\1' << ( i % BitsPerCell() ) );
0132       Cell  anold = (Cell)( *abyte & amask );
0133       *abyte = (Cell)( *abyte & ~amask );
0134       return anold;
0135     }
0136 
0137   public:
0138     Standard_Size*   Count; 
0139     Standard_Address Array; 
0140     Cell*            Bits;  
0141   };
0142 
0143 public:
0144   
0145 
0146 
0147 
0148   class Iterator {
0149   public:
0150     
0151 
0152     
0153     void Restart () { init(myArr); }
0154 
0155     
0156     Standard_Boolean More () const { return myHasMore; }
0157 
0158     
0159     Standard_EXPORT void Next ();
0160 
0161     
0162     Standard_Size Index () const 
0163     { 
0164       return myIBlock * myArr->myBlockSize + myInd;
0165     }
0166 
0167   protected:
0168     
0169 
0170     
0171     Standard_EXPORT Iterator (const NCollection_SparseArrayBase* theArray=0);
0172 
0173     
0174     Standard_EXPORT void init (const NCollection_SparseArrayBase* theArray);
0175 
0176     
0177     Standard_Address value () const 
0178     { 
0179       return myArr->getItem (myBlock, myInd);
0180     }
0181     
0182   private:
0183     const NCollection_SparseArrayBase *myArr;
0184     Standard_Boolean myHasMore;
0185     Standard_Size myIBlock;
0186     Standard_Size myInd;
0187     Block myBlock;
0188   };
0189   friend class Iterator;
0190 
0191 private:
0192   
0193   NCollection_SparseArrayBase(const NCollection_SparseArrayBase&);
0194   void operator = (const NCollection_SparseArrayBase&);
0195 
0196 protected:
0197   
0198 
0199   
0200   NCollection_SparseArrayBase (Standard_Size theItemSize,
0201                    Standard_Size theBlockSize)
0202     : myItemSize(theItemSize), myBlockSize(theBlockSize), 
0203       myNbBlocks(0), mySize(0), myData(0)
0204   {
0205   }
0206 
0207   
0208   virtual ~NCollection_SparseArrayBase ()
0209   {
0210     Clear();
0211   }
0212 
0213 protected:
0214   
0215 
0216   
0217   Block getBlock (const Standard_Address theAddr) const
0218   {
0219     return Block (theAddr, myBlockSize, myItemSize);
0220   }
0221 
0222   
0223   Standard_Address getItem (const Block &theBlock, Standard_Size theInd) const
0224   {
0225     return ((char*)theBlock.Array) + myItemSize * theInd;
0226   }
0227 
0228   
0229   Standard_Address getValue (const Standard_Size theIndex) const
0230   {
0231     Standard_OutOfRange_Raise_if (!HasValue(theIndex),"NCollection_SparseArray::Value()")
0232     return Block::ToArray(myData[theIndex/myBlockSize], myBlockSize, myItemSize) + 
0233            myItemSize * (theIndex % myBlockSize);
0234   }
0235 
0236   
0237   Standard_EXPORT Standard_Address setValue (const Standard_Size theIndex, 
0238                                              const Standard_Address theValue);
0239 
0240   
0241   
0242   Standard_EXPORT void assign (const NCollection_SparseArrayBase& theOther);
0243 
0244   
0245   
0246   Standard_EXPORT void exchange (NCollection_SparseArrayBase& theOther);
0247 
0248 protected:
0249   
0250 
0251   
0252 
0253   
0254   
0255   
0256   virtual void createItem (Standard_Address theAddress, Standard_Address theOther) = 0;
0257   
0258   
0259   virtual void destroyItem (Standard_Address theAddress) = 0;
0260 
0261   
0262   virtual void copyItem (Standard_Address theAddress, Standard_Address theOther) = 0;
0263 
0264 private:
0265   
0266 
0267   
0268   void allocData (const Standard_Size iBlock);
0269 
0270   
0271   void freeBlock (const Standard_Size iBlock);
0272 
0273 protected:
0274   Standard_Size     myItemSize;  
0275   Standard_Size     myBlockSize; 
0276   Standard_Size     myNbBlocks;  
0277   Standard_Size     mySize;      
0278   Standard_Address *myData;      
0279 };
0280 
0281 #endif
0282