Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:20

0001 // Created on: 2007-01-23
0002 // Created by: Andrey BETENEV
0003 // Copyright (c) 2007-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_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 * Base class for NCollection_SparseArray;  
0026 * provides non-template implementation of general mechanics
0027 * of block allocation, items creation / deletion etc.
0028 */
0029 
0030 class NCollection_SparseArrayBase 
0031 {
0032 public:
0033   //!@name Type-independent public interface 
0034   //!@{
0035 
0036   //! Clears all the data
0037   Standard_EXPORT void Clear ();
0038 
0039   //! Returns number of currently contained items
0040   Standard_Size Size () const { return mySize; }
0041 
0042   //! Check whether the value at given index is set
0043   Standard_EXPORT Standard_Boolean HasValue (const Standard_Size theIndex) const;
0044 
0045   //! Deletes the item from the array; 
0046   //! returns True if that item was defined
0047   Standard_EXPORT Standard_Boolean UnsetValue (const Standard_Size theIndex);
0048 
0049   //!@}
0050 
0051 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
0052 public: // work-around against obsolete SUN WorkShop 5.3 compiler
0053 #else
0054 private:
0055 #endif
0056 
0057   /**
0058    * The block of data contains array of items, counter 
0059    * and bit field, allocated as single piece of memory addressed
0060    * from the blocks array (myData).
0061    * 
0062    * The Block structure provides a logical view on the block,
0063    * and provides methods to work with bit map.
0064    *
0065    * Note that NCollection_SparseArrayBase class takes responsibility 
0066    * for correct allocation/deallocation of all the data.
0067    */
0068 
0069   class Block {
0070   public:
0071 
0072     typedef unsigned char Cell; //!< type of items used to hold bits
0073 
0074     //! Number of bits in each cell
0075     static Standard_Size BitsPerCell() { return sizeof(Cell) * 8; } 
0076 
0077   public:
0078 
0079     //! Initializes the block by pointer to block data 
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     //! Compute required size for block data, in bytes
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     //! Returns address of array from address of block
0098     static char* ToArray (const Standard_Address theAddress, 
0099               const Standard_Size /*theNbItems*/, 
0100               const Standard_Size /*theItemSize*/) 
0101     {
0102       return (char*)theAddress + sizeof(Standard_Size);
0103     }
0104 
0105   public:
0106 
0107     //! Set bit for i-th item; returns non-null if that bit has 
0108     //! not been set previously
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     //! Check bit for i-th item; returns non-null if that bit is set
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     //! Unset bit for i-th item; returns non-null if that bit 
0127     //! has been set previously
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; //!< items counter 
0139     Standard_Address Array; //!< pointer to the data items array
0140     Cell*            Bits;  //!< bit map for defined/undefined flags
0141   };
0142 
0143 public:
0144   /**
0145    * Iterator 
0146    */
0147 
0148   class Iterator {
0149   public:
0150     // Public interface
0151 
0152     //! Restart iterations on the same array
0153     void Restart () { init(myArr); }
0154 
0155     //! Returns True if current item is available
0156     Standard_Boolean More () const { return myHasMore; }
0157 
0158     //! Advances to the next item
0159     Standard_EXPORT void Next ();
0160 
0161     //! Returns current index
0162     Standard_Size Index () const 
0163     { 
0164       return myIBlock * myArr->myBlockSize + myInd;
0165     }
0166 
0167   protected:
0168     // Methods for descendant
0169 
0170     //! Empty constructor
0171     Standard_EXPORT Iterator (const NCollection_SparseArrayBase* theArray=0);
0172 
0173     //! Initialize by the specified array
0174     Standard_EXPORT void init (const NCollection_SparseArrayBase* theArray);
0175 
0176     //! Returns address of the current item
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   // Copy constructor and assignment operator are private thus not accessible
0193   NCollection_SparseArrayBase(const NCollection_SparseArrayBase&);
0194   void operator = (const NCollection_SparseArrayBase&);
0195 
0196 protected:
0197   // Object life
0198 
0199   //! Constructor; initialized by size of item and of block (in items)
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   //! Destructor
0208   virtual ~NCollection_SparseArrayBase ()
0209   {
0210     Clear();
0211   }
0212 
0213 protected:
0214   // Data access interface for descendants
0215 
0216   //! Creates Block structure for block pointed by theAddr
0217   Block getBlock (const Standard_Address theAddr) const
0218   {
0219     return Block (theAddr, myBlockSize, myItemSize);
0220   }
0221 
0222   //! Find address of the item in the block by index (in the block)
0223   Standard_Address getItem (const Block &theBlock, Standard_Size theInd) const
0224   {
0225     return ((char*)theBlock.Array) + myItemSize * theInd;
0226   }
0227 
0228   //! Direct const access to the item
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   //! Set a value to the specified item; returns address of the set item
0237   Standard_EXPORT Standard_Address setValue (const Standard_Size theIndex, 
0238                                              const Standard_Address theValue);
0239 
0240   //! Copy contents of theOther to this; 
0241   //! assumes that this and theOther have exactly the same type of arguments 
0242   Standard_EXPORT void assign (const NCollection_SparseArrayBase& theOther);
0243 
0244   //! Exchange contents of theOther and this; 
0245   //! assumes that this and theOther have exactly the same type of arguments 
0246   Standard_EXPORT void exchange (NCollection_SparseArrayBase& theOther);
0247 
0248 protected:
0249   // Methods to be provided by descendant 
0250 
0251   //! Create new item at the specified address with default constructor
0252 //  virtual void createItem (Standard_Address theAddress) = 0;
0253   
0254   //! Create new item at the specified address with copy constructor
0255   //! from existing item
0256   virtual void createItem (Standard_Address theAddress, Standard_Address theOther) = 0;
0257   
0258   //! Call destructor to the item 
0259   virtual void destroyItem (Standard_Address theAddress) = 0;
0260 
0261   //! Call assignment operator to the item
0262   virtual void copyItem (Standard_Address theAddress, Standard_Address theOther) = 0;
0263 
0264 private:
0265   // Implementation of memory allocation/deallocation and access mechanics
0266 
0267   //! Allocate space for at least iBlock+1 blocks
0268   void allocData (const Standard_Size iBlock);
0269 
0270   //! Free specified block
0271   void freeBlock (const Standard_Size iBlock);
0272 
0273 protected:
0274   Standard_Size     myItemSize;  //!< size of item
0275   Standard_Size     myBlockSize; //!< block size (in items)
0276   Standard_Size     myNbBlocks;  //!< allocated size of blocks table
0277   Standard_Size     mySize;      //!< number of currently defined items
0278   Standard_Address *myData;      //!< array of pointers to data blocks
0279 };
0280 
0281 #endif
0282